1 /* 2 * SH7780 Setup 3 * 4 * Copyright (C) 2006 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/io.h> 14 #include <linux/serial_sci.h> 15 16 static struct resource rtc_resources[] = { 17 [0] = { 18 .start = 0xffe80000, 19 .end = 0xffe80000 + 0x58 - 1, 20 .flags = IORESOURCE_IO, 21 }, 22 [1] = { 23 /* Shared Period/Carry/Alarm IRQ */ 24 .start = 20, 25 .flags = IORESOURCE_IRQ, 26 }, 27 }; 28 29 static struct platform_device rtc_device = { 30 .name = "sh-rtc", 31 .id = -1, 32 .num_resources = ARRAY_SIZE(rtc_resources), 33 .resource = rtc_resources, 34 }; 35 36 static struct plat_sci_port sci_platform_data[] = { 37 { 38 .mapbase = 0xffe00000, 39 .flags = UPF_BOOT_AUTOCONF, 40 .type = PORT_SCIF, 41 .irqs = { 40, 40, 40, 40 }, 42 }, { 43 .mapbase = 0xffe10000, 44 .flags = UPF_BOOT_AUTOCONF, 45 .type = PORT_SCIF, 46 .irqs = { 76, 76, 76, 76 }, 47 }, { 48 .flags = 0, 49 } 50 }; 51 52 static struct platform_device sci_device = { 53 .name = "sh-sci", 54 .id = -1, 55 .dev = { 56 .platform_data = sci_platform_data, 57 }, 58 }; 59 60 static struct platform_device *sh7780_devices[] __initdata = { 61 &rtc_device, 62 &sci_device, 63 }; 64 65 static int __init sh7780_devices_setup(void) 66 { 67 return platform_add_devices(sh7780_devices, 68 ARRAY_SIZE(sh7780_devices)); 69 } 70 __initcall(sh7780_devices_setup); 71 72 enum { 73 UNUSED = 0, 74 75 /* interrupt sources */ 76 77 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 78 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 79 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 80 IRL_HHLL, IRL_HHLH, IRL_HHHL, 81 82 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, 83 RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI, 84 HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC, 85 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5, 86 SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL, GPIO, 87 88 /* interrupt groups */ 89 90 TMU012, TMU345, 91 }; 92 93 static struct intc_vect vectors[] __initdata = { 94 INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0), 95 INTC_VECT(RTC, 0x4c0), 96 INTC_VECT(WDT, 0x560), 97 INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), 98 INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), 99 INTC_VECT(HUDI, 0x600), 100 INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660), 101 INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0), 102 INTC_VECT(DMAC0, 0x6c0), 103 INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720), 104 INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760), 105 INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0), 106 INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0), 107 INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980), 108 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), 109 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), 110 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0), 111 INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0), 112 INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20), 113 INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0), 114 INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0), 115 INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80), 116 INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20), 117 INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60), 118 INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0), 119 INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0), 120 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), 121 INTC_VECT(TMU5, 0xe40), 122 INTC_VECT(SSI, 0xe80), 123 INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20), 124 INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60), 125 INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0), 126 INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0), 127 }; 128 129 static struct intc_group groups[] __initdata = { 130 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), 131 INTC_GROUP(TMU345, TMU3, TMU4, TMU5), 132 }; 133 134 static struct intc_mask_reg mask_registers[] __initdata = { 135 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ 136 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, 137 SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, 138 PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0, 139 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, 140 }; 141 142 static struct intc_prio_reg prio_registers[] __initdata = { 143 { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, 144 TMU2, TMU2_TICPI } }, 145 { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, 146 { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, 147 { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, 148 { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC, 149 PCISERR, PCIINTA, } }, 150 { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, 151 PCIINTD, PCIC5 } }, 152 { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, 153 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, 154 }; 155 156 static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, 157 mask_registers, prio_registers, NULL); 158 159 /* Support for external interrupt pins in IRQ mode */ 160 161 static struct intc_vect irq_vectors[] __initdata = { 162 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), 163 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), 164 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), 165 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), 166 }; 167 168 static struct intc_mask_reg irq_mask_registers[] __initdata = { 169 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ 170 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 171 }; 172 173 static struct intc_prio_reg irq_prio_registers[] __initdata = { 174 { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, 175 IRQ4, IRQ5, IRQ6, IRQ7 } }, 176 }; 177 178 static struct intc_sense_reg irq_sense_registers[] __initdata = { 179 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, 180 IRQ4, IRQ5, IRQ6, IRQ7 } }, 181 }; 182 183 static struct intc_mask_reg irq_ack_registers[] __initdata = { 184 { 0xffd00024, 0, 32, /* INTREQ */ 185 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 186 }; 187 188 static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors, 189 NULL, irq_mask_registers, irq_prio_registers, 190 irq_sense_registers, irq_ack_registers); 191 192 /* External interrupt pins in IRL mode */ 193 194 static struct intc_vect irl_vectors[] __initdata = { 195 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), 196 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), 197 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), 198 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), 199 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), 200 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), 201 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), 202 INTC_VECT(IRL_HHHL, 0x3c0), 203 }; 204 205 static struct intc_mask_reg irl3210_mask_registers[] __initdata = { 206 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ 207 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 208 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 209 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 210 IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, 211 }; 212 213 static struct intc_mask_reg irl7654_mask_registers[] __initdata = { 214 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ 215 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 217 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 218 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 219 IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, 220 }; 221 222 static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, 223 NULL, irl7654_mask_registers, NULL, NULL); 224 225 static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, 226 NULL, irl3210_mask_registers, NULL, NULL); 227 228 #define INTC_ICR0 0xffd00000 229 #define INTC_INTMSK0 0xffd00044 230 #define INTC_INTMSK1 0xffd00048 231 #define INTC_INTMSK2 0xffd40080 232 #define INTC_INTMSKCLR1 0xffd00068 233 #define INTC_INTMSKCLR2 0xffd40084 234 235 void __init plat_irq_setup(void) 236 { 237 /* disable IRQ7-0 */ 238 ctrl_outl(0xff000000, INTC_INTMSK0); 239 240 /* disable IRL3-0 + IRL7-4 */ 241 ctrl_outl(0xc0000000, INTC_INTMSK1); 242 ctrl_outl(0xfffefffe, INTC_INTMSK2); 243 244 /* select IRL mode for IRL3-0 + IRL7-4 */ 245 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); 246 247 /* disable holding function, ie enable "SH-4 Mode" */ 248 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); 249 250 register_intc_controller(&intc_desc); 251 } 252 253 void __init plat_irq_setup_pins(int mode) 254 { 255 switch (mode) { 256 case IRQ_MODE_IRQ: 257 /* select IRQ mode for IRL3-0 + IRL7-4 */ 258 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); 259 register_intc_controller(&intc_irq_desc); 260 break; 261 case IRQ_MODE_IRL7654: 262 /* enable IRL7-4 but don't provide any masking */ 263 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 264 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 265 break; 266 case IRQ_MODE_IRL3210: 267 /* enable IRL0-3 but don't provide any masking */ 268 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 269 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 270 break; 271 case IRQ_MODE_IRL7654_MASK: 272 /* enable IRL7-4 and mask using cpu intc controller */ 273 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 274 register_intc_controller(&intc_irl7654_desc); 275 break; 276 case IRQ_MODE_IRL3210_MASK: 277 /* enable IRL0-3 and mask using cpu intc controller */ 278 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 279 register_intc_controller(&intc_irl3210_desc); 280 break; 281 default: 282 BUG(); 283 } 284 } 285