diff options
Diffstat (limited to 'arch/arm/plat-iop/pci.c')
-rw-r--r-- | arch/arm/plat-iop/pci.c | 140 |
1 files changed, 139 insertions, 1 deletions
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index b5f6ec35aafb..e2744b7227c5 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c | |||
@@ -55,7 +55,7 @@ static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where) | |||
55 | * This routine checks the status of the last configuration cycle. If an error | 55 | * This routine checks the status of the last configuration cycle. If an error |
56 | * was detected it returns a 1, else it returns a 0. The errors being checked | 56 | * was detected it returns a 1, else it returns a 0. The errors being checked |
57 | * are parity, master abort, target abort (master and target). These types of | 57 | * are parity, master abort, target abort (master and target). These types of |
58 | * errors occure during a config cycle where there is no device, like during | 58 | * errors occur during a config cycle where there is no device, like during |
59 | * the discovery stage. | 59 | * the discovery stage. |
60 | */ | 60 | */ |
61 | static int iop3xx_pci_status(void) | 61 | static int iop3xx_pci_status(void) |
@@ -223,8 +223,111 @@ struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) | |||
223 | return pci_scan_bus(sys->busnr, &iop3xx_ops, sys); | 223 | return pci_scan_bus(sys->busnr, &iop3xx_ops, sys); |
224 | } | 224 | } |
225 | 225 | ||
226 | void __init iop3xx_atu_setup(void) | ||
227 | { | ||
228 | /* BAR 0 ( Disabled ) */ | ||
229 | *IOP3XX_IAUBAR0 = 0x0; | ||
230 | *IOP3XX_IABAR0 = 0x0; | ||
231 | *IOP3XX_IATVR0 = 0x0; | ||
232 | *IOP3XX_IALR0 = 0x0; | ||
233 | |||
234 | /* BAR 1 ( Disabled ) */ | ||
235 | *IOP3XX_IAUBAR1 = 0x0; | ||
236 | *IOP3XX_IABAR1 = 0x0; | ||
237 | *IOP3XX_IALR1 = 0x0; | ||
238 | |||
239 | /* BAR 2 (1:1 mapping with Physical RAM) */ | ||
240 | /* Set limit and enable */ | ||
241 | *IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1; | ||
242 | *IOP3XX_IAUBAR2 = 0x0; | ||
243 | |||
244 | /* Align the inbound bar with the base of memory */ | ||
245 | *IOP3XX_IABAR2 = PHYS_OFFSET | | ||
246 | PCI_BASE_ADDRESS_MEM_TYPE_64 | | ||
247 | PCI_BASE_ADDRESS_MEM_PREFETCH; | ||
248 | |||
249 | *IOP3XX_IATVR2 = PHYS_OFFSET; | ||
250 | |||
251 | /* Outbound window 0 */ | ||
252 | *IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_PA; | ||
253 | *IOP3XX_OUMWTVR0 = 0; | ||
254 | |||
255 | /* Outbound window 1 */ | ||
256 | *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE; | ||
257 | *IOP3XX_OUMWTVR1 = 0; | ||
258 | |||
259 | /* BAR 3 ( Disabled ) */ | ||
260 | *IOP3XX_IAUBAR3 = 0x0; | ||
261 | *IOP3XX_IABAR3 = 0x0; | ||
262 | *IOP3XX_IATVR3 = 0x0; | ||
263 | *IOP3XX_IALR3 = 0x0; | ||
264 | |||
265 | /* Setup the I/O Bar | ||
266 | */ | ||
267 | *IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_PA;; | ||
268 | |||
269 | /* Enable inbound and outbound cycles | ||
270 | */ | ||
271 | *IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | | ||
272 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; | ||
273 | *IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN; | ||
274 | } | ||
275 | |||
276 | void __init iop3xx_atu_disable(void) | ||
277 | { | ||
278 | *IOP3XX_ATUCMD = 0; | ||
279 | *IOP3XX_ATUCR = 0; | ||
280 | |||
281 | /* wait for cycles to quiesce */ | ||
282 | while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY | | ||
283 | IOP3XX_PCSR_IN_Q_BUSY)) | ||
284 | cpu_relax(); | ||
285 | |||
286 | /* BAR 0 ( Disabled ) */ | ||
287 | *IOP3XX_IAUBAR0 = 0x0; | ||
288 | *IOP3XX_IABAR0 = 0x0; | ||
289 | *IOP3XX_IATVR0 = 0x0; | ||
290 | *IOP3XX_IALR0 = 0x0; | ||
291 | |||
292 | /* BAR 1 ( Disabled ) */ | ||
293 | *IOP3XX_IAUBAR1 = 0x0; | ||
294 | *IOP3XX_IABAR1 = 0x0; | ||
295 | *IOP3XX_IALR1 = 0x0; | ||
296 | |||
297 | /* BAR 2 ( Disabled ) */ | ||
298 | *IOP3XX_IAUBAR2 = 0x0; | ||
299 | *IOP3XX_IABAR2 = 0x0; | ||
300 | *IOP3XX_IATVR2 = 0x0; | ||
301 | *IOP3XX_IALR2 = 0x0; | ||
302 | |||
303 | /* BAR 3 ( Disabled ) */ | ||
304 | *IOP3XX_IAUBAR3 = 0x0; | ||
305 | *IOP3XX_IABAR3 = 0x0; | ||
306 | *IOP3XX_IATVR3 = 0x0; | ||
307 | *IOP3XX_IALR3 = 0x0; | ||
308 | |||
309 | /* Clear the outbound windows */ | ||
310 | *IOP3XX_OIOWTVR = 0; | ||
311 | |||
312 | /* Outbound window 0 */ | ||
313 | *IOP3XX_OMWTVR0 = 0; | ||
314 | *IOP3XX_OUMWTVR0 = 0; | ||
315 | |||
316 | /* Outbound window 1 */ | ||
317 | *IOP3XX_OMWTVR1 = 0; | ||
318 | *IOP3XX_OUMWTVR1 = 0; | ||
319 | } | ||
320 | |||
321 | /* Flag to determine whether the ATU is initialized and the PCI bus scanned */ | ||
322 | int init_atu; | ||
323 | |||
226 | void iop3xx_pci_preinit(void) | 324 | void iop3xx_pci_preinit(void) |
227 | { | 325 | { |
326 | if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) { | ||
327 | iop3xx_atu_disable(); | ||
328 | iop3xx_atu_setup(); | ||
329 | } | ||
330 | |||
228 | DBG("PCI: Intel 803xx PCI init code.\n"); | 331 | DBG("PCI: Intel 803xx PCI init code.\n"); |
229 | DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); | 332 | DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); |
230 | DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n", | 333 | DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n", |
@@ -245,3 +348,38 @@ void iop3xx_pci_preinit(void) | |||
245 | 348 | ||
246 | hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); | 349 | hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); |
247 | } | 350 | } |
351 | |||
352 | /* allow init_atu to be user overridden */ | ||
353 | static int __init iop3xx_init_atu_setup(char *str) | ||
354 | { | ||
355 | init_atu = IOP3XX_INIT_ATU_DEFAULT; | ||
356 | if (str) { | ||
357 | while (*str != '\0') { | ||
358 | switch (*str) { | ||
359 | case 'y': | ||
360 | case 'Y': | ||
361 | init_atu = IOP3XX_INIT_ATU_ENABLE; | ||
362 | break; | ||
363 | case 'n': | ||
364 | case 'N': | ||
365 | init_atu = IOP3XX_INIT_ATU_DISABLE; | ||
366 | break; | ||
367 | case ',': | ||
368 | case '=': | ||
369 | break; | ||
370 | default: | ||
371 | printk(KERN_DEBUG "\"%s\" malformed at " | ||
372 | "character: \'%c\'", | ||
373 | __FUNCTION__, | ||
374 | *str); | ||
375 | *(str + 1) = '\0'; | ||
376 | } | ||
377 | str++; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | return 1; | ||
382 | } | ||
383 | |||
384 | __setup("iop3xx_init_atu", iop3xx_init_atu_setup); | ||
385 | |||