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