1 /* 2 * SH-X3 Prototype Setup 3 * 4 * Copyright (C) 2007 - 2009 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/platform_device.h> 11 #include <linux/init.h> 12 #include <linux/serial.h> 13 #include <linux/serial_sci.h> 14 #include <linux/io.h> 15 #include <linux/sh_timer.h> 16 #include <asm/mmzone.h> 17 18 /* 19 * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2 20 * INTEVT values overlap with the FPU EXPEVT ones, requiring special 21 * demuxing in the exception dispatch path. 22 * 23 * As this overlap is something that never should have made it in to 24 * silicon in the first place, we just refuse to deal with the port at 25 * all rather than adding infrastructure to hack around it. 26 */ 27 static struct plat_sci_port scif0_platform_data = { 28 .mapbase = 0xffc30000, 29 .flags = UPF_BOOT_AUTOCONF, 30 .type = PORT_SCIF, 31 .irqs = { 40, 41, 43, 42 }, 32 }; 33 34 static struct platform_device scif0_device = { 35 .name = "sh-sci", 36 .id = 0, 37 .dev = { 38 .platform_data = &scif0_platform_data, 39 }, 40 }; 41 42 static struct plat_sci_port scif1_platform_data = { 43 .mapbase = 0xffc40000, 44 .flags = UPF_BOOT_AUTOCONF, 45 .type = PORT_SCIF, 46 .irqs = { 44, 45, 47, 46 }, 47 }; 48 49 static struct platform_device scif1_device = { 50 .name = "sh-sci", 51 .id = 1, 52 .dev = { 53 .platform_data = &scif1_platform_data, 54 }, 55 }; 56 57 static struct plat_sci_port scif2_platform_data = { 58 .mapbase = 0xffc60000, 59 .flags = UPF_BOOT_AUTOCONF, 60 .type = PORT_SCIF, 61 .irqs = { 52, 53, 55, 54 }, 62 }; 63 64 static struct platform_device scif2_device = { 65 .name = "sh-sci", 66 .id = 2, 67 .dev = { 68 .platform_data = &scif2_platform_data, 69 }, 70 }; 71 72 static struct sh_timer_config tmu0_platform_data = { 73 .channel_offset = 0x04, 74 .timer_bit = 0, 75 .clockevent_rating = 200, 76 }; 77 78 static struct resource tmu0_resources[] = { 79 [0] = { 80 .start = 0xffc10008, 81 .end = 0xffc10013, 82 .flags = IORESOURCE_MEM, 83 }, 84 [1] = { 85 .start = 16, 86 .flags = IORESOURCE_IRQ, 87 }, 88 }; 89 90 static struct platform_device tmu0_device = { 91 .name = "sh_tmu", 92 .id = 0, 93 .dev = { 94 .platform_data = &tmu0_platform_data, 95 }, 96 .resource = tmu0_resources, 97 .num_resources = ARRAY_SIZE(tmu0_resources), 98 }; 99 100 static struct sh_timer_config tmu1_platform_data = { 101 .channel_offset = 0x10, 102 .timer_bit = 1, 103 .clocksource_rating = 200, 104 }; 105 106 static struct resource tmu1_resources[] = { 107 [0] = { 108 .start = 0xffc10014, 109 .end = 0xffc1001f, 110 .flags = IORESOURCE_MEM, 111 }, 112 [1] = { 113 .start = 17, 114 .flags = IORESOURCE_IRQ, 115 }, 116 }; 117 118 static struct platform_device tmu1_device = { 119 .name = "sh_tmu", 120 .id = 1, 121 .dev = { 122 .platform_data = &tmu1_platform_data, 123 }, 124 .resource = tmu1_resources, 125 .num_resources = ARRAY_SIZE(tmu1_resources), 126 }; 127 128 static struct sh_timer_config tmu2_platform_data = { 129 .channel_offset = 0x1c, 130 .timer_bit = 2, 131 }; 132 133 static struct resource tmu2_resources[] = { 134 [0] = { 135 .start = 0xffc10020, 136 .end = 0xffc1002f, 137 .flags = IORESOURCE_MEM, 138 }, 139 [1] = { 140 .start = 18, 141 .flags = IORESOURCE_IRQ, 142 }, 143 }; 144 145 static struct platform_device tmu2_device = { 146 .name = "sh_tmu", 147 .id = 2, 148 .dev = { 149 .platform_data = &tmu2_platform_data, 150 }, 151 .resource = tmu2_resources, 152 .num_resources = ARRAY_SIZE(tmu2_resources), 153 }; 154 155 static struct sh_timer_config tmu3_platform_data = { 156 .channel_offset = 0x04, 157 .timer_bit = 0, 158 }; 159 160 static struct resource tmu3_resources[] = { 161 [0] = { 162 .start = 0xffc20008, 163 .end = 0xffc20013, 164 .flags = IORESOURCE_MEM, 165 }, 166 [1] = { 167 .start = 19, 168 .flags = IORESOURCE_IRQ, 169 }, 170 }; 171 172 static struct platform_device tmu3_device = { 173 .name = "sh_tmu", 174 .id = 3, 175 .dev = { 176 .platform_data = &tmu3_platform_data, 177 }, 178 .resource = tmu3_resources, 179 .num_resources = ARRAY_SIZE(tmu3_resources), 180 }; 181 182 static struct sh_timer_config tmu4_platform_data = { 183 .channel_offset = 0x10, 184 .timer_bit = 1, 185 }; 186 187 static struct resource tmu4_resources[] = { 188 [0] = { 189 .start = 0xffc20014, 190 .end = 0xffc2001f, 191 .flags = IORESOURCE_MEM, 192 }, 193 [1] = { 194 .start = 20, 195 .flags = IORESOURCE_IRQ, 196 }, 197 }; 198 199 static struct platform_device tmu4_device = { 200 .name = "sh_tmu", 201 .id = 4, 202 .dev = { 203 .platform_data = &tmu4_platform_data, 204 }, 205 .resource = tmu4_resources, 206 .num_resources = ARRAY_SIZE(tmu4_resources), 207 }; 208 209 static struct sh_timer_config tmu5_platform_data = { 210 .channel_offset = 0x1c, 211 .timer_bit = 2, 212 }; 213 214 static struct resource tmu5_resources[] = { 215 [0] = { 216 .start = 0xffc20020, 217 .end = 0xffc2002b, 218 .flags = IORESOURCE_MEM, 219 }, 220 [1] = { 221 .start = 21, 222 .flags = IORESOURCE_IRQ, 223 }, 224 }; 225 226 static struct platform_device tmu5_device = { 227 .name = "sh_tmu", 228 .id = 5, 229 .dev = { 230 .platform_data = &tmu5_platform_data, 231 }, 232 .resource = tmu5_resources, 233 .num_resources = ARRAY_SIZE(tmu5_resources), 234 }; 235 236 static struct platform_device *shx3_early_devices[] __initdata = { 237 &scif0_device, 238 &scif1_device, 239 &scif2_device, 240 &tmu0_device, 241 &tmu1_device, 242 &tmu2_device, 243 &tmu3_device, 244 &tmu4_device, 245 &tmu5_device, 246 }; 247 248 static int __init shx3_devices_setup(void) 249 { 250 return platform_add_devices(shx3_early_devices, 251 ARRAY_SIZE(shx3_early_devices)); 252 } 253 arch_initcall(shx3_devices_setup); 254 255 void __init plat_early_device_setup(void) 256 { 257 early_platform_add_devices(shx3_early_devices, 258 ARRAY_SIZE(shx3_early_devices)); 259 } 260 261 enum { 262 UNUSED = 0, 263 264 /* interrupt sources */ 265 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 266 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 267 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 268 IRL_HHLL, IRL_HHLH, IRL_HHHL, 269 IRQ0, IRQ1, IRQ2, IRQ3, 270 HUDII, 271 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5, 272 PCII0, PCII1, PCII2, PCII3, PCII4, 273 PCII5, PCII6, PCII7, PCII8, PCII9, 274 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, 275 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, 276 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, 277 SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI, 278 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, 279 DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE, 280 DU, 281 DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9, 282 DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE, 283 IIC, VIN0, VIN1, VCORE0, ATAPI, 284 DTU0, DTU1, DTU2, DTU3, 285 FE0, FE1, 286 GPIO0, GPIO1, GPIO2, GPIO3, 287 PAM, IRM, 288 INTICI0, INTICI1, INTICI2, INTICI3, 289 INTICI4, INTICI5, INTICI6, INTICI7, 290 291 /* interrupt groups */ 292 IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3, 293 DMAC0, DMAC1, 294 }; 295 296 static struct intc_vect vectors[] __initdata = { 297 INTC_VECT(HUDII, 0x3e0), 298 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), 299 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460), 300 INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0), 301 INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520), 302 INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560), 303 INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0), 304 INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0), 305 INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620), 306 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), 307 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), 308 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0), 309 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0), 310 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0), 311 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0), 312 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920), 313 INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960), 314 INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0), 315 INTC_VECT(DMAC0_DMAE, 0x9c0), 316 INTC_VECT(DU, 0x9e0), 317 INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20), 318 INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60), 319 INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0), 320 INTC_VECT(DMAC1_DMAE, 0xac0), 321 INTC_VECT(IIC, 0xae0), 322 INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20), 323 INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60), 324 INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20), 325 INTC_VECT(DTU0, 0xc40), 326 INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80), 327 INTC_VECT(DTU1, 0xca0), 328 INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0), 329 INTC_VECT(DTU2, 0xd00), 330 INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40), 331 INTC_VECT(DTU3, 0xd60), 332 INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20), 333 INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60), 334 INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0), 335 INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0), 336 INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20), 337 INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60), 338 INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0), 339 INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0), 340 }; 341 342 static struct intc_group groups[] __initdata = { 343 INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 344 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 345 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 346 IRL_HHLL, IRL_HHLH, IRL_HHHL), 347 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9), 348 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), 349 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), 350 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI), 351 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, 352 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), 353 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, 354 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11), 355 }; 356 357 static struct intc_mask_reg mask_registers[] __initdata = { 358 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */ 359 { IRQ0, IRQ1, IRQ2, IRQ3 } }, 360 { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */ 361 { IRL } }, 362 { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */ 363 { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC, 364 DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0, 365 0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */ 366 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } }, 367 { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */ 368 { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */ 369 PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2, 370 PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11, 371 DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7, 372 DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4, 373 DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } }, 374 { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */ 375 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 376 SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI, 377 SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI, 378 SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI, 379 SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } }, 380 }; 381 382 static struct intc_prio_reg prio_registers[] __initdata = { 383 { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, 384 385 { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4, 386 TMU3, TMU2, TMU1, TMU0 } }, 387 { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0, 388 SCIF3, SCIF2, 389 SCIF1, SCIF0 } }, 390 { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0, 391 PCII56789, PCII4, 392 PCII3, PCII2, 393 PCII1, PCII0 } }, 394 { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0, 395 VIN1, VIN0, IIC, DU} }, 396 { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3, 397 GPIO2, GPIO1, GPIO0, IRM } }, 398 { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */ 399 { INTICI7, INTICI6, INTICI5, INTICI4, 400 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) }, 401 }; 402 403 static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, 404 mask_registers, prio_registers, NULL); 405 406 /* Support for external interrupt pins in IRQ mode */ 407 static struct intc_vect vectors_irq[] __initdata = { 408 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), 409 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), 410 }; 411 412 static struct intc_sense_reg sense_registers[] __initdata = { 413 { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, 414 }; 415 416 static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups, 417 mask_registers, prio_registers, sense_registers); 418 419 /* External interrupt pins in IRL mode */ 420 static struct intc_vect vectors_irl[] __initdata = { 421 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), 422 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), 423 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), 424 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), 425 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), 426 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), 427 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), 428 INTC_VECT(IRL_HHHL, 0x3c0), 429 }; 430 431 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups, 432 mask_registers, prio_registers, NULL); 433 434 void __init plat_irq_setup_pins(int mode) 435 { 436 switch (mode) { 437 case IRQ_MODE_IRQ: 438 register_intc_controller(&intc_desc_irq); 439 break; 440 case IRQ_MODE_IRL3210: 441 register_intc_controller(&intc_desc_irl); 442 break; 443 default: 444 BUG(); 445 } 446 } 447 448 void __init plat_irq_setup(void) 449 { 450 register_intc_controller(&intc_desc); 451 } 452 453 void __init plat_mem_setup(void) 454 { 455 unsigned int nid = 1; 456 457 /* Register CPU#0 URAM space as Node 1 */ 458 setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */ 459 460 #if 0 461 /* XXX: Not yet.. */ 462 setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */ 463 setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */ 464 setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */ 465 #endif 466 467 setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */ 468 } 469