aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-iop/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-iop/pci.c')
-rw-r--r--arch/arm/plat-iop/pci.c140
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 */
61static int iop3xx_pci_status(void) 61static 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
226void __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
276void __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 */
322int init_atu;
323
226void iop3xx_pci_preinit(void) 324void 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 */
353static 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