15283ecb5SPaul Mundt /* 25283ecb5SPaul Mundt * Low-Level PCI Support for the SH7780 35283ecb5SPaul Mundt * 4a45635dfSPaul Mundt * Copyright (C) 2005 - 2010 Paul Mundt 55283ecb5SPaul Mundt * 662c7ae87SPaul Mundt * This file is subject to the terms and conditions of the GNU General Public 762c7ae87SPaul Mundt * License. See the file "COPYING" in the main directory of this archive 862c7ae87SPaul Mundt * for more details. 95283ecb5SPaul Mundt */ 105283ecb5SPaul Mundt #include <linux/types.h> 115283ecb5SPaul Mundt #include <linux/kernel.h> 125283ecb5SPaul Mundt #include <linux/init.h> 135283ecb5SPaul Mundt #include <linux/pci.h> 14*ef407beeSPaul Mundt #include <linux/interrupt.h> 15*ef407beeSPaul Mundt #include <linux/timer.h> 16*ef407beeSPaul Mundt #include <linux/irq.h> 175283ecb5SPaul Mundt #include <linux/errno.h> 185283ecb5SPaul Mundt #include <linux/delay.h> 19aee4467bSPaul Mundt #include <linux/log2.h> 20959f85f8SPaul Mundt #include "pci-sh4.h" 21a45635dfSPaul Mundt #include <asm/mmu.h> 22a45635dfSPaul Mundt #include <asm/sizes.h> 235283ecb5SPaul Mundt 24e79066a6SPaul Mundt static struct resource sh7785_io_resource = { 25e79066a6SPaul Mundt .name = "SH7785_IO", 26a45635dfSPaul Mundt .start = 0x1000, 27a45635dfSPaul Mundt .end = SH7780_PCI_IO_SIZE - 1, 28e79066a6SPaul Mundt .flags = IORESOURCE_IO 29e79066a6SPaul Mundt }; 30e79066a6SPaul Mundt 31e79066a6SPaul Mundt static struct resource sh7785_mem_resource = { 32e79066a6SPaul Mundt .name = "SH7785_mem", 33e79066a6SPaul Mundt .start = SH7780_PCI_MEMORY_BASE, 34e79066a6SPaul Mundt .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, 35e79066a6SPaul Mundt .flags = IORESOURCE_MEM 36e79066a6SPaul Mundt }; 37e79066a6SPaul Mundt 38e79066a6SPaul Mundt static struct pci_channel sh7780_pci_controller = { 39e79066a6SPaul Mundt .pci_ops = &sh4_pci_ops, 40e79066a6SPaul Mundt .mem_resource = &sh7785_mem_resource, 4109cfeb13SPaul Mundt .mem_offset = 0x00000000, 42e79066a6SPaul Mundt .io_resource = &sh7785_io_resource, 4309cfeb13SPaul Mundt .io_offset = 0x00000000, 445582b064SPaul Mundt .io_map_base = SH7780_PCI_IO_BASE, 45*ef407beeSPaul Mundt .serr_irq = evt2irq(0xa00), 46*ef407beeSPaul Mundt .err_irq = evt2irq(0xaa0), 47e79066a6SPaul Mundt }; 48e79066a6SPaul Mundt 49*ef407beeSPaul Mundt struct pci_errors { 50*ef407beeSPaul Mundt unsigned int mask; 51*ef407beeSPaul Mundt const char *str; 52*ef407beeSPaul Mundt } pci_arbiter_errors[] = { 53*ef407beeSPaul Mundt { SH4_PCIAINT_MBKN, "master broken" }, 54*ef407beeSPaul Mundt { SH4_PCIAINT_TBTO, "target bus time out" }, 55*ef407beeSPaul Mundt { SH4_PCIAINT_MBTO, "master bus time out" }, 56*ef407beeSPaul Mundt { SH4_PCIAINT_TABT, "target abort" }, 57*ef407beeSPaul Mundt { SH4_PCIAINT_MABT, "master abort" }, 58*ef407beeSPaul Mundt { SH4_PCIAINT_RDPE, "read data parity error" }, 59*ef407beeSPaul Mundt { SH4_PCIAINT_WDPE, "write data parity error" }, 60*ef407beeSPaul Mundt }, pci_interrupt_errors[] = { 61*ef407beeSPaul Mundt { SH4_PCIINT_MLCK, "master lock error" }, 62*ef407beeSPaul Mundt { SH4_PCIINT_TABT, "target-target abort" }, 63*ef407beeSPaul Mundt { SH4_PCIINT_TRET, "target retry time out" }, 64*ef407beeSPaul Mundt { SH4_PCIINT_MFDE, "master function disable erorr" }, 65*ef407beeSPaul Mundt { SH4_PCIINT_PRTY, "address parity error" }, 66*ef407beeSPaul Mundt { SH4_PCIINT_SERR, "SERR" }, 67*ef407beeSPaul Mundt { SH4_PCIINT_TWDP, "data parity error for target write" }, 68*ef407beeSPaul Mundt { SH4_PCIINT_TRDP, "PERR detected for target read" }, 69*ef407beeSPaul Mundt { SH4_PCIINT_MTABT, "target abort for master" }, 70*ef407beeSPaul Mundt { SH4_PCIINT_MMABT, "master abort for master" }, 71*ef407beeSPaul Mundt { SH4_PCIINT_MWPD, "master write data parity error" }, 72*ef407beeSPaul Mundt { SH4_PCIINT_MRPD, "master read data parity error" }, 73*ef407beeSPaul Mundt }; 74*ef407beeSPaul Mundt 75*ef407beeSPaul Mundt static irqreturn_t sh7780_pci_err_irq(int irq, void *dev_id) 76*ef407beeSPaul Mundt { 77*ef407beeSPaul Mundt struct pci_channel *hose = dev_id; 78*ef407beeSPaul Mundt unsigned long addr; 79*ef407beeSPaul Mundt unsigned int status; 80*ef407beeSPaul Mundt unsigned int cmd; 81*ef407beeSPaul Mundt int i; 82*ef407beeSPaul Mundt 83*ef407beeSPaul Mundt addr = __raw_readl(hose->reg_base + SH4_PCIALR); 84*ef407beeSPaul Mundt 85*ef407beeSPaul Mundt /* 86*ef407beeSPaul Mundt * Handle status errors. 87*ef407beeSPaul Mundt */ 88*ef407beeSPaul Mundt status = __raw_readw(hose->reg_base + PCI_STATUS); 89*ef407beeSPaul Mundt if (status & (PCI_STATUS_PARITY | 90*ef407beeSPaul Mundt PCI_STATUS_DETECTED_PARITY | 91*ef407beeSPaul Mundt PCI_STATUS_SIG_TARGET_ABORT | 92*ef407beeSPaul Mundt PCI_STATUS_REC_TARGET_ABORT | 93*ef407beeSPaul Mundt PCI_STATUS_REC_MASTER_ABORT)) { 94*ef407beeSPaul Mundt cmd = pcibios_handle_status_errors(addr, status, hose); 95*ef407beeSPaul Mundt if (likely(cmd)) 96*ef407beeSPaul Mundt __raw_writew(cmd, hose->reg_base + PCI_STATUS); 97*ef407beeSPaul Mundt } 98*ef407beeSPaul Mundt 99*ef407beeSPaul Mundt /* 100*ef407beeSPaul Mundt * Handle arbiter errors. 101*ef407beeSPaul Mundt */ 102*ef407beeSPaul Mundt status = __raw_readl(hose->reg_base + SH4_PCIAINT); 103*ef407beeSPaul Mundt for (i = cmd = 0; i < ARRAY_SIZE(pci_arbiter_errors); i++) { 104*ef407beeSPaul Mundt if (status & pci_arbiter_errors[i].mask) { 105*ef407beeSPaul Mundt printk(KERN_DEBUG "PCI: %s, addr=%08lx\n", 106*ef407beeSPaul Mundt pci_arbiter_errors[i].str, addr); 107*ef407beeSPaul Mundt cmd |= pci_arbiter_errors[i].mask; 108*ef407beeSPaul Mundt } 109*ef407beeSPaul Mundt } 110*ef407beeSPaul Mundt __raw_writel(cmd, hose->reg_base + SH4_PCIAINT); 111*ef407beeSPaul Mundt 112*ef407beeSPaul Mundt /* 113*ef407beeSPaul Mundt * Handle the remaining PCI errors. 114*ef407beeSPaul Mundt */ 115*ef407beeSPaul Mundt status = __raw_readl(hose->reg_base + SH4_PCIINT); 116*ef407beeSPaul Mundt for (i = cmd = 0; i < ARRAY_SIZE(pci_interrupt_errors); i++) { 117*ef407beeSPaul Mundt if (status & pci_interrupt_errors[i].mask) { 118*ef407beeSPaul Mundt printk(KERN_DEBUG "PCI: %s, addr=%08lx\n", 119*ef407beeSPaul Mundt pci_interrupt_errors[i].str, addr); 120*ef407beeSPaul Mundt cmd |= pci_interrupt_errors[i].mask; 121*ef407beeSPaul Mundt } 122*ef407beeSPaul Mundt } 123*ef407beeSPaul Mundt __raw_writel(cmd, hose->reg_base + SH4_PCIINT); 124*ef407beeSPaul Mundt 125*ef407beeSPaul Mundt return IRQ_HANDLED; 126*ef407beeSPaul Mundt } 127*ef407beeSPaul Mundt 128*ef407beeSPaul Mundt static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id) 129*ef407beeSPaul Mundt { 130*ef407beeSPaul Mundt struct pci_channel *hose = dev_id; 131*ef407beeSPaul Mundt 132*ef407beeSPaul Mundt printk(KERN_DEBUG "PCI: system error received: "); 133*ef407beeSPaul Mundt pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1); 134*ef407beeSPaul Mundt printk("\n"); 135*ef407beeSPaul Mundt 136*ef407beeSPaul Mundt /* Deassert SERR */ 137*ef407beeSPaul Mundt __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM); 138*ef407beeSPaul Mundt 139*ef407beeSPaul Mundt /* Back off the IRQ for awhile */ 140*ef407beeSPaul Mundt disable_irq(irq); 141*ef407beeSPaul Mundt hose->serr_timer.expires = jiffies + HZ; 142*ef407beeSPaul Mundt add_timer(&hose->serr_timer); 143*ef407beeSPaul Mundt 144*ef407beeSPaul Mundt return IRQ_HANDLED; 145*ef407beeSPaul Mundt } 146*ef407beeSPaul Mundt 147*ef407beeSPaul Mundt static int __init sh7780_pci_setup_irqs(struct pci_channel *hose) 148*ef407beeSPaul Mundt { 149*ef407beeSPaul Mundt int ret; 150*ef407beeSPaul Mundt 151*ef407beeSPaul Mundt /* Clear out PCI arbiter IRQs */ 152*ef407beeSPaul Mundt __raw_writel(0, hose->reg_base + SH4_PCIAINT); 153*ef407beeSPaul Mundt 154*ef407beeSPaul Mundt /* Clear all error conditions */ 155*ef407beeSPaul Mundt __raw_writew(PCI_STATUS_DETECTED_PARITY | \ 156*ef407beeSPaul Mundt PCI_STATUS_SIG_SYSTEM_ERROR | \ 157*ef407beeSPaul Mundt PCI_STATUS_REC_MASTER_ABORT | \ 158*ef407beeSPaul Mundt PCI_STATUS_REC_TARGET_ABORT | \ 159*ef407beeSPaul Mundt PCI_STATUS_SIG_TARGET_ABORT | \ 160*ef407beeSPaul Mundt PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS); 161*ef407beeSPaul Mundt 162*ef407beeSPaul Mundt ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED, 163*ef407beeSPaul Mundt "PCI SERR interrupt", hose); 164*ef407beeSPaul Mundt if (unlikely(ret)) { 165*ef407beeSPaul Mundt printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n"); 166*ef407beeSPaul Mundt return ret; 167*ef407beeSPaul Mundt } 168*ef407beeSPaul Mundt 169*ef407beeSPaul Mundt /* 170*ef407beeSPaul Mundt * The PCI ERR IRQ needs to be IRQF_SHARED since all of the power 171*ef407beeSPaul Mundt * down IRQ vectors are routed through the ERR IRQ vector. We 172*ef407beeSPaul Mundt * only request_irq() once as there is only a single masking 173*ef407beeSPaul Mundt * source for multiple events. 174*ef407beeSPaul Mundt */ 175*ef407beeSPaul Mundt ret = request_irq(hose->err_irq, sh7780_pci_err_irq, IRQF_SHARED, 176*ef407beeSPaul Mundt "PCI ERR interrupt", hose); 177*ef407beeSPaul Mundt if (unlikely(ret)) { 178*ef407beeSPaul Mundt free_irq(hose->serr_irq, hose); 179*ef407beeSPaul Mundt return ret; 180*ef407beeSPaul Mundt } 181*ef407beeSPaul Mundt 182*ef407beeSPaul Mundt /* Unmask all of the arbiter IRQs. */ 183*ef407beeSPaul Mundt __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \ 184*ef407beeSPaul Mundt SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \ 185*ef407beeSPaul Mundt SH4_PCIAINT_WDPE, hose->reg_base + SH4_PCIAINTM); 186*ef407beeSPaul Mundt 187*ef407beeSPaul Mundt /* Unmask all of the PCI IRQs */ 188*ef407beeSPaul Mundt __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \ 189*ef407beeSPaul Mundt SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \ 190*ef407beeSPaul Mundt SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \ 191*ef407beeSPaul Mundt SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \ 192*ef407beeSPaul Mundt SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \ 193*ef407beeSPaul Mundt SH4_PCIINTM_MRDPEIM, hose->reg_base + SH4_PCIINTM); 194*ef407beeSPaul Mundt 195*ef407beeSPaul Mundt return ret; 196*ef407beeSPaul Mundt } 197*ef407beeSPaul Mundt 198*ef407beeSPaul Mundt static inline void __init sh7780_pci_teardown_irqs(struct pci_channel *hose) 199*ef407beeSPaul Mundt { 200*ef407beeSPaul Mundt free_irq(hose->err_irq, hose); 201*ef407beeSPaul Mundt free_irq(hose->serr_irq, hose); 202*ef407beeSPaul Mundt } 203*ef407beeSPaul Mundt 20485b59f5bSPaul Mundt static void __init sh7780_pci66_init(struct pci_channel *hose) 20585b59f5bSPaul Mundt { 20685b59f5bSPaul Mundt unsigned int tmp; 20785b59f5bSPaul Mundt 20885b59f5bSPaul Mundt if (!pci_is_66mhz_capable(hose, 0, 0)) 20985b59f5bSPaul Mundt return; 21085b59f5bSPaul Mundt 21185b59f5bSPaul Mundt /* Enable register access */ 21285b59f5bSPaul Mundt tmp = __raw_readl(hose->reg_base + SH4_PCICR); 21385b59f5bSPaul Mundt tmp |= SH4_PCICR_PREFIX; 21485b59f5bSPaul Mundt __raw_writel(tmp, hose->reg_base + SH4_PCICR); 21585b59f5bSPaul Mundt 21685b59f5bSPaul Mundt /* Enable 66MHz operation */ 21785b59f5bSPaul Mundt tmp = __raw_readw(hose->reg_base + PCI_STATUS); 21885b59f5bSPaul Mundt tmp |= PCI_STATUS_66MHZ; 21985b59f5bSPaul Mundt __raw_writew(tmp, hose->reg_base + PCI_STATUS); 22085b59f5bSPaul Mundt 22185b59f5bSPaul Mundt /* Done */ 22285b59f5bSPaul Mundt tmp = __raw_readl(hose->reg_base + SH4_PCICR); 22385b59f5bSPaul Mundt tmp |= SH4_PCICR_PREFIX | SH4_PCICR_CFIN; 22485b59f5bSPaul Mundt __raw_writel(tmp, hose->reg_base + SH4_PCICR); 22585b59f5bSPaul Mundt } 22685b59f5bSPaul Mundt 227e79066a6SPaul Mundt static int __init sh7780_pci_init(void) 2285283ecb5SPaul Mundt { 229e79066a6SPaul Mundt struct pci_channel *chan = &sh7780_pci_controller; 230a45635dfSPaul Mundt phys_addr_t memphys; 231a45635dfSPaul Mundt size_t memsize; 232959f85f8SPaul Mundt unsigned int id; 233a45635dfSPaul Mundt const char *type; 234bcf39352SPaul Mundt int ret; 2355283ecb5SPaul Mundt 2364e7b7fdbSPaul Mundt printk(KERN_NOTICE "PCI: Starting intialization.\n"); 2375283ecb5SPaul Mundt 238e4c6a360SMagnus Damm chan->reg_base = 0xfe040000; 239e4c6a360SMagnus Damm 2404e7b7fdbSPaul Mundt /* Enable CPU access to the PCIC registers. */ 2414e7b7fdbSPaul Mundt __raw_writel(PCIECR_ENBL, PCIECR); 242959f85f8SPaul Mundt 243a45635dfSPaul Mundt /* Reset */ 244a45635dfSPaul Mundt __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, 245a45635dfSPaul Mundt chan->reg_base + SH4_PCICR); 246a45635dfSPaul Mundt 247aee4467bSPaul Mundt /* 248aee4467bSPaul Mundt * Wait for it to come back up. The spec says to allow for up to 249aee4467bSPaul Mundt * 1 second after toggling the reset pin, but in practice 100ms 250aee4467bSPaul Mundt * is more than enough. 251aee4467bSPaul Mundt */ 252a45635dfSPaul Mundt mdelay(100); 253a45635dfSPaul Mundt 254a45635dfSPaul Mundt id = __raw_readw(chan->reg_base + PCI_VENDOR_ID); 255a45635dfSPaul Mundt if (id != PCI_VENDOR_ID_RENESAS) { 2564e7b7fdbSPaul Mundt printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); 257959f85f8SPaul Mundt return -ENODEV; 258959f85f8SPaul Mundt } 259959f85f8SPaul Mundt 260a45635dfSPaul Mundt id = __raw_readw(chan->reg_base + PCI_DEVICE_ID); 261a45635dfSPaul Mundt type = (id == PCI_DEVICE_ID_RENESAS_SH7763) ? "SH7763" : 262a45635dfSPaul Mundt (id == PCI_DEVICE_ID_RENESAS_SH7780) ? "SH7780" : 263a45635dfSPaul Mundt (id == PCI_DEVICE_ID_RENESAS_SH7781) ? "SH7781" : 264a45635dfSPaul Mundt (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" : 2654e7b7fdbSPaul Mundt NULL; 2664e7b7fdbSPaul Mundt if (unlikely(!type)) { 2674e7b7fdbSPaul Mundt printk(KERN_ERR "PCI: Found an unsupported Renesas host " 2684e7b7fdbSPaul Mundt "controller, device id 0x%04x.\n", id); 2694e7b7fdbSPaul Mundt return -EINVAL; 2704e7b7fdbSPaul Mundt } 2714e7b7fdbSPaul Mundt 2724e7b7fdbSPaul Mundt printk(KERN_NOTICE "PCI: Found a Renesas %s host " 2734e7b7fdbSPaul Mundt "controller, revision %d.\n", type, 274a45635dfSPaul Mundt __raw_readb(chan->reg_base + PCI_REVISION_ID)); 2754e7b7fdbSPaul Mundt 276c66c1d79SPaul Mundt /* 277a45635dfSPaul Mundt * Now throw it in to register initialization mode and 278a45635dfSPaul Mundt * start the real work. 279c66c1d79SPaul Mundt */ 280a45635dfSPaul Mundt __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); 281a45635dfSPaul Mundt 282a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); 2835283ecb5SPaul Mundt 284aee4467bSPaul Mundt memphys = __pa(memory_start); 285aee4467bSPaul Mundt memsize = roundup_pow_of_two(memory_end - memory_start); 286aee4467bSPaul Mundt 287aee4467bSPaul Mundt /* 288aee4467bSPaul Mundt * If there's more than 512MB of memory, we need to roll over to 289aee4467bSPaul Mundt * LAR1/LSR1. 290aee4467bSPaul Mundt */ 291aee4467bSPaul Mundt if (memsize > SZ_512M) { 292aee4467bSPaul Mundt __raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1); 293aee4467bSPaul Mundt __raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1, 294aee4467bSPaul Mundt chan->reg_base + SH4_PCILSR1); 295aee4467bSPaul Mundt memsize = SZ_512M; 296aee4467bSPaul Mundt } else { 297aee4467bSPaul Mundt /* 298aee4467bSPaul Mundt * Otherwise just zero it out and disable it. 299aee4467bSPaul Mundt */ 300aee4467bSPaul Mundt __raw_writel(0, chan->reg_base + SH4_PCILAR1); 301aee4467bSPaul Mundt __raw_writel(0, chan->reg_base + SH4_PCILSR1); 302aee4467bSPaul Mundt } 303aee4467bSPaul Mundt 304aee4467bSPaul Mundt /* 305aee4467bSPaul Mundt * LAR0/LSR0 covers up to the first 512MB, which is enough to 306aee4467bSPaul Mundt * cover all of lowmem on most platforms. 307aee4467bSPaul Mundt */ 308a45635dfSPaul Mundt __raw_writel(memphys, chan->reg_base + SH4_PCILAR0); 309aee4467bSPaul Mundt __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, 310a45635dfSPaul Mundt chan->reg_base + SH4_PCILSR0); 31162c7ae87SPaul Mundt 312*ef407beeSPaul Mundt /* 313*ef407beeSPaul Mundt * Hook up the ERR and SERR IRQs. 314*ef407beeSPaul Mundt */ 315*ef407beeSPaul Mundt ret = sh7780_pci_setup_irqs(chan); 316*ef407beeSPaul Mundt if (unlikely(ret)) 317*ef407beeSPaul Mundt return ret; 31862c7ae87SPaul Mundt 319a45635dfSPaul Mundt /* 320a45635dfSPaul Mundt * Disable the cache snoop controller for non-coherent DMA. 321a45635dfSPaul Mundt */ 322a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + SH7780_PCICSCR0); 323a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + SH7780_PCICSAR0); 324a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + SH7780_PCICSCR1); 325a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + SH7780_PCICSAR1); 32662c7ae87SPaul Mundt 327a45635dfSPaul Mundt __raw_writel(0xfd000000, chan->reg_base + SH7780_PCIMBR0); 328a45635dfSPaul Mundt __raw_writel(0x00fc0000, chan->reg_base + SH7780_PCIMBMR0); 329a45635dfSPaul Mundt 330a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); 331a45635dfSPaul Mundt __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); 332a45635dfSPaul Mundt 333*ef407beeSPaul Mundt __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ 334*ef407beeSPaul Mundt PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ 335*ef407beeSPaul Mundt PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); 336*ef407beeSPaul Mundt 337a45635dfSPaul Mundt /* 338a45635dfSPaul Mundt * Initialization mode complete, release the control register and 339a45635dfSPaul Mundt * enable round robin mode to stop device overruns/starvation. 340a45635dfSPaul Mundt */ 341a45635dfSPaul Mundt __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO, 342a45635dfSPaul Mundt chan->reg_base + SH4_PCICR); 3435283ecb5SPaul Mundt 344bcf39352SPaul Mundt ret = register_pci_controller(chan); 345bcf39352SPaul Mundt if (unlikely(ret)) 346*ef407beeSPaul Mundt goto err; 347e79066a6SPaul Mundt 34885b59f5bSPaul Mundt sh7780_pci66_init(chan); 34985b59f5bSPaul Mundt 35085b59f5bSPaul Mundt printk(KERN_NOTICE "PCI: Running at %dMHz.\n", 35185b59f5bSPaul Mundt (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ? 35285b59f5bSPaul Mundt 66 : 33); 35385b59f5bSPaul Mundt 354d0e3db40SMagnus Damm return 0; 355*ef407beeSPaul Mundt 356*ef407beeSPaul Mundt err: 357*ef407beeSPaul Mundt sh7780_pci_teardown_irqs(chan); 358*ef407beeSPaul Mundt return ret; 3595283ecb5SPaul Mundt } 360e79066a6SPaul Mundt arch_initcall(sh7780_pci_init); 361