1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * SH7763 Setup 4 * 5 * Copyright (C) 2006 Paul Mundt 6 * Copyright (C) 2007 Yoshihiro Shimoda 7 * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu 8 */ 9 #include <linux/platform_device.h> 10 #include <linux/init.h> 11 #include <linux/serial.h> 12 #include <linux/sh_timer.h> 13 #include <linux/sh_intc.h> 14 #include <linux/io.h> 15 #include <linux/serial_sci.h> 16 #include <linux/usb/ohci_pdriver.h> 17 #include <asm/platform_early.h> 18 19 static struct plat_sci_port scif0_platform_data = { 20 .scscr = SCSCR_REIE, 21 .type = PORT_SCIF, 22 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 23 }; 24 25 static struct resource scif0_resources[] = { 26 DEFINE_RES_MEM(0xffe00000, 0x100), 27 DEFINE_RES_IRQ(evt2irq(0x700)), 28 }; 29 30 static struct platform_device scif0_device = { 31 .name = "sh-sci", 32 .id = 0, 33 .resource = scif0_resources, 34 .num_resources = ARRAY_SIZE(scif0_resources), 35 .dev = { 36 .platform_data = &scif0_platform_data, 37 }, 38 }; 39 40 static struct plat_sci_port scif1_platform_data = { 41 .scscr = SCSCR_REIE, 42 .type = PORT_SCIF, 43 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 44 }; 45 46 static struct resource scif1_resources[] = { 47 DEFINE_RES_MEM(0xffe08000, 0x100), 48 DEFINE_RES_IRQ(evt2irq(0xb80)), 49 }; 50 51 static struct platform_device scif1_device = { 52 .name = "sh-sci", 53 .id = 1, 54 .resource = scif1_resources, 55 .num_resources = ARRAY_SIZE(scif1_resources), 56 .dev = { 57 .platform_data = &scif1_platform_data, 58 }, 59 }; 60 61 static struct plat_sci_port scif2_platform_data = { 62 .scscr = SCSCR_REIE, 63 .type = PORT_SCIF, 64 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 65 }; 66 67 static struct resource scif2_resources[] = { 68 DEFINE_RES_MEM(0xffe10000, 0x100), 69 DEFINE_RES_IRQ(evt2irq(0xf00)), 70 }; 71 72 static struct platform_device scif2_device = { 73 .name = "sh-sci", 74 .id = 2, 75 .resource = scif2_resources, 76 .num_resources = ARRAY_SIZE(scif2_resources), 77 .dev = { 78 .platform_data = &scif2_platform_data, 79 }, 80 }; 81 82 static struct resource rtc_resources[] = { 83 [0] = { 84 .start = 0xffe80000, 85 .end = 0xffe80000 + 0x58 - 1, 86 .flags = IORESOURCE_IO, 87 }, 88 [1] = { 89 /* Shared Period/Carry/Alarm IRQ */ 90 .start = evt2irq(0x480), 91 .flags = IORESOURCE_IRQ, 92 }, 93 }; 94 95 static struct platform_device rtc_device = { 96 .name = "sh-rtc", 97 .id = -1, 98 .num_resources = ARRAY_SIZE(rtc_resources), 99 .resource = rtc_resources, 100 }; 101 102 static struct resource usb_ohci_resources[] = { 103 [0] = { 104 .start = 0xffec8000, 105 .end = 0xffec80ff, 106 .flags = IORESOURCE_MEM, 107 }, 108 [1] = { 109 .start = evt2irq(0xc60), 110 .end = evt2irq(0xc60), 111 .flags = IORESOURCE_IRQ, 112 }, 113 }; 114 115 static u64 usb_ohci_dma_mask = 0xffffffffUL; 116 117 static struct usb_ohci_pdata usb_ohci_pdata; 118 119 static struct platform_device usb_ohci_device = { 120 .name = "ohci-platform", 121 .id = -1, 122 .dev = { 123 .dma_mask = &usb_ohci_dma_mask, 124 .coherent_dma_mask = 0xffffffff, 125 .platform_data = &usb_ohci_pdata, 126 }, 127 .num_resources = ARRAY_SIZE(usb_ohci_resources), 128 .resource = usb_ohci_resources, 129 }; 130 131 static struct resource usbf_resources[] = { 132 [0] = { 133 .start = 0xffec0000, 134 .end = 0xffec00ff, 135 .flags = IORESOURCE_MEM, 136 }, 137 [1] = { 138 .start = evt2irq(0xc80), 139 .end = evt2irq(0xc80), 140 .flags = IORESOURCE_IRQ, 141 }, 142 }; 143 144 static struct platform_device usbf_device = { 145 .name = "sh_udc", 146 .id = -1, 147 .dev = { 148 .dma_mask = NULL, 149 .coherent_dma_mask = 0xffffffff, 150 }, 151 .num_resources = ARRAY_SIZE(usbf_resources), 152 .resource = usbf_resources, 153 }; 154 155 static struct sh_timer_config tmu0_platform_data = { 156 .channels_mask = 7, 157 }; 158 159 static struct resource tmu0_resources[] = { 160 DEFINE_RES_MEM(0xffd80000, 0x30), 161 DEFINE_RES_IRQ(evt2irq(0x580)), 162 DEFINE_RES_IRQ(evt2irq(0x5a0)), 163 DEFINE_RES_IRQ(evt2irq(0x5c0)), 164 }; 165 166 static struct platform_device tmu0_device = { 167 .name = "sh-tmu", 168 .id = 0, 169 .dev = { 170 .platform_data = &tmu0_platform_data, 171 }, 172 .resource = tmu0_resources, 173 .num_resources = ARRAY_SIZE(tmu0_resources), 174 }; 175 176 static struct sh_timer_config tmu1_platform_data = { 177 .channels_mask = 7, 178 }; 179 180 static struct resource tmu1_resources[] = { 181 DEFINE_RES_MEM(0xffd88000, 0x2c), 182 DEFINE_RES_IRQ(evt2irq(0xe00)), 183 DEFINE_RES_IRQ(evt2irq(0xe20)), 184 DEFINE_RES_IRQ(evt2irq(0xe40)), 185 }; 186 187 static struct platform_device tmu1_device = { 188 .name = "sh-tmu", 189 .id = 1, 190 .dev = { 191 .platform_data = &tmu1_platform_data, 192 }, 193 .resource = tmu1_resources, 194 .num_resources = ARRAY_SIZE(tmu1_resources), 195 }; 196 197 static struct platform_device *sh7763_devices[] __initdata = { 198 &scif0_device, 199 &scif1_device, 200 &scif2_device, 201 &tmu0_device, 202 &tmu1_device, 203 &rtc_device, 204 &usb_ohci_device, 205 &usbf_device, 206 }; 207 208 static int __init sh7763_devices_setup(void) 209 { 210 return platform_add_devices(sh7763_devices, 211 ARRAY_SIZE(sh7763_devices)); 212 } 213 arch_initcall(sh7763_devices_setup); 214 215 static struct platform_device *sh7763_early_devices[] __initdata = { 216 &scif0_device, 217 &scif1_device, 218 &scif2_device, 219 &tmu0_device, 220 &tmu1_device, 221 }; 222 223 void __init plat_early_device_setup(void) 224 { 225 sh_early_platform_add_devices(sh7763_early_devices, 226 ARRAY_SIZE(sh7763_early_devices)); 227 } 228 229 enum { 230 UNUSED = 0, 231 232 /* interrupt sources */ 233 234 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 235 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 236 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 237 IRL_HHLL, IRL_HHLH, IRL_HHHL, 238 239 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, 240 RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI, 241 HUDI, LCDC, DMAC, SCIF0, IIC0, IIC1, CMT, GETHER, HAC, 242 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5, 243 STIF0, STIF1, SCIF1, SIOF0, SIOF1, SIOF2, 244 USBH, USBF, TPU, PCC, MMCIF, SIM, 245 TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3, 246 SCIF2, GPIO, 247 248 /* interrupt groups */ 249 250 TMU012, TMU345, 251 }; 252 253 static struct intc_vect vectors[] __initdata = { 254 INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0), 255 INTC_VECT(RTC, 0x4c0), 256 INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580), 257 INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0), 258 INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600), 259 INTC_VECT(LCDC, 0x620), 260 INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660), 261 INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0), 262 INTC_VECT(DMAC, 0x6c0), 263 INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720), 264 INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760), 265 INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0), 266 INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0), 267 INTC_VECT(CMT, 0x900), INTC_VECT(GETHER, 0x920), 268 INTC_VECT(GETHER, 0x940), INTC_VECT(GETHER, 0x960), 269 INTC_VECT(HAC, 0x980), 270 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), 271 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), 272 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0), 273 INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0), 274 INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20), 275 INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60), 276 INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0), 277 INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0), 278 INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20), 279 INTC_VECT(USBH, 0xc60), INTC_VECT(USBF, 0xc80), 280 INTC_VECT(USBF, 0xca0), 281 INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0), 282 INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20), 283 INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60), 284 INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0), 285 INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0), 286 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), 287 INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60), 288 INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0), 289 INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0), 290 INTC_VECT(SCIF2, 0xf00), INTC_VECT(SCIF2, 0xf20), 291 INTC_VECT(SCIF2, 0xf40), INTC_VECT(SCIF2, 0xf60), 292 INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0), 293 INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0), 294 }; 295 296 static struct intc_group groups[] __initdata = { 297 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), 298 INTC_GROUP(TMU345, TMU3, TMU4, TMU5), 299 }; 300 301 static struct intc_mask_reg mask_registers[] __initdata = { 302 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ 303 { 0, 0, 0, 0, 0, 0, GPIO, 0, 304 SSI0, MMCIF, 0, SIOF0, PCIC5, PCIINTD, PCIINTC, PCIINTB, 305 PCIINTA, PCISERR, HAC, CMT, 0, 0, 0, DMAC, 306 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, 307 { 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */ 308 { 0, 0, 0, 0, 0, 0, SCIF2, USBF, 309 0, 0, STIF1, STIF0, 0, 0, USBH, GETHER, 310 PCC, 0, 0, ADC, TPU, SIM, SIOF2, SIOF1, 311 LCDC, 0, IIC1, IIC0, SSI3, SSI2, SSI1, 0 } }, 312 }; 313 314 static struct intc_prio_reg prio_registers[] __initdata = { 315 { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, 316 TMU2, TMU2_TICPI } }, 317 { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, 318 { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, 319 { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC, ADC } }, 320 { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC, 321 PCISERR, PCIINTA } }, 322 { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, 323 PCIINTD, PCIC5 } }, 324 { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF0, USBF, MMCIF, SSI0 } }, 325 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SCIF2, GPIO } }, 326 { 0xffd400a0, 0, 32, 8, /* INT2PRI8 */ { SSI3, SSI2, SSI1, 0 } }, 327 { 0xffd400a4, 0, 32, 8, /* INT2PRI9 */ { LCDC, 0, IIC1, IIC0 } }, 328 { 0xffd400a8, 0, 32, 8, /* INT2PRI10 */ { TPU, SIM, SIOF2, SIOF1 } }, 329 { 0xffd400ac, 0, 32, 8, /* INT2PRI11 */ { PCC } }, 330 { 0xffd400b0, 0, 32, 8, /* INT2PRI12 */ { 0, 0, USBH, GETHER } }, 331 { 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } }, 332 }; 333 334 static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups, 335 mask_registers, prio_registers, NULL); 336 337 /* Support for external interrupt pins in IRQ mode */ 338 static struct intc_vect irq_vectors[] __initdata = { 339 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), 340 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), 341 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), 342 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), 343 }; 344 345 static struct intc_mask_reg irq_mask_registers[] __initdata = { 346 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ 347 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 348 }; 349 350 static struct intc_prio_reg irq_prio_registers[] __initdata = { 351 { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, 352 IRQ4, IRQ5, IRQ6, IRQ7 } }, 353 }; 354 355 static struct intc_sense_reg irq_sense_registers[] __initdata = { 356 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, 357 IRQ4, IRQ5, IRQ6, IRQ7 } }, 358 }; 359 360 static struct intc_mask_reg irq_ack_registers[] __initdata = { 361 { 0xffd00024, 0, 32, /* INTREQ */ 362 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 363 }; 364 365 static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7763-irq", irq_vectors, 366 NULL, irq_mask_registers, irq_prio_registers, 367 irq_sense_registers, irq_ack_registers); 368 369 370 /* External interrupt pins in IRL mode */ 371 static struct intc_vect irl_vectors[] __initdata = { 372 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), 373 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), 374 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), 375 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), 376 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), 377 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), 378 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), 379 INTC_VECT(IRL_HHHL, 0x3c0), 380 }; 381 382 static struct intc_mask_reg irl3210_mask_registers[] __initdata = { 383 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ 384 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 385 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 386 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 387 IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, 388 }; 389 390 static struct intc_mask_reg irl7654_mask_registers[] __initdata = { 391 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ 392 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 393 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 394 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 395 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 396 IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, 397 }; 398 399 static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors, 400 NULL, irl7654_mask_registers, NULL, NULL); 401 402 static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors, 403 NULL, irl3210_mask_registers, NULL, NULL); 404 405 #define INTC_ICR0 0xffd00000 406 #define INTC_INTMSK0 0xffd00044 407 #define INTC_INTMSK1 0xffd00048 408 #define INTC_INTMSK2 0xffd40080 409 #define INTC_INTMSKCLR1 0xffd00068 410 #define INTC_INTMSKCLR2 0xffd40084 411 412 void __init plat_irq_setup(void) 413 { 414 /* disable IRQ7-0 */ 415 __raw_writel(0xff000000, INTC_INTMSK0); 416 417 /* disable IRL3-0 + IRL7-4 */ 418 __raw_writel(0xc0000000, INTC_INTMSK1); 419 __raw_writel(0xfffefffe, INTC_INTMSK2); 420 421 register_intc_controller(&intc_desc); 422 } 423 424 void __init plat_irq_setup_pins(int mode) 425 { 426 switch (mode) { 427 case IRQ_MODE_IRQ: 428 /* select IRQ mode for IRL3-0 + IRL7-4 */ 429 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0); 430 register_intc_controller(&intc_irq_desc); 431 break; 432 case IRQ_MODE_IRL7654: 433 /* enable IRL7-4 but don't provide any masking */ 434 __raw_writel(0x40000000, INTC_INTMSKCLR1); 435 __raw_writel(0x0000fffe, INTC_INTMSKCLR2); 436 break; 437 case IRQ_MODE_IRL3210: 438 /* enable IRL0-3 but don't provide any masking */ 439 __raw_writel(0x80000000, INTC_INTMSKCLR1); 440 __raw_writel(0xfffe0000, INTC_INTMSKCLR2); 441 break; 442 case IRQ_MODE_IRL7654_MASK: 443 /* enable IRL7-4 and mask using cpu intc controller */ 444 __raw_writel(0x40000000, INTC_INTMSKCLR1); 445 register_intc_controller(&intc_irl7654_desc); 446 break; 447 case IRQ_MODE_IRL3210_MASK: 448 /* enable IRL0-3 and mask using cpu intc controller */ 449 __raw_writel(0x80000000, INTC_INTMSKCLR1); 450 register_intc_controller(&intc_irl3210_desc); 451 break; 452 default: 453 BUG(); 454 } 455 } 456
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.