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