2 * arch/ppc/kernel/pci_auto.c
4 * PCI autoconfiguration library
6 * Author: Matt Porter <mporter@mvista.com>
8 * Copyright 2000 MontaVista Software Inc.
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
24 #define DEBUGF(x...) printf(x)
29 #define PCIAUTO_IDE_MODE_MASK 0x05
35 void pciauto_region_init(struct pci_region
* res
)
37 res
->bus_lower
= res
->bus_start
;
40 void pciauto_region_align(struct pci_region
*res
, unsigned long size
)
42 res
->bus_lower
= ((res
->bus_lower
- 1) | (size
- 1)) + 1;
45 int pciauto_region_allocate(struct pci_region
* res
, unsigned int size
, unsigned int *bar
)
50 DEBUGF("No resource");
54 addr
= ((res
->bus_lower
- 1) | (size
- 1)) + 1;
56 if (addr
- res
->bus_start
+ size
> res
->size
) {
57 DEBUGF("No room in resource");
61 res
->bus_lower
= addr
+ size
;
63 DEBUGF("address=0x%lx", addr
);
77 void pciauto_setup_device(struct pci_controller
*hose
,
78 pci_dev_t dev
, int bars_num
,
79 struct pci_region
*mem
,
80 struct pci_region
*prefetch
,
81 struct pci_region
*io
)
83 unsigned int bar_value
, bar_response
, bar_size
;
84 unsigned int cmdstat
= 0;
85 struct pci_region
*bar_res
;
89 pci_hose_read_config_dword(hose
, dev
, PCI_COMMAND
, &cmdstat
);
90 cmdstat
= (cmdstat
& ~(PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
)) | PCI_COMMAND_MASTER
;
92 for (bar
= PCI_BASE_ADDRESS_0
; bar
<= PCI_BASE_ADDRESS_0
+ (bars_num
*4); bar
+= 4) {
93 /* Tickle the BAR and get the response */
94 pci_hose_write_config_dword(hose
, dev
, bar
, 0xffffffff);
95 pci_hose_read_config_dword(hose
, dev
, bar
, &bar_response
);
97 /* If BAR is not implemented go to the next BAR */
103 /* Check the BAR type and set our address mask */
104 if (bar_response
& PCI_BASE_ADDRESS_SPACE
) {
105 bar_size
= ((~(bar_response
& PCI_BASE_ADDRESS_IO_MASK
))
109 DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr
, bar_size
);
111 if ( (bar_response
& PCI_BASE_ADDRESS_MEM_TYPE_MASK
) ==
112 PCI_BASE_ADDRESS_MEM_TYPE_64
)
115 bar_size
= ~(bar_response
& PCI_BASE_ADDRESS_MEM_MASK
) + 1;
116 if (prefetch
&& (bar_response
& PCI_BASE_ADDRESS_MEM_PREFETCH
))
121 DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr
, bar_size
);
124 if (pciauto_region_allocate(bar_res
, bar_size
, &bar_value
) == 0) {
125 /* Write it out and update our limit */
126 pci_hose_write_config_dword(hose
, dev
, bar
, bar_value
);
129 * If we are a 64-bit decoder then increment to the
130 * upper 32 bits of the bar and force it to locate
131 * in the lower 4GB of memory.
135 pci_hose_write_config_dword(hose
, dev
, bar
, 0x00000000);
138 cmdstat
|= (bar_response
& PCI_BASE_ADDRESS_SPACE
) ?
139 PCI_COMMAND_IO
: PCI_COMMAND_MEMORY
;
147 pci_hose_write_config_dword(hose
, dev
, PCI_COMMAND
, cmdstat
);
148 pci_hose_write_config_byte(hose
, dev
, PCI_CACHE_LINE_SIZE
, 0x08);
149 pci_hose_write_config_byte(hose
, dev
, PCI_LATENCY_TIMER
, 0x80);
152 static void pciauto_prescan_setup_bridge(struct pci_controller
*hose
,
153 pci_dev_t dev
, int sub_bus
)
155 struct pci_region
*pci_mem
= hose
->pci_mem
;
156 struct pci_region
*pci_prefetch
= hose
->pci_prefetch
;
157 struct pci_region
*pci_io
= hose
->pci_io
;
158 unsigned int cmdstat
;
160 pci_hose_read_config_dword(hose
, dev
, PCI_COMMAND
, &cmdstat
);
162 /* Configure bus number registers */
163 pci_hose_write_config_byte(hose
, dev
, PCI_PRIMARY_BUS
, PCI_BUS(dev
));
164 pci_hose_write_config_byte(hose
, dev
, PCI_SECONDARY_BUS
, sub_bus
);
165 pci_hose_write_config_byte(hose
, dev
, PCI_SUBORDINATE_BUS
, 0xff);
168 /* Round memory allocator to 1MB boundary */
169 pciauto_region_align(pci_mem
, 0x100000);
171 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
172 pci_hose_write_config_word(hose
, dev
, PCI_MEMORY_BASE
,
173 (pci_mem
->bus_lower
& 0xfff00000) >> 16);
175 cmdstat
|= PCI_COMMAND_MEMORY
;
179 /* Round memory allocator to 1MB boundary */
180 pciauto_region_align(pci_prefetch
, 0x100000);
182 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
183 pci_hose_write_config_word(hose
, dev
, PCI_PREF_MEMORY_BASE
,
184 (pci_prefetch
->bus_lower
& 0xfff00000) >> 16);
186 cmdstat
|= PCI_COMMAND_MEMORY
;
188 /* We don't support prefetchable memory for now, so disable */
189 pci_hose_write_config_word(hose
, dev
, PCI_PREF_MEMORY_BASE
, 0x1000);
190 pci_hose_write_config_word(hose
, dev
, PCI_PREF_MEMORY_LIMIT
, 0x0);
194 /* Round I/O allocator to 4KB boundary */
195 pciauto_region_align(pci_io
, 0x1000);
197 pci_hose_write_config_byte(hose
, dev
, PCI_IO_BASE
,
198 (pci_io
->bus_lower
& 0x0000f000) >> 8);
199 pci_hose_write_config_word(hose
, dev
, PCI_IO_BASE_UPPER16
,
200 (pci_io
->bus_lower
& 0xffff0000) >> 16);
202 cmdstat
|= PCI_COMMAND_IO
;
205 /* Enable memory and I/O accesses, enable bus master */
206 pci_hose_write_config_dword(hose
, dev
, PCI_COMMAND
, cmdstat
| PCI_COMMAND_MASTER
);
209 static void pciauto_postscan_setup_bridge(struct pci_controller
*hose
,
210 pci_dev_t dev
, int sub_bus
)
212 struct pci_region
*pci_mem
= hose
->pci_mem
;
213 struct pci_region
*pci_prefetch
= hose
->pci_prefetch
;
214 struct pci_region
*pci_io
= hose
->pci_io
;
216 /* Configure bus number registers */
217 pci_hose_write_config_byte(hose
, dev
, PCI_SUBORDINATE_BUS
, sub_bus
);
220 /* Round memory allocator to 1MB boundary */
221 pciauto_region_align(pci_mem
, 0x100000);
223 pci_hose_write_config_word(hose
, dev
, PCI_MEMORY_LIMIT
,
224 (pci_mem
->bus_lower
-1) >> 16);
228 /* Round memory allocator to 1MB boundary */
229 pciauto_region_align(pci_prefetch
, 0x100000);
231 pci_hose_write_config_word(hose
, dev
, PCI_PREF_MEMORY_LIMIT
,
232 (pci_prefetch
->bus_lower
-1) >> 16);
236 /* Round I/O allocator to 4KB boundary */
237 pciauto_region_align(pci_io
, 0x1000);
239 pci_hose_write_config_byte(hose
, dev
, PCI_IO_LIMIT
,
240 ((pci_io
->bus_lower
-1) & 0x0000f000) >> 8);
241 pci_hose_write_config_word(hose
, dev
, PCI_IO_LIMIT_UPPER16
,
242 ((pci_io
->bus_lower
-1) & 0xffff0000) >> 16);
250 void pciauto_config_init(struct pci_controller
*hose
)
254 hose
->pci_io
= hose
->pci_mem
= NULL
;
256 for (i
=0; i
<hose
->region_count
; i
++) {
257 switch(hose
->regions
[i
].flags
) {
260 hose
->pci_io
->size
< hose
->regions
[i
].size
)
261 hose
->pci_io
= hose
->regions
+ i
;
264 if (!hose
->pci_mem
||
265 hose
->pci_mem
->size
< hose
->regions
[i
].size
)
266 hose
->pci_mem
= hose
->regions
+ i
;
268 case (PCI_REGION_MEM
| PCI_REGION_PREFETCH
):
269 if (!hose
->pci_prefetch
||
270 hose
->pci_prefetch
->size
< hose
->regions
[i
].size
)
271 hose
->pci_prefetch
= hose
->regions
+ i
;
278 pciauto_region_init(hose
->pci_mem
);
280 DEBUGF("PCI Autoconfig: Memory region: [%lx-%lx]\n",
281 hose
->pci_mem
->bus_start
,
282 hose
->pci_mem
->bus_start
+ hose
->pci_mem
->size
- 1);
285 if (hose
->pci_prefetch
) {
286 pciauto_region_init(hose
->pci_prefetch
);
288 DEBUGF("PCI Autoconfig: Prefetchable Memory region: [%lx-%lx]\n",
289 hose
->pci_prefetch
->bus_start
,
290 hose
->pci_prefetch
->bus_start
+ hose
->pci_prefetch
->size
- 1);
294 pciauto_region_init(hose
->pci_io
);
296 DEBUGF("PCI Autoconfig: I/O region: [%lx-%lx]\n",
297 hose
->pci_io
->bus_start
,
298 hose
->pci_io
->bus_start
+ hose
->pci_io
->size
- 1);
302 /* HJF: Changed this to return int. I think this is required
303 * to get the correct result when scanning bridges
305 int pciauto_config_device(struct pci_controller
*hose
, pci_dev_t dev
)
307 unsigned int sub_bus
= PCI_BUS(dev
);
308 unsigned short class;
309 unsigned char prg_iface
;
312 pci_hose_read_config_word(hose
, dev
, PCI_CLASS_DEVICE
, &class);
315 case PCI_CLASS_BRIDGE_PCI
:
316 hose
->current_busno
++;
317 pciauto_setup_device(hose
, dev
, 2, hose
->pci_mem
, hose
->pci_prefetch
, hose
->pci_io
);
319 DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev
));
321 /* Passing in current_busno allows for sibling P2P bridges */
322 pciauto_prescan_setup_bridge(hose
, dev
, hose
->current_busno
);
324 * need to figure out if this is a subordinate bridge on the bus
325 * to be able to properly set the pri/sec/sub bridge registers.
327 n
= pci_hose_scan_bus(hose
, hose
->current_busno
);
329 /* figure out the deepest we've gone for this leg */
330 sub_bus
= max(n
, sub_bus
);
331 pciauto_postscan_setup_bridge(hose
, dev
, sub_bus
);
333 sub_bus
= hose
->current_busno
;
336 case PCI_CLASS_STORAGE_IDE
:
337 pci_hose_read_config_byte(hose
, dev
, PCI_CLASS_PROG
, &prg_iface
);
338 if (!(prg_iface
& PCIAUTO_IDE_MODE_MASK
)) {
339 DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
343 pciauto_setup_device(hose
, dev
, 6, hose
->pci_mem
, hose
->pci_prefetch
, hose
->pci_io
);
346 case PCI_CLASS_BRIDGE_CARDBUS
:
347 /* just do a minimal setup of the bridge, let the OS take care of the rest */
348 pciauto_setup_device(hose
, dev
, 0, hose
->pci_mem
, hose
->pci_prefetch
, hose
->pci_io
);
350 DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev
));
352 hose
->current_busno
++;
355 #ifdef CONFIG_MPC5200
356 case PCI_CLASS_BRIDGE_OTHER
:
357 DEBUGF("PCI Autoconfig: Skipping bridge device %d\n",
361 #ifdef CONFIG_MPC834X
362 case PCI_CLASS_BRIDGE_OTHER
:
364 * The host/PCI bridge 1 seems broken in 8349 - it presents
365 * itself as 'PCI_CLASS_BRIDGE_OTHER' and appears as an _agent_
366 * device claiming resources io/mem/irq.. we only allow for
367 * the PIMMR window to be allocated (BAR0 - 1MB size)
369 DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
370 pciauto_setup_device(hose
, dev
, 0, hose
->pci_mem
, hose
->pci_prefetch
, hose
->pci_io
);
374 pciauto_setup_device(hose
, dev
, 6, hose
->pci_mem
, hose
->pci_prefetch
, hose
->pci_io
);
381 #endif /* CONFIG_PCI */