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
)
51 DEBUGF("No resource");
55 addr
= ((res
->bus_lower
- 1) | (size
- 1)) + 1;
57 if (addr
- res
->bus_start
+ size
> res
->size
)
59 DEBUGF("No room in resource");
63 res
->bus_lower
= addr
+ size
;
65 DEBUGF("address=0x%lx", addr
);
79 void pciauto_setup_device(struct pci_controller
*hose
,
80 pci_dev_t dev
, int bars_num
,
81 struct pci_region
*mem
,
82 struct pci_region
*io
)
84 unsigned int bar_value
, bar_response
, bar_size
;
85 unsigned int cmdstat
= 0;
86 struct pci_region
*bar_res
;
90 pci_hose_read_config_dword(hose
, dev
, PCI_COMMAND
, &cmdstat
);
91 cmdstat
= (cmdstat
& ~(PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
)) | PCI_COMMAND_MASTER
;
93 for (bar
= PCI_BASE_ADDRESS_0
; bar
<= PCI_BASE_ADDRESS_0
+ (bars_num
*4); bar
+= 4)
95 /* Tickle the BAR and get the response */
96 pci_hose_write_config_dword(hose
, dev
, bar
, 0xffffffff);
97 pci_hose_read_config_dword(hose
, dev
, bar
, &bar_response
);
99 /* If BAR is not implemented go to the next BAR */
105 /* Check the BAR type and set our address mask */
106 if (bar_response
& PCI_BASE_ADDRESS_SPACE
)
108 bar_size
= ~(bar_response
& PCI_BASE_ADDRESS_IO_MASK
) + 1;
111 DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr
, bar_size
);
115 if ( (bar_response
& PCI_BASE_ADDRESS_MEM_TYPE_MASK
) ==
116 PCI_BASE_ADDRESS_MEM_TYPE_64
)
119 bar_size
= ~(bar_response
& PCI_BASE_ADDRESS_MEM_MASK
) + 1;
122 DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr
, bar_size
);
125 if (pciauto_region_allocate(bar_res
, bar_size
, &bar_value
) == 0)
127 /* Write it out and update our limit */
128 pci_hose_write_config_dword(hose
, dev
, bar
, bar_value
);
131 * If we are a 64-bit decoder then increment to the
132 * upper 32 bits of the bar and force it to locate
133 * in the lower 4GB of memory.
138 pci_hose_write_config_dword(hose
, dev
, bar
, 0x00000000);
141 cmdstat
|= (bar_response
& PCI_BASE_ADDRESS_SPACE
) ?
142 PCI_COMMAND_IO
: PCI_COMMAND_MEMORY
;
150 pci_hose_write_config_dword(hose
, dev
, PCI_COMMAND
, cmdstat
);
151 pci_hose_write_config_byte(hose
, dev
, PCI_CACHE_LINE_SIZE
, 0x08);
152 pci_hose_write_config_byte(hose
, dev
, PCI_LATENCY_TIMER
, 0x80);
155 static void pciauto_prescan_setup_bridge(struct pci_controller
*hose
,
156 pci_dev_t dev
, int sub_bus
)
158 struct pci_region
*pci_mem
= hose
->pci_mem
;
159 struct pci_region
*pci_io
= hose
->pci_io
;
160 unsigned int cmdstat
;
162 pci_hose_read_config_dword(hose
, dev
, PCI_COMMAND
, &cmdstat
);
164 /* Configure bus number registers */
165 pci_hose_write_config_byte(hose
, dev
, PCI_PRIMARY_BUS
, PCI_BUS(dev
));
166 pci_hose_write_config_byte(hose
, dev
, PCI_SECONDARY_BUS
, sub_bus
+ 1);
167 pci_hose_write_config_byte(hose
, dev
, PCI_SUBORDINATE_BUS
, 0xff);
171 /* Round memory allocator to 1MB boundary */
172 pciauto_region_align(pci_mem
, 0x100000);
174 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
175 pci_hose_write_config_word(hose
, dev
, PCI_MEMORY_BASE
,
176 (pci_mem
->bus_lower
& 0xfff00000) >> 16);
178 cmdstat
|= PCI_COMMAND_MEMORY
;
183 /* Round I/O allocator to 4KB boundary */
184 pciauto_region_align(pci_io
, 0x1000);
186 pci_hose_write_config_byte(hose
, dev
, PCI_IO_BASE
,
187 (pci_io
->bus_lower
& 0x0000f000) >> 8);
188 pci_hose_write_config_word(hose
, dev
, PCI_IO_BASE_UPPER16
,
189 (pci_io
->bus_lower
& 0xffff0000) >> 16);
191 cmdstat
|= PCI_COMMAND_IO
;
194 /* We don't support prefetchable memory for now, so disable */
195 pci_hose_write_config_word(hose
, dev
, PCI_PREF_MEMORY_BASE
, 0x1000);
196 pci_hose_write_config_word(hose
, dev
, PCI_PREF_MEMORY_LIMIT
, 0x1000);
198 /* Enable memory and I/O accesses, enable bus master */
199 pci_hose_write_config_dword(hose
, dev
, PCI_COMMAND
, cmdstat
| PCI_COMMAND_MASTER
);
202 static void pciauto_postscan_setup_bridge(struct pci_controller
*hose
,
203 pci_dev_t dev
, int sub_bus
)
205 struct pci_region
*pci_mem
= hose
->pci_mem
;
206 struct pci_region
*pci_io
= hose
->pci_io
;
208 /* Configure bus number registers */
209 pci_hose_write_config_byte(hose
, dev
, PCI_SUBORDINATE_BUS
, sub_bus
);
213 /* Round memory allocator to 1MB boundary */
214 pciauto_region_align(pci_mem
, 0x100000);
216 pci_hose_write_config_word(hose
, dev
, PCI_MEMORY_LIMIT
,
217 (pci_mem
->bus_lower
-1) >> 16);
222 /* Round I/O allocator to 4KB boundary */
223 pciauto_region_align(pci_io
, 0x1000);
225 pci_hose_write_config_byte(hose
, dev
, PCI_IO_LIMIT
,
226 ((pci_io
->bus_lower
-1) & 0x0000f000) >> 8);
227 pci_hose_write_config_word(hose
, dev
, PCI_IO_LIMIT_UPPER16
,
228 ((pci_io
->bus_lower
-1) & 0xffff0000) >> 16);
236 void pciauto_config_init(struct pci_controller
*hose
)
240 hose
->pci_io
= hose
->pci_mem
= NULL
;
242 for (i
=0; i
<hose
->region_count
; i
++)
244 switch(hose
->regions
[i
].flags
)
248 hose
->pci_io
->size
< hose
->regions
[i
].size
)
249 hose
->pci_io
= hose
->regions
+ i
;
252 if (!hose
->pci_mem
||
253 hose
->pci_mem
->size
< hose
->regions
[i
].size
)
254 hose
->pci_mem
= hose
->regions
+ i
;
262 pciauto_region_init(hose
->pci_mem
);
264 DEBUGF("PCI Autoconfig: Memory region: [%lx-%lx]\n",
265 hose
->pci_mem
->bus_start
,
266 hose
->pci_mem
->bus_start
+ hose
->pci_mem
->size
- 1);
271 pciauto_region_init(hose
->pci_io
);
273 DEBUGF("PCI Autoconfig: I/O region: [%lx-%lx]\n",
274 hose
->pci_io
->bus_start
,
275 hose
->pci_io
->bus_start
+ hose
->pci_io
->size
- 1);
279 /* HJF: Changed this to return int. I think this is required
280 * to get the correct result when scanning bridges
282 int pciauto_config_device(struct pci_controller
*hose
, pci_dev_t dev
)
284 unsigned int sub_bus
= PCI_BUS(dev
);
285 unsigned short class;
286 unsigned char prg_iface
;
288 pci_hose_read_config_word(hose
, dev
, PCI_CLASS_DEVICE
, &class);
292 case PCI_CLASS_BRIDGE_PCI
:
293 hose
->current_busno
++;
294 pciauto_setup_device(hose
, dev
, 2, hose
->pci_mem
, hose
->pci_io
);
296 DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev
));
297 pciauto_prescan_setup_bridge(hose
, dev
, sub_bus
);
299 pci_hose_scan_bus(hose
, hose
->current_busno
);
301 pciauto_postscan_setup_bridge(hose
, dev
, sub_bus
);
302 sub_bus
= hose
->current_busno
;
305 case PCI_CLASS_STORAGE_IDE
:
306 pci_hose_read_config_byte(hose
, dev
, PCI_CLASS_PROG
, &prg_iface
);
307 if (!(prg_iface
& PCIAUTO_IDE_MODE_MASK
))
309 DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
313 pciauto_setup_device(hose
, dev
, 6, hose
->pci_mem
, hose
->pci_io
);
316 case PCI_CLASS_BRIDGE_CARDBUS
:
317 /* just do a minimal setup of the bridge, let the OS take care of the rest */
318 pciauto_setup_device(hose
, dev
, 0, hose
->pci_mem
, hose
->pci_io
);
320 DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
323 hose
->current_busno
++;
327 pciauto_setup_device(hose
, dev
, 6, hose
->pci_mem
, hose
->pci_io
);
334 #endif /* CONFIG_PCI */