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