1 /* 2 * SH7720 Setup 3 * 4 * Copyright (C) 2007 Markus Brunner, Mark Jonas 5 * Copyright (C) 2009 Paul Mundt 6 * 7 * Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c: 8 * 9 * Copyright (C) 2006 Paul Mundt 10 * Copyright (C) 2006 Jamie Lenehan 11 * 12 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file "COPYING" in the main directory of this archive 14 * for more details. 15 */ 16 #include <linux/platform_device.h> 17 #include <linux/init.h> 18 #include <linux/serial.h> 19 #include <linux/io.h> 20 #include <linux/serial_sci.h> 21 #include <linux/sh_timer.h> 22 #include <asm/rtc.h> 23 24 static struct resource rtc_resources[] = { 25 [0] = { 26 .start = 0xa413fec0, 27 .end = 0xa413fec0 + 0x28 - 1, 28 .flags = IORESOURCE_IO, 29 }, 30 [1] = { 31 /* Shared Period/Carry/Alarm IRQ */ 32 .start = 20, 33 .flags = IORESOURCE_IRQ, 34 }, 35 }; 36 37 static struct sh_rtc_platform_info rtc_info = { 38 .capabilities = RTC_CAP_4_DIGIT_YEAR, 39 }; 40 41 static struct platform_device rtc_device = { 42 .name = "sh-rtc", 43 .id = -1, 44 .num_resources = ARRAY_SIZE(rtc_resources), 45 .resource = rtc_resources, 46 .dev = { 47 .platform_data = &rtc_info, 48 }, 49 }; 50 51 static struct plat_sci_port scif0_platform_data = { 52 .mapbase = 0xa4430000, 53 .flags = UPF_BOOT_AUTOCONF, 54 .type = PORT_SCIF, 55 .irqs = { 80, 80, 80, 80 }, 56 }; 57 58 static struct platform_device scif0_device = { 59 .name = "sh-sci", 60 .id = 0, 61 .dev = { 62 .platform_data = &scif0_platform_data, 63 }, 64 }; 65 66 static struct plat_sci_port scif1_platform_data = { 67 .mapbase = 0xa4438000, 68 .flags = UPF_BOOT_AUTOCONF, 69 .type = PORT_SCIF, 70 .irqs = { 81, 81, 81, 81 }, 71 }; 72 73 static struct platform_device scif1_device = { 74 .name = "sh-sci", 75 .id = 1, 76 .dev = { 77 .platform_data = &scif1_platform_data, 78 }, 79 }; 80 81 static struct resource usb_ohci_resources[] = { 82 [0] = { 83 .start = 0xA4428000, 84 .end = 0xA44280FF, 85 .flags = IORESOURCE_MEM, 86 }, 87 [1] = { 88 .start = 67, 89 .end = 67, 90 .flags = IORESOURCE_IRQ, 91 }, 92 }; 93 94 static u64 usb_ohci_dma_mask = 0xffffffffUL; 95 static struct platform_device usb_ohci_device = { 96 .name = "sh_ohci", 97 .id = -1, 98 .dev = { 99 .dma_mask = &usb_ohci_dma_mask, 100 .coherent_dma_mask = 0xffffffff, 101 }, 102 .num_resources = ARRAY_SIZE(usb_ohci_resources), 103 .resource = usb_ohci_resources, 104 }; 105 106 static struct resource usbf_resources[] = { 107 [0] = { 108 .name = "sh_udc", 109 .start = 0xA4420000, 110 .end = 0xA44200FF, 111 .flags = IORESOURCE_MEM, 112 }, 113 [1] = { 114 .name = "sh_udc", 115 .start = 65, 116 .end = 65, 117 .flags = IORESOURCE_IRQ, 118 }, 119 }; 120 121 static struct platform_device usbf_device = { 122 .name = "sh_udc", 123 .id = -1, 124 .dev = { 125 .dma_mask = NULL, 126 .coherent_dma_mask = 0xffffffff, 127 }, 128 .num_resources = ARRAY_SIZE(usbf_resources), 129 .resource = usbf_resources, 130 }; 131 132 static struct sh_timer_config cmt0_platform_data = { 133 .name = "CMT0", 134 .channel_offset = 0x10, 135 .timer_bit = 0, 136 .clk = "peripheral_clk", 137 .clockevent_rating = 125, 138 .clocksource_rating = 125, 139 }; 140 141 static struct resource cmt0_resources[] = { 142 [0] = { 143 .name = "CMT0", 144 .start = 0x044a0010, 145 .end = 0x044a001b, 146 .flags = IORESOURCE_MEM, 147 }, 148 [1] = { 149 .start = 104, 150 .flags = IORESOURCE_IRQ, 151 }, 152 }; 153 154 static struct platform_device cmt0_device = { 155 .name = "sh_cmt", 156 .id = 0, 157 .dev = { 158 .platform_data = &cmt0_platform_data, 159 }, 160 .resource = cmt0_resources, 161 .num_resources = ARRAY_SIZE(cmt0_resources), 162 }; 163 164 static struct sh_timer_config cmt1_platform_data = { 165 .name = "CMT1", 166 .channel_offset = 0x20, 167 .timer_bit = 1, 168 .clk = "peripheral_clk", 169 }; 170 171 static struct resource cmt1_resources[] = { 172 [0] = { 173 .name = "CMT1", 174 .start = 0x044a0020, 175 .end = 0x044a002b, 176 .flags = IORESOURCE_MEM, 177 }, 178 [1] = { 179 .start = 104, 180 .flags = IORESOURCE_IRQ, 181 }, 182 }; 183 184 static struct platform_device cmt1_device = { 185 .name = "sh_cmt", 186 .id = 1, 187 .dev = { 188 .platform_data = &cmt1_platform_data, 189 }, 190 .resource = cmt1_resources, 191 .num_resources = ARRAY_SIZE(cmt1_resources), 192 }; 193 194 static struct sh_timer_config cmt2_platform_data = { 195 .name = "CMT2", 196 .channel_offset = 0x30, 197 .timer_bit = 2, 198 .clk = "peripheral_clk", 199 }; 200 201 static struct resource cmt2_resources[] = { 202 [0] = { 203 .name = "CMT2", 204 .start = 0x044a0030, 205 .end = 0x044a003b, 206 .flags = IORESOURCE_MEM, 207 }, 208 [1] = { 209 .start = 104, 210 .flags = IORESOURCE_IRQ, 211 }, 212 }; 213 214 static struct platform_device cmt2_device = { 215 .name = "sh_cmt", 216 .id = 2, 217 .dev = { 218 .platform_data = &cmt2_platform_data, 219 }, 220 .resource = cmt2_resources, 221 .num_resources = ARRAY_SIZE(cmt2_resources), 222 }; 223 224 static struct sh_timer_config cmt3_platform_data = { 225 .name = "CMT3", 226 .channel_offset = 0x40, 227 .timer_bit = 3, 228 .clk = "peripheral_clk", 229 }; 230 231 static struct resource cmt3_resources[] = { 232 [0] = { 233 .name = "CMT3", 234 .start = 0x044a0040, 235 .end = 0x044a004b, 236 .flags = IORESOURCE_MEM, 237 }, 238 [1] = { 239 .start = 104, 240 .flags = IORESOURCE_IRQ, 241 }, 242 }; 243 244 static struct platform_device cmt3_device = { 245 .name = "sh_cmt", 246 .id = 3, 247 .dev = { 248 .platform_data = &cmt3_platform_data, 249 }, 250 .resource = cmt3_resources, 251 .num_resources = ARRAY_SIZE(cmt3_resources), 252 }; 253 254 static struct sh_timer_config cmt4_platform_data = { 255 .name = "CMT4", 256 .channel_offset = 0x50, 257 .timer_bit = 4, 258 .clk = "peripheral_clk", 259 }; 260 261 static struct resource cmt4_resources[] = { 262 [0] = { 263 .name = "CMT4", 264 .start = 0x044a0050, 265 .end = 0x044a005b, 266 .flags = IORESOURCE_MEM, 267 }, 268 [1] = { 269 .start = 104, 270 .flags = IORESOURCE_IRQ, 271 }, 272 }; 273 274 static struct platform_device cmt4_device = { 275 .name = "sh_cmt", 276 .id = 4, 277 .dev = { 278 .platform_data = &cmt4_platform_data, 279 }, 280 .resource = cmt4_resources, 281 .num_resources = ARRAY_SIZE(cmt4_resources), 282 }; 283 284 static struct sh_timer_config tmu0_platform_data = { 285 .name = "TMU0", 286 .channel_offset = 0x02, 287 .timer_bit = 0, 288 .clk = "peripheral_clk", 289 .clockevent_rating = 200, 290 }; 291 292 static struct resource tmu0_resources[] = { 293 [0] = { 294 .name = "TMU0", 295 .start = 0xa412fe94, 296 .end = 0xa412fe9f, 297 .flags = IORESOURCE_MEM, 298 }, 299 [1] = { 300 .start = 16, 301 .flags = IORESOURCE_IRQ, 302 }, 303 }; 304 305 static struct platform_device tmu0_device = { 306 .name = "sh_tmu", 307 .id = 0, 308 .dev = { 309 .platform_data = &tmu0_platform_data, 310 }, 311 .resource = tmu0_resources, 312 .num_resources = ARRAY_SIZE(tmu0_resources), 313 }; 314 315 static struct sh_timer_config tmu1_platform_data = { 316 .name = "TMU1", 317 .channel_offset = 0xe, 318 .timer_bit = 1, 319 .clk = "peripheral_clk", 320 .clocksource_rating = 200, 321 }; 322 323 static struct resource tmu1_resources[] = { 324 [0] = { 325 .name = "TMU1", 326 .start = 0xa412fea0, 327 .end = 0xa412feab, 328 .flags = IORESOURCE_MEM, 329 }, 330 [1] = { 331 .start = 17, 332 .flags = IORESOURCE_IRQ, 333 }, 334 }; 335 336 static struct platform_device tmu1_device = { 337 .name = "sh_tmu", 338 .id = 1, 339 .dev = { 340 .platform_data = &tmu1_platform_data, 341 }, 342 .resource = tmu1_resources, 343 .num_resources = ARRAY_SIZE(tmu1_resources), 344 }; 345 346 static struct sh_timer_config tmu2_platform_data = { 347 .name = "TMU2", 348 .channel_offset = 0x1a, 349 .timer_bit = 2, 350 .clk = "peripheral_clk", 351 }; 352 353 static struct resource tmu2_resources[] = { 354 [0] = { 355 .name = "TMU2", 356 .start = 0xa412feac, 357 .end = 0xa412feb5, 358 .flags = IORESOURCE_MEM, 359 }, 360 [1] = { 361 .start = 18, 362 .flags = IORESOURCE_IRQ, 363 }, 364 }; 365 366 static struct platform_device tmu2_device = { 367 .name = "sh_tmu", 368 .id = 2, 369 .dev = { 370 .platform_data = &tmu2_platform_data, 371 }, 372 .resource = tmu2_resources, 373 .num_resources = ARRAY_SIZE(tmu2_resources), 374 }; 375 376 static struct platform_device *sh7720_devices[] __initdata = { 377 &scif0_device, 378 &scif1_device, 379 &cmt0_device, 380 &cmt1_device, 381 &cmt2_device, 382 &cmt3_device, 383 &cmt4_device, 384 &tmu0_device, 385 &tmu1_device, 386 &tmu2_device, 387 &rtc_device, 388 &usb_ohci_device, 389 &usbf_device, 390 }; 391 392 static int __init sh7720_devices_setup(void) 393 { 394 return platform_add_devices(sh7720_devices, 395 ARRAY_SIZE(sh7720_devices)); 396 } 397 arch_initcall(sh7720_devices_setup); 398 399 static struct platform_device *sh7720_early_devices[] __initdata = { 400 &scif0_device, 401 &scif1_device, 402 &cmt0_device, 403 &cmt1_device, 404 &cmt2_device, 405 &cmt3_device, 406 &cmt4_device, 407 &tmu0_device, 408 &tmu1_device, 409 &tmu2_device, 410 }; 411 412 void __init plat_early_device_setup(void) 413 { 414 early_platform_add_devices(sh7720_early_devices, 415 ARRAY_SIZE(sh7720_early_devices)); 416 } 417 418 enum { 419 UNUSED = 0, 420 421 /* interrupt sources */ 422 TMU0, TMU1, TMU2, RTC, 423 WDT, REF_RCMI, SIM, 424 IRQ0, IRQ1, IRQ2, IRQ3, 425 USBF_SPD, TMU_SUNI, IRQ5, IRQ4, 426 DMAC1, LCDC, SSL, 427 ADC, DMAC2, USBFI, CMT, 428 SCIF0, SCIF1, 429 PINT07, PINT815, TPU, IIC, 430 SIOF0, SIOF1, MMC, PCC, 431 USBHI, AFEIF, 432 H_UDI, 433 }; 434 435 static struct intc_vect vectors[] __initdata = { 436 /* IRQ0->5 are handled in setup-sh3.c */ 437 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), 438 INTC_VECT(TMU2, 0x440), INTC_VECT(RTC, 0x480), 439 INTC_VECT(RTC, 0x4a0), INTC_VECT(RTC, 0x4c0), 440 INTC_VECT(SIM, 0x4e0), INTC_VECT(SIM, 0x500), 441 INTC_VECT(SIM, 0x520), INTC_VECT(SIM, 0x540), 442 INTC_VECT(WDT, 0x560), INTC_VECT(REF_RCMI, 0x580), 443 /* H_UDI cannot be masked */ INTC_VECT(TMU_SUNI, 0x6c0), 444 INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1, 0x800), 445 INTC_VECT(DMAC1, 0x820), INTC_VECT(DMAC1, 0x840), 446 INTC_VECT(DMAC1, 0x860), INTC_VECT(LCDC, 0x900), 447 #if defined(CONFIG_CPU_SUBTYPE_SH7720) 448 INTC_VECT(SSL, 0x980), 449 #endif 450 INTC_VECT(USBFI, 0xa20), INTC_VECT(USBFI, 0xa40), 451 INTC_VECT(USBHI, 0xa60), 452 INTC_VECT(DMAC2, 0xb80), INTC_VECT(DMAC2, 0xba0), 453 INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00), 454 INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80), 455 INTC_VECT(PINT815, 0xca0), INTC_VECT(SIOF0, 0xd00), 456 INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU, 0xd80), 457 INTC_VECT(TPU, 0xda0), INTC_VECT(TPU, 0xdc0), 458 INTC_VECT(TPU, 0xde0), INTC_VECT(IIC, 0xe00), 459 INTC_VECT(MMC, 0xe80), INTC_VECT(MMC, 0xea0), 460 INTC_VECT(MMC, 0xec0), INTC_VECT(MMC, 0xee0), 461 INTC_VECT(CMT, 0xf00), INTC_VECT(PCC, 0xf60), 462 INTC_VECT(AFEIF, 0xfe0), 463 }; 464 465 static struct intc_prio_reg prio_registers[] __initdata = { 466 { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 467 { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } }, 468 { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, 469 { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } }, 470 { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, 471 { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } }, 472 { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } }, 473 { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } }, 474 { 0xA4080006UL, 0, 16, 4, /* IPRI */ { SIOF0, SIOF1, MMC, PCC } }, 475 { 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } }, 476 }; 477 478 static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, NULL, 479 NULL, prio_registers, NULL); 480 481 void __init plat_irq_setup(void) 482 { 483 register_intc_controller(&intc_desc); 484 plat_irq_setup_sh3(); 485 } 486