1/* 2 * SH3 Setup code for SH7706, SH7707, SH7708, SH7709 3 * 4 * Copyright (C) 2007 Magnus Damm 5 * Copyright (C) 2009 Paul Mundt 6 * 7 * Based on setup-sh7709.c 8 * 9 * Copyright (C) 2006 Paul Mundt 10 * 11 * This file is subject to the terms and conditions of the GNU General Public 12 * License. See the file "COPYING" in the main directory of this archive 13 * for more details. 14 */ 15#include <linux/init.h> 16#include <linux/io.h> 17#include <linux/irq.h> 18#include <linux/platform_device.h> 19#include <linux/serial.h> 20#include <linux/serial_sci.h> 21#include <linux/sh_timer.h> 22 23enum { 24 UNUSED = 0, 25 26 /* interrupt sources */ 27 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, 28 PINT07, PINT815, 29 DMAC, SCIF0, SCIF2, SCI, ADC_ADI, 30 LCDC, PCC0, PCC1, 31 TMU0, TMU1, TMU2, 32 RTC, WDT, REF, 33}; 34 35static struct intc_vect vectors[] __initdata = { 36 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), 37 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460), 38 INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0), 39 INTC_VECT(RTC, 0x4c0), 40 INTC_VECT(SCI, 0x4e0), INTC_VECT(SCI, 0x500), 41 INTC_VECT(SCI, 0x520), INTC_VECT(SCI, 0x540), 42 INTC_VECT(WDT, 0x560), 43 INTC_VECT(REF, 0x580), 44 INTC_VECT(REF, 0x5a0), 45#if defined(CONFIG_CPU_SUBTYPE_SH7706) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 46 defined(CONFIG_CPU_SUBTYPE_SH7709) 47 /* IRQ0->5 are handled in setup-sh3.c */ 48 INTC_VECT(DMAC, 0x800), INTC_VECT(DMAC, 0x820), 49 INTC_VECT(DMAC, 0x840), INTC_VECT(DMAC, 0x860), 50 INTC_VECT(ADC_ADI, 0x980), 51 INTC_VECT(SCIF2, 0x900), INTC_VECT(SCIF2, 0x920), 52 INTC_VECT(SCIF2, 0x940), INTC_VECT(SCIF2, 0x960), 53#endif 54#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) 55 INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720), 56 INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0), 57 INTC_VECT(SCIF0, 0x8c0), INTC_VECT(SCIF0, 0x8e0), 58#endif 59#if defined(CONFIG_CPU_SUBTYPE_SH7707) 60 INTC_VECT(LCDC, 0x9a0), 61 INTC_VECT(PCC0, 0x9c0), INTC_VECT(PCC1, 0x9e0), 62#endif 63}; 64 65static struct intc_prio_reg prio_registers[] __initdata = { 66 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 67 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, 68#if defined(CONFIG_CPU_SUBTYPE_SH7706) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 69 defined(CONFIG_CPU_SUBTYPE_SH7709) 70 { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, 71 { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, 72 { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, 0, SCIF2, ADC_ADI } }, 73#endif 74#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) 75 { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, } }, 76 { 0xa400001a, 0, 16, 4, /* IPRE */ { 0, SCIF0 } }, 77#endif 78#if defined(CONFIG_CPU_SUBTYPE_SH7707) 79 { 0xa400001c, 0, 16, 4, /* IPRF */ { 0, LCDC, PCC0, PCC1, } }, 80#endif 81}; 82 83static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, NULL, 84 NULL, prio_registers, NULL); 85 86static struct resource rtc_resources[] = { 87 [0] = { 88 .start = 0xfffffec0, 89 .end = 0xfffffec0 + 0x1e, 90 .flags = IORESOURCE_IO, 91 }, 92 [1] = { 93 .start = 20, 94 .flags = IORESOURCE_IRQ, 95 }, 96}; 97 98static struct platform_device rtc_device = { 99 .name = "sh-rtc", 100 .id = -1, 101 .num_resources = ARRAY_SIZE(rtc_resources), 102 .resource = rtc_resources, 103}; 104 105static struct plat_sci_port scif0_platform_data = { 106 .mapbase = 0xfffffe80, 107 .flags = UPF_BOOT_AUTOCONF, 108 .type = PORT_SCI, 109 .irqs = { 23, 23, 23, 0 }, 110}; 111 112static struct platform_device scif0_device = { 113 .name = "sh-sci", 114 .id = 0, 115 .dev = { 116 .platform_data = &scif0_platform_data, 117 }, 118}; 119#if defined(CONFIG_CPU_SUBTYPE_SH7706) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 120 defined(CONFIG_CPU_SUBTYPE_SH7709) 121static struct plat_sci_port scif1_platform_data = { 122 .mapbase = 0xa4000150, 123 .flags = UPF_BOOT_AUTOCONF, 124 .type = PORT_SCIF, 125 .irqs = { 56, 56, 56, 56 }, 126}; 127 128static struct platform_device scif1_device = { 129 .name = "sh-sci", 130 .id = 1, 131 .dev = { 132 .platform_data = &scif1_platform_data, 133 }, 134}; 135#endif 136#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) 137static struct plat_sci_port scif2_platform_data = { 138 .mapbase = 0xa4000140, 139 .flags = UPF_BOOT_AUTOCONF, 140 .type = PORT_IRDA, 141 .irqs = { 52, 52, 52, 52 }, 142}; 143 144static struct platform_device scif2_device = { 145 .name = "sh-sci", 146 .id = 2, 147 .dev = { 148 .platform_data = &scif2_platform_data, 149 }, 150}; 151#endif 152 153static struct sh_timer_config tmu0_platform_data = { 154 .channel_offset = 0x02, 155 .timer_bit = 0, 156 .clockevent_rating = 200, 157}; 158 159static struct resource tmu0_resources[] = { 160 [0] = { 161 .start = 0xfffffe94, 162 .end = 0xfffffe9f, 163 .flags = IORESOURCE_MEM, 164 }, 165 [1] = { 166 .start = 16, 167 .flags = IORESOURCE_IRQ, 168 }, 169}; 170 171static struct platform_device tmu0_device = { 172 .name = "sh_tmu", 173 .id = 0, 174 .dev = { 175 .platform_data = &tmu0_platform_data, 176 }, 177 .resource = tmu0_resources, 178 .num_resources = ARRAY_SIZE(tmu0_resources), 179}; 180 181static struct sh_timer_config tmu1_platform_data = { 182 .channel_offset = 0xe, 183 .timer_bit = 1, 184 .clocksource_rating = 200, 185}; 186 187static struct resource tmu1_resources[] = { 188 [0] = { 189 .start = 0xfffffea0, 190 .end = 0xfffffeab, 191 .flags = IORESOURCE_MEM, 192 }, 193 [1] = { 194 .start = 17, 195 .flags = IORESOURCE_IRQ, 196 }, 197}; 198 199static struct platform_device tmu1_device = { 200 .name = "sh_tmu", 201 .id = 1, 202 .dev = { 203 .platform_data = &tmu1_platform_data, 204 }, 205 .resource = tmu1_resources, 206 .num_resources = ARRAY_SIZE(tmu1_resources), 207}; 208 209static struct sh_timer_config tmu2_platform_data = { 210 .channel_offset = 0x1a, 211 .timer_bit = 2, 212}; 213 214static struct resource tmu2_resources[] = { 215 [0] = { 216 .start = 0xfffffeac, 217 .end = 0xfffffebb, 218 .flags = IORESOURCE_MEM, 219 }, 220 [1] = { 221 .start = 18, 222 .flags = IORESOURCE_IRQ, 223 }, 224}; 225 226static struct platform_device tmu2_device = { 227 .name = "sh_tmu", 228 .id = 2, 229 .dev = { 230 .platform_data = &tmu2_platform_data, 231 }, 232 .resource = tmu2_resources, 233 .num_resources = ARRAY_SIZE(tmu2_resources), 234}; 235 236static struct platform_device *sh770x_devices[] __initdata = { 237 &scif0_device, 238#if defined(CONFIG_CPU_SUBTYPE_SH7706) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 239 defined(CONFIG_CPU_SUBTYPE_SH7709) 240 &scif1_device, 241#endif 242#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) 243 &scif2_device, 244#endif 245 &tmu0_device, 246 &tmu1_device, 247 &tmu2_device, 248 &rtc_device, 249}; 250 251static int __init sh770x_devices_setup(void) 252{ 253 return platform_add_devices(sh770x_devices, 254 ARRAY_SIZE(sh770x_devices)); 255} 256arch_initcall(sh770x_devices_setup); 257 258static struct platform_device *sh770x_early_devices[] __initdata = { 259 &scif0_device, 260#if defined(CONFIG_CPU_SUBTYPE_SH7706) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 261 defined(CONFIG_CPU_SUBTYPE_SH7709) 262 &scif1_device, 263#endif 264#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) 265 &scif2_device, 266#endif 267 &tmu0_device, 268 &tmu1_device, 269 &tmu2_device, 270}; 271 272void __init plat_early_device_setup(void) 273{ 274 early_platform_add_devices(sh770x_early_devices, 275 ARRAY_SIZE(sh770x_early_devices)); 276} 277 278void __init plat_irq_setup(void) 279{ 280 register_intc_controller(&intc_desc); 281#if defined(CONFIG_CPU_SUBTYPE_SH7706) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 282 defined(CONFIG_CPU_SUBTYPE_SH7709) 283 plat_irq_setup_sh3(); 284#endif 285} 286