| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * | 
 | 3 |  * Copyright 2001 MontaVista Software Inc. | 
 | 4 |  * Author: jsun@mvista.com or jsun@junsun.net | 
 | 5 |  * | 
 | 6 |  * arch/mips/ddb5xxx/common/nile4.c | 
 | 7 |  *     misc low-level routines for vrc-5xxx controllers. | 
 | 8 |  * | 
 | 9 |  * derived from original code by Geert Uytterhoeven <geert@sonycom.com> | 
 | 10 |  * | 
 | 11 |  * This program is free software; you can redistribute  it and/or modify it | 
 | 12 |  * under  the terms of  the GNU General  Public License as published by the | 
 | 13 |  * Free Software Foundation;  either version 2 of the  License, or (at your | 
 | 14 |  * option) any later version. | 
 | 15 |  */ | 
 | 16 | #include <linux/types.h> | 
 | 17 | #include <linux/kernel.h> | 
 | 18 |  | 
 | 19 | #include <asm/ddb5xxx/ddb5xxx.h> | 
 | 20 |  | 
 | 21 | u32 | 
 | 22 | ddb_calc_pdar(u32 phys, u32 size, int width, | 
 | 23 | 	      int on_memory_bus, int pci_visible) | 
 | 24 | { | 
 | 25 |         u32 maskbits; | 
 | 26 |         u32 widthbits; | 
 | 27 |  | 
 | 28 |         switch (size) { | 
 | 29 | #if 0                           /* We don't support 4 GB yet */ | 
 | 30 |         case 0x100000000:       /* 4 GB */ | 
 | 31 |                 maskbits = 4; | 
 | 32 |                 break; | 
 | 33 | #endif | 
 | 34 |         case 0x80000000:        /* 2 GB */ | 
 | 35 |                 maskbits = 5; | 
 | 36 |                 break; | 
 | 37 |         case 0x40000000:        /* 1 GB */ | 
 | 38 |                 maskbits = 6; | 
 | 39 |                 break; | 
 | 40 |         case 0x20000000:        /* 512 MB */ | 
 | 41 |                 maskbits = 7; | 
 | 42 |                 break; | 
 | 43 |         case 0x10000000:        /* 256 MB */ | 
 | 44 |                 maskbits = 8; | 
 | 45 |                 break; | 
 | 46 |         case 0x08000000:        /* 128 MB */ | 
 | 47 |                 maskbits = 9; | 
 | 48 |                 break; | 
 | 49 |         case 0x04000000:        /* 64 MB */ | 
 | 50 |                 maskbits = 10; | 
 | 51 |                 break; | 
 | 52 |         case 0x02000000:        /* 32 MB */ | 
 | 53 |                 maskbits = 11; | 
 | 54 |                 break; | 
 | 55 |         case 0x01000000:        /* 16 MB */ | 
 | 56 |                 maskbits = 12; | 
 | 57 |                 break; | 
 | 58 |         case 0x00800000:        /* 8 MB */ | 
 | 59 |                 maskbits = 13; | 
 | 60 |                 break; | 
 | 61 |         case 0x00400000:        /* 4 MB */ | 
 | 62 |                 maskbits = 14; | 
 | 63 |                 break; | 
 | 64 |         case 0x00200000:        /* 2 MB */ | 
 | 65 |                 maskbits = 15; | 
 | 66 |                 break; | 
 | 67 |         case 0:         /* OFF */ | 
 | 68 |                 maskbits = 0; | 
 | 69 |                 break; | 
 | 70 |         default: | 
 | 71 |                 panic("nile4_set_pdar: unsupported size %p", (void *) size); | 
 | 72 |         } | 
 | 73 |         switch (width) { | 
 | 74 |         case 8: | 
 | 75 |                 widthbits = 0; | 
 | 76 |                 break; | 
 | 77 |         case 16: | 
 | 78 |                 widthbits = 1; | 
 | 79 |                 break; | 
 | 80 |         case 32: | 
 | 81 |                 widthbits = 2; | 
 | 82 |                 break; | 
 | 83 |         case 64: | 
 | 84 |                 widthbits = 3; | 
 | 85 |                 break; | 
 | 86 |         default: | 
 | 87 |                 panic("nile4_set_pdar: unsupported width %d", width); | 
 | 88 |         } | 
 | 89 |  | 
 | 90 | 	return maskbits | (on_memory_bus ? 0x10 : 0) | | 
 | 91 | 		(pci_visible ? 0x20 : 0) | (widthbits << 6) | | 
 | 92 | 		(phys & 0xffe00000); | 
 | 93 | } | 
 | 94 |  | 
 | 95 | void | 
 | 96 | ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width, | 
 | 97 | 	     int on_memory_bus, int pci_visible) | 
 | 98 | { | 
 | 99 | 	u32 temp= ddb_calc_pdar(phys, size, width, on_memory_bus, pci_visible); | 
 | 100 | 	ddb_out32(pdar, temp); | 
 | 101 | 	ddb_out32(pdar + 4, 0); | 
 | 102 |  | 
 | 103 |         /* | 
 | 104 |          * When programming a PDAR, the register should be read immediately | 
 | 105 |          * after writing it. This ensures that address decoders are properly | 
 | 106 |          * configured. | 
 | 107 | 	 * [jsun] is this really necessary? | 
 | 108 |          */ | 
 | 109 |         ddb_in32(pdar); | 
 | 110 |         ddb_in32(pdar + 4); | 
 | 111 | } | 
 | 112 |  | 
 | 113 | /* | 
 | 114 |  * routines that mess with PCIINITx registers | 
 | 115 |  */ | 
 | 116 |  | 
 | 117 | void ddb_set_pmr(u32 pmr, u32 type, u32 addr, u32 options) | 
 | 118 | { | 
 | 119 |         switch (type) { | 
 | 120 |         case DDB_PCICMD_IACK: /* PCI Interrupt Acknowledge */ | 
 | 121 |         case DDB_PCICMD_IO:   /* PCI I/O Space */ | 
 | 122 |         case DDB_PCICMD_MEM:  /* PCI Memory Space */ | 
 | 123 |         case DDB_PCICMD_CFG:  /* PCI Configuration Space */ | 
 | 124 |                 break; | 
 | 125 |         default: | 
 | 126 |                 panic("nile4_set_pmr: invalid type %d", type); | 
 | 127 |         } | 
 | 128 |         ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options ); | 
 | 129 |         ddb_out32(pmr + 4, 0); | 
 | 130 | } |