Commit 7b230f61db319d87d51449d4620d520822813fbb

Authored by Wolfgang Denk

Merge with git://git.kernel.org/pub/scm/boot/u-boot/u-boot.git#pci

Showing 5 changed files Side-by-side Diff

... ... @@ -2,6 +2,24 @@
2 2 Changes since U-Boot 1.1.4:
3 3 ======================================================================
4 4  
  5 +* Fixed PCI indirect config ops to handle multiple PCI controllers
  6 + We need to adjust the bus number we are trying to access based
  7 + on which PCI controller its on
  8 + Patch by Kumar Gala 12 Jan 2006
  9 +
  10 +* Report back PCI bus when doing table based device config
  11 + Patch by Kumar Gala 11 Jan 2006
  12 +
  13 +* Added support for PCI prefetchable region and BARs
  14 + If a host controller sets up a region as prefetchable and
  15 + a device's BAR denotes it as prefetchable, allocate the
  16 + BAR into the prefetch region.
  17 +
  18 + If a BAR is prefetchable and no prefetchable region has
  19 + been setup by the controller we fall back to allocating
  20 + the BAR into the normally memory region.
  21 + Patch by Kumar Gala 11 Jan 2006
  22 +
5 23 * Add helper function for generic flat device tree fixups for mpc83xx
6 24 Patch by Kumar Gala, 11 Jan 2006
7 25  
... ... @@ -459,6 +459,7 @@
459 459 PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
460 460 if (cfg) {
461 461 cfg->config_device(hose, dev, cfg);
  462 + sub_bus = max(sub_bus, hose->current_busno);
462 463 #ifdef CONFIG_PCI_PNP
463 464 } else {
464 465 int n = pciauto_config_device(hose, dev);
... ... @@ -77,6 +77,7 @@
77 77 void pciauto_setup_device(struct pci_controller *hose,
78 78 pci_dev_t dev, int bars_num,
79 79 struct pci_region *mem,
  80 + struct pci_region *prefetch,
80 81 struct pci_region *io)
81 82 {
82 83 unsigned int bar_value, bar_response, bar_size;
... ... @@ -111,7 +112,10 @@
111 112 found_mem64 = 1;
112 113  
113 114 bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
114   - bar_res = mem;
  115 + if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
  116 + bar_res = prefetch;
  117 + else
  118 + bar_res = mem;
115 119  
116 120 DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
117 121 }
... ... @@ -148,6 +152,7 @@
148 152 pci_dev_t dev, int sub_bus)
149 153 {
150 154 struct pci_region *pci_mem = hose->pci_mem;
  155 + struct pci_region *pci_prefetch = hose->pci_prefetch;
151 156 struct pci_region *pci_io = hose->pci_io;
152 157 unsigned int cmdstat;
153 158  
... ... @@ -169,6 +174,21 @@
169 174 cmdstat |= PCI_COMMAND_MEMORY;
170 175 }
171 176  
  177 + if (pci_prefetch) {
  178 + /* Round memory allocator to 1MB boundary */
  179 + pciauto_region_align(pci_prefetch, 0x100000);
  180 +
  181 + /* Set up memory and I/O filter limits, assume 32-bit I/O space */
  182 + pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
  183 + (pci_prefetch->bus_lower & 0xfff00000) >> 16);
  184 +
  185 + cmdstat |= PCI_COMMAND_MEMORY;
  186 + } else {
  187 + /* We don't support prefetchable memory for now, so disable */
  188 + pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
  189 + pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
  190 + }
  191 +
172 192 if (pci_io) {
173 193 /* Round I/O allocator to 4KB boundary */
174 194 pciauto_region_align(pci_io, 0x1000);
... ... @@ -181,10 +201,6 @@
181 201 cmdstat |= PCI_COMMAND_IO;
182 202 }
183 203  
184   - /* We don't support prefetchable memory for now, so disable */
185   - pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
186   - pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
187   -
188 204 /* Enable memory and I/O accesses, enable bus master */
189 205 pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
190 206 }
... ... @@ -193,6 +209,7 @@
193 209 pci_dev_t dev, int sub_bus)
194 210 {
195 211 struct pci_region *pci_mem = hose->pci_mem;
  212 + struct pci_region *pci_prefetch = hose->pci_prefetch;
196 213 struct pci_region *pci_io = hose->pci_io;
197 214  
198 215 /* Configure bus number registers */
... ... @@ -206,6 +223,14 @@
206 223 (pci_mem->bus_lower-1) >> 16);
207 224 }
208 225  
  226 + if (pci_prefetch) {
  227 + /* Round memory allocator to 1MB boundary */
  228 + pciauto_region_align(pci_prefetch, 0x100000);
  229 +
  230 + pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
  231 + (pci_prefetch->bus_lower-1) >> 16);
  232 + }
  233 +
209 234 if (pci_io) {
210 235 /* Round I/O allocator to 4KB boundary */
211 236 pciauto_region_align(pci_io, 0x1000);
... ... @@ -239,6 +264,11 @@
239 264 hose->pci_mem->size < hose->regions[i].size)
240 265 hose->pci_mem = hose->regions + i;
241 266 break;
  267 + case (PCI_REGION_MEM | PCI_REGION_PREFETCH):
  268 + if (!hose->pci_prefetch ||
  269 + hose->pci_prefetch->size < hose->regions[i].size)
  270 + hose->pci_prefetch = hose->regions + i;
  271 + break;
242 272 }
243 273 }
244 274  
... ... @@ -251,6 +281,14 @@
251 281 hose->pci_mem->bus_start + hose->pci_mem->size - 1);
252 282 }
253 283  
  284 + if (hose->pci_prefetch) {
  285 + pciauto_region_init(hose->pci_prefetch);
  286 +
  287 + DEBUGF("PCI Autoconfig: Prefetchable Memory region: [%lx-%lx]\n",
  288 + hose->pci_prefetch->bus_start,
  289 + hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1);
  290 + }
  291 +
254 292 if (hose->pci_io) {
255 293 pciauto_region_init(hose->pci_io);
256 294  
... ... @@ -275,7 +313,7 @@
275 313 switch(class) {
276 314 case PCI_CLASS_BRIDGE_PCI:
277 315 hose->current_busno++;
278   - pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
  316 + pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
279 317  
280 318 DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
281 319  
282 320  
... ... @@ -301,12 +339,12 @@
301 339 return sub_bus;
302 340 }
303 341  
304   - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
  342 + pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
305 343 break;
306 344  
307 345 case PCI_CLASS_BRIDGE_CARDBUS:
308 346 /* just do a minimal setup of the bridge, let the OS take care of the rest */
309   - pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io);
  347 + pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
310 348  
311 349 DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev));
312 350  
313 351  
... ... @@ -328,11 +366,11 @@
328 366 * the PIMMR window to be allocated (BAR0 - 1MB size)
329 367 */
330 368 DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
331   - pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io);
  369 + pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
332 370 break;
333 371 #endif
334 372 default:
335   - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
  373 + pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
336 374 break;
337 375 }
338 376  
drivers/pci_indirect.c
... ... @@ -36,6 +36,10 @@
36 36 indirect_##rw##_config_##size(struct pci_controller *hose, \
37 37 pci_dev_t dev, int offset, type val) \
38 38 { \
  39 + u32 b, d,f; \
  40 + b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
  41 + b = b - hose->first_busno; \
  42 + dev = PCI_BDF(b, d, f); \
39 43 out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
40 44 sync(); \
41 45 cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
... ... @@ -47,6 +51,10 @@
47 51 indirect_##rw##_config_##size(struct pci_controller *hose, \
48 52 pci_dev_t dev, int offset, type val) \
49 53 { \
  54 + u32 b, d,f; \
  55 + b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
  56 + b = b - hose->first_busno; \
  57 + dev = PCI_BDF(b, d, f); \
50 58 *(hose->cfg_addr) = dev | (offset & 0xfc) | 0x80000000; \
51 59 sync(); \
52 60 cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
... ... @@ -58,6 +66,10 @@
58 66 indirect_##rw##_config_##size(struct pci_controller *hose, \
59 67 pci_dev_t dev, int offset, type val) \
60 68 { \
  69 + u32 b, d,f; \
  70 + b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
  71 + b = b - hose->first_busno; \
  72 + dev = PCI_BDF(b, d, f); \
61 73 if (PCI_BUS(dev) > 0) \
62 74 out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000001); \
63 75 else \
... ... @@ -71,6 +83,10 @@
71 83 indirect_##rw##_config_##size(struct pci_controller *hose, \
72 84 pci_dev_t dev, int offset, type val) \
73 85 { \
  86 + u32 b, d,f; \
  87 + b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
  88 + b = b - hose->first_busno; \
  89 + dev = PCI_BDF(b, d, f); \
74 90 out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
75 91 cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
76 92 return 0; \
... ... @@ -309,6 +309,7 @@
309 309 #define PCI_REGION_MEM 0x00000000 /* PCI memory space */
310 310 #define PCI_REGION_IO 0x00000001 /* PCI IO space */
311 311 #define PCI_REGION_TYPE 0x00000001
  312 +#define PCI_REGION_PREFETCH 0x00000008 /* prefetchable PCI memory */
312 313  
313 314 #define PCI_REGION_MEMORY 0x00000100 /* System memory */
314 315 #define PCI_REGION_RO 0x00000200 /* Read-only memory */
... ... @@ -386,7 +387,7 @@
386 387 int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
387 388  
388 389 /* Used by auto config */
389   - struct pci_region *pci_mem, *pci_io;
  390 + struct pci_region *pci_mem, *pci_io, *pci_prefetch;
390 391  
391 392 /* Used by ppc405 autoconfig*/
392 393 struct pci_region *pci_fb;
... ... @@ -472,6 +473,7 @@
472 473 extern void pciauto_setup_device(struct pci_controller *hose,
473 474 pci_dev_t dev, int bars_num,
474 475 struct pci_region *mem,
  476 + struct pci_region *prefetch,
475 477 struct pci_region *io);
476 478 int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
477 479