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