Commit 30e76d5e3bc4c5208ee63585fe12b409d9308cd8

Authored by Kumar Gala
Committed by Andrew Fleming-AFLEMING
1 parent ae5f943ba8

pci: Allow for PCI addresses to be 64-bit

PCI bus is inherently 64-bit.  While not all system require access to
the full 64-bit PCI address range some do.  This allows those systems
to enable the full PCI address width via CONFIG_SYS_PCI_64BIT.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Andrew Fleming-AFLEMING <afleming@freescale.com>
Acked-by: Wolfgang Denk <wd@denx.de>

Showing 3 changed files with 102 additions and 63 deletions Side-by-side Diff

... ... @@ -218,12 +218,12 @@
218 218 *
219 219 */
220 220  
221   -unsigned long pci_hose_phys_to_bus (struct pci_controller *hose,
  221 +pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
222 222 phys_addr_t phys_addr,
223 223 unsigned long flags)
224 224 {
225 225 struct pci_region *res;
226   - unsigned long bus_addr;
  226 + pci_addr_t bus_addr;
227 227 int i;
228 228  
229 229 if (!hose) {
... ... @@ -252,7 +252,7 @@
252 252 }
253 253  
254 254 phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
255   - unsigned long bus_addr,
  255 + pci_addr_t bus_addr,
256 256 unsigned long flags)
257 257 {
258 258 struct pci_region *res;
259 259  
260 260  
... ... @@ -288,15 +288,17 @@
288 288 int pci_hose_config_device(struct pci_controller *hose,
289 289 pci_dev_t dev,
290 290 unsigned long io,
291   - unsigned long mem,
  291 + pci_addr_t mem,
292 292 unsigned long command)
293 293 {
294   - unsigned int bar_response, bar_size, bar_value, old_command;
  294 + unsigned int bar_response, old_command;
  295 + pci_addr_t bar_value;
  296 + pci_size_t bar_size;
295 297 unsigned char pin;
296 298 int bar, found_mem64;
297 299  
298   - debug ("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n",
299   - io, mem, command);
  300 + debug ("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n",
  301 + io, (u64)mem, command);
300 302  
301 303 pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0);
302 304  
303 305  
304 306  
... ... @@ -319,11 +321,20 @@
319 321 io = io + bar_size;
320 322 } else {
321 323 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
322   - PCI_BASE_ADDRESS_MEM_TYPE_64)
323   - found_mem64 = 1;
  324 + PCI_BASE_ADDRESS_MEM_TYPE_64) {
  325 + u32 bar_response_upper;
  326 + u64 bar64;
  327 + pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff);
  328 + pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper);
324 329  
325   - bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
  330 + bar64 = ((u64)bar_response_upper << 32) | bar_response;
326 331  
  332 + bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
  333 + found_mem64 = 1;
  334 + } else {
  335 + bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
  336 + }
  337 +
327 338 /* round up region base address to multiple of size */
328 339 mem = ((mem - 1) | (bar_size - 1)) + 1;
329 340 bar_value = mem;
330 341  
331 342  
... ... @@ -332,11 +343,15 @@
332 343 }
333 344  
334 345 /* Write it out and update our limit */
335   - pci_hose_write_config_dword (hose, dev, bar, bar_value);
  346 + pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value);
336 347  
337 348 if (found_mem64) {
338 349 bar += 4;
  350 +#ifdef CONFIG_SYS_PCI_64BIT
  351 + pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32));
  352 +#else
339 353 pci_hose_write_config_dword (hose, dev, bar, 0x00000000);
  354 +#endif
340 355 }
341 356 }
342 357  
drivers/pci/pci_auto.c
... ... @@ -45,14 +45,14 @@
45 45 res->bus_lower = res->bus_start ? res->bus_start : 0x1000;
46 46 }
47 47  
48   -void pciauto_region_align(struct pci_region *res, unsigned long size)
  48 +void pciauto_region_align(struct pci_region *res, pci_size_t size)
49 49 {
50 50 res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1;
51 51 }
52 52  
53   -int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar)
  53 +int pciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar)
54 54 {
55   - unsigned long addr;
  55 + pci_addr_t addr;
56 56  
57 57 if (!res) {
58 58 DEBUGF("No resource");
59 59  
... ... @@ -68,13 +68,13 @@
68 68  
69 69 res->bus_lower = addr + size;
70 70  
71   - DEBUGF("address=0x%lx bus_lower=%x", addr, res->bus_lower);
  71 + DEBUGF("address=0x%llx bus_lower=0x%llx", (u64)addr, (u64)res->bus_lower);
72 72  
73 73 *bar = addr;
74 74 return 0;
75 75  
76 76 error:
77   - *bar = 0xffffffff;
  77 + *bar = (pci_addr_t)-1;
78 78 return -1;
79 79 }
80 80  
... ... @@ -88,7 +88,9 @@
88 88 struct pci_region *prefetch,
89 89 struct pci_region *io)
90 90 {
91   - unsigned int bar_value, bar_response, bar_size;
  91 + unsigned int bar_response;
  92 + pci_addr_t bar_value;
  93 + pci_size_t bar_size;
92 94 unsigned int cmdstat = 0;
93 95 struct pci_region *bar_res;
94 96 int bar, bar_nr = 0;
95 97  
96 98  
97 99  
98 100  
99 101  
100 102  
101 103  
... ... @@ -114,33 +116,46 @@
114 116 & 0xffff) + 1;
115 117 bar_res = io;
116 118  
117   - DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr, bar_size);
  119 + DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size);
118 120 } else {
119 121 if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
120   - PCI_BASE_ADDRESS_MEM_TYPE_64)
121   - found_mem64 = 1;
  122 + PCI_BASE_ADDRESS_MEM_TYPE_64) {
  123 + u32 bar_response_upper;
  124 + u64 bar64;
  125 + pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff);
  126 + pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper);
122 127  
123   - bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
  128 + bar64 = ((u64)bar_response_upper << 32) | bar_response;
  129 +
  130 + bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
  131 + found_mem64 = 1;
  132 + } else {
  133 + bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
  134 + }
124 135 if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
125 136 bar_res = prefetch;
126 137 else
127 138 bar_res = mem;
128 139  
129   - DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
  140 + DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size);
130 141 }
131 142  
132 143 if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) {
133 144 /* Write it out and update our limit */
134   - pci_hose_write_config_dword(hose, dev, bar, bar_value);
  145 + pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value);
135 146  
136   - /*
137   - * If we are a 64-bit decoder then increment to the
138   - * upper 32 bits of the bar and force it to locate
139   - * in the lower 4GB of memory.
140   - */
141 147 if (found_mem64) {
142 148 bar += 4;
  149 +#ifdef CONFIG_SYS_PCI_64BIT
  150 + pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32));
  151 +#else
  152 + /*
  153 + * If we are a 64-bit decoder then increment to the
  154 + * upper 32 bits of the bar and force it to locate
  155 + * in the lower 4GB of memory.
  156 + */
143 157 pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
  158 +#endif
144 159 }
145 160  
146 161 cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
147 162  
148 163  
... ... @@ -289,35 +304,36 @@
289 304 if (hose->pci_mem) {
290 305 pciauto_region_init(hose->pci_mem);
291 306  
292   - DEBUGF("PCI Autoconfig: Bus Memory region: [%lx-%lx],\n"
293   - "\t\tPhysical Memory [%x-%x]\n",
294   - hose->pci_mem->bus_start,
295   - hose->pci_mem->bus_start + hose->pci_mem->size - 1,
296   - hose->pci_mem->phys_start,
297   - hose->pci_mem->phys_start + hose->pci_mem->size - 1);
  307 + DEBUGF("PCI Autoconfig: Bus Memory region: [0x%llx-0x%llx],\n"
  308 + "\t\tPhysical Memory [%llx-%llxx]\n",
  309 + (u64)hose->pci_mem->bus_start,
  310 + (u64)(hose->pci_mem->bus_start + hose->pci_mem->size - 1),
  311 + (u64)hose->pci_mem->phys_start,
  312 + (u64)(hose->pci_mem->phys_start + hose->pci_mem->size - 1));
298 313 }
299 314  
300 315 if (hose->pci_prefetch) {
301 316 pciauto_region_init(hose->pci_prefetch);
302 317  
303   - DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [%lx-%lx],\n"
304   - "\t\tPhysical Memory [%x-%x]\n",
305   - hose->pci_prefetch->bus_start,
306   - hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1,
307   - hose->pci_prefetch->phys_start,
308   - hose->pci_prefetch->phys_start +
309   - hose->pci_prefetch->size - 1);
  318 + DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [0x%llx-0x%llx],\n"
  319 + "\t\tPhysical Memory [%llx-%llx]\n",
  320 + (u64)hose->pci_prefetch->bus_start,
  321 + (u64)(hose->pci_prefetch->bus_start +
  322 + hose->pci_prefetch->size - 1),
  323 + (u64)hose->pci_prefetch->phys_start,
  324 + (u64)(hose->pci_prefetch->phys_start +
  325 + hose->pci_prefetch->size - 1));
310 326 }
311 327  
312 328 if (hose->pci_io) {
313 329 pciauto_region_init(hose->pci_io);
314 330  
315   - DEBUGF("PCI Autoconfig: Bus I/O region: [%lx-%lx],\n"
316   - "\t\tPhysical Memory: [%x-%x]\n",
317   - hose->pci_io->bus_start,
318   - hose->pci_io->bus_start + hose->pci_io->size - 1,
319   - hose->pci_io->phys_start,
320   - hose->pci_io->phys_start + hose->pci_io->size - 1);
  331 + DEBUGF("PCI Autoconfig: Bus I/O region: [0x%llx-0x%llx],\n"
  332 + "\t\tPhysical Memory: [%llx-%llx]\n",
  333 + (u64)hose->pci_io->bus_start,
  334 + (u64)(hose->pci_io->bus_start + hose->pci_io->size - 1),
  335 + (u64)hose->pci_io->phys_start,
  336 + (u64)(hose->pci_io->phys_start + hose->pci_io->size - 1));
321 337  
322 338 }
323 339 }
... ... @@ -101,8 +101,8 @@
101 101 #define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
102 102 #define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
103 103 #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
104   -#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
105   -#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
  104 +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL)
  105 +#define PCI_BASE_ADDRESS_IO_MASK (~0x03ULL)
106 106 /* bit 1 is reserved if address_space = 1 */
107 107  
108 108 /* Header type 0 (normal devices) */
... ... @@ -111,7 +111,7 @@
111 111 #define PCI_SUBSYSTEM_ID 0x2e
112 112 #define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
113 113 #define PCI_ROM_ADDRESS_ENABLE 0x01
114   -#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
  114 +#define PCI_ROM_ADDRESS_MASK (~0x7ffULL)
115 115  
116 116 #define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
117 117  
118 118  
119 119  
... ... @@ -312,13 +312,21 @@
312 312  
313 313 #include <pci_ids.h>
314 314  
  315 +#ifdef CONFIG_SYS_PCI_64BIT
  316 +typedef u64 pci_addr_t;
  317 +typedef u64 pci_size_t;
  318 +#else
  319 +typedef u32 pci_addr_t;
  320 +typedef u32 pci_size_t;
  321 +#endif
  322 +
315 323 struct pci_region {
316   - unsigned long bus_start; /* Start on the bus */
317   - phys_addr_t phys_start; /* Start in physical address space */
318   - unsigned long size; /* Size */
319   - unsigned long flags; /* Resource flags */
  324 + pci_addr_t bus_start; /* Start on the bus */
  325 + phys_addr_t phys_start; /* Start in physical address space */
  326 + pci_size_t size; /* Size */
  327 + unsigned long flags; /* Resource flags */
320 328  
321   - unsigned long bus_lower;
  329 + pci_addr_t bus_lower;
322 330 };
323 331  
324 332 #define PCI_REGION_MEM 0x00000000 /* PCI memory space */
325 333  
... ... @@ -330,9 +338,9 @@
330 338 #define PCI_REGION_RO 0x00000200 /* Read-only memory */
331 339  
332 340 extern __inline__ void pci_set_region(struct pci_region *reg,
333   - unsigned long bus_start,
  341 + pci_addr_t bus_start,
334 342 phys_addr_t phys_start,
335   - unsigned long size,
  343 + pci_size_t size,
336 344 unsigned long flags) {
337 345 reg->bus_start = bus_start;
338 346 reg->phys_start = phys_start;
... ... @@ -433,9 +441,9 @@
433 441 extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
434 442  
435 443 extern phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
436   - unsigned long addr, unsigned long flags);
437   -extern unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
438   - phys_addr_t addr, unsigned long flags);
  444 + pci_addr_t addr, unsigned long flags);
  445 +extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
  446 + phys_addr_t addr, unsigned long flags);
439 447  
440 448 #define pci_phys_to_bus(dev, addr, flags) \
441 449 pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
... ... @@ -483,8 +491,8 @@
483 491 extern int pci_hose_scan_bus(struct pci_controller *hose, int bus);
484 492  
485 493 extern void pciauto_region_init(struct pci_region* res);
486   -extern void pciauto_region_align(struct pci_region *res, unsigned long size);
487   -extern int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
  494 +extern void pciauto_region_align(struct pci_region *res, pci_size_t size);
  495 +extern int pciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar);
488 496 extern void pciauto_setup_device(struct pci_controller *hose,
489 497 pci_dev_t dev, int bars_num,
490 498 struct pci_region *mem,
... ... @@ -500,7 +508,7 @@
500 508 extern int pci_hose_config_device(struct pci_controller *hose,
501 509 pci_dev_t dev,
502 510 unsigned long io,
503   - unsigned long mem,
  511 + pci_addr_t mem,
504 512 unsigned long command);
505 513  
506 514 #ifdef CONFIG_MPC824X