1 /* 2 * SH4-202 Setup 3 * 4 * Copyright (C) 2006 Paul Mundt 5 * Copyright (C) 2009 Magnus Damm 6 * 7 * This file is subject to the terms and conditions of the GNU General Public 8 * License. See the file "COPYING" in the main directory of this archive 9 * for more details. 10 */ 11 #include <linux/platform_device.h> 12 #include <linux/init.h> 13 #include <linux/serial.h> 14 #include <linux/serial_sci.h> 15 #include <linux/sh_timer.h> 16 #include <linux/sh_intc.h> 17 #include <linux/io.h> 18 19 static struct plat_sci_port scif0_platform_data = { 20 .flags = UPF_BOOT_AUTOCONF, 21 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 22 .type = PORT_SCIF, 23 }; 24 25 static struct resource scif0_resources[] = { 26 DEFINE_RES_MEM(0xffe80000, 0x100), 27 DEFINE_RES_IRQ(evt2irq(0x700)), 28 DEFINE_RES_IRQ(evt2irq(0x720)), 29 DEFINE_RES_IRQ(evt2irq(0x760)), 30 DEFINE_RES_IRQ(evt2irq(0x740)), 31 }; 32 33 static struct platform_device scif0_device = { 34 .name = "sh-sci", 35 .id = 0, 36 .resource = scif0_resources, 37 .num_resources = ARRAY_SIZE(scif0_resources), 38 .dev = { 39 .platform_data = &scif0_platform_data, 40 }, 41 }; 42 43 static struct sh_timer_config tmu0_platform_data = { 44 .channel_offset = 0x04, 45 .timer_bit = 0, 46 .clockevent_rating = 200, 47 }; 48 49 static struct resource tmu0_resources[] = { 50 [0] = { 51 .start = 0xffd80008, 52 .end = 0xffd80013, 53 .flags = IORESOURCE_MEM, 54 }, 55 [1] = { 56 .start = evt2irq(0x400), 57 .flags = IORESOURCE_IRQ, 58 }, 59 }; 60 61 static struct platform_device tmu0_device = { 62 .name = "sh_tmu", 63 .id = 0, 64 .dev = { 65 .platform_data = &tmu0_platform_data, 66 }, 67 .resource = tmu0_resources, 68 .num_resources = ARRAY_SIZE(tmu0_resources), 69 }; 70 71 static struct sh_timer_config tmu1_platform_data = { 72 .channel_offset = 0x10, 73 .timer_bit = 1, 74 .clocksource_rating = 200, 75 }; 76 77 static struct resource tmu1_resources[] = { 78 [0] = { 79 .start = 0xffd80014, 80 .end = 0xffd8001f, 81 .flags = IORESOURCE_MEM, 82 }, 83 [1] = { 84 .start = evt2irq(0x420), 85 .flags = IORESOURCE_IRQ, 86 }, 87 }; 88 89 static struct platform_device tmu1_device = { 90 .name = "sh_tmu", 91 .id = 1, 92 .dev = { 93 .platform_data = &tmu1_platform_data, 94 }, 95 .resource = tmu1_resources, 96 .num_resources = ARRAY_SIZE(tmu1_resources), 97 }; 98 99 static struct sh_timer_config tmu2_platform_data = { 100 .channel_offset = 0x1c, 101 .timer_bit = 2, 102 }; 103 104 static struct resource tmu2_resources[] = { 105 [0] = { 106 .start = 0xffd80020, 107 .end = 0xffd8002f, 108 .flags = IORESOURCE_MEM, 109 }, 110 [1] = { 111 .start = evt2irq(0x440), 112 .flags = IORESOURCE_IRQ, 113 }, 114 }; 115 116 static struct platform_device tmu2_device = { 117 .name = "sh_tmu", 118 .id = 2, 119 .dev = { 120 .platform_data = &tmu2_platform_data, 121 }, 122 .resource = tmu2_resources, 123 .num_resources = ARRAY_SIZE(tmu2_resources), 124 }; 125 126 static struct platform_device *sh4202_devices[] __initdata = { 127 &scif0_device, 128 &tmu0_device, 129 &tmu1_device, 130 &tmu2_device, 131 }; 132 133 static int __init sh4202_devices_setup(void) 134 { 135 return platform_add_devices(sh4202_devices, 136 ARRAY_SIZE(sh4202_devices)); 137 } 138 arch_initcall(sh4202_devices_setup); 139 140 static struct platform_device *sh4202_early_devices[] __initdata = { 141 &scif0_device, 142 &tmu0_device, 143 &tmu1_device, 144 &tmu2_device, 145 }; 146 147 void __init plat_early_device_setup(void) 148 { 149 early_platform_add_devices(sh4202_early_devices, 150 ARRAY_SIZE(sh4202_early_devices)); 151 } 152 153 enum { 154 UNUSED = 0, 155 156 /* interrupt sources */ 157 IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */ 158 HUDI, TMU0, TMU1, TMU2, RTC, SCIF, WDT, 159 }; 160 161 static struct intc_vect vectors[] __initdata = { 162 INTC_VECT(HUDI, 0x600), 163 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), 164 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460), 165 INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0), 166 INTC_VECT(RTC, 0x4c0), 167 INTC_VECT(SCIF, 0x700), INTC_VECT(SCIF, 0x720), 168 INTC_VECT(SCIF, 0x740), INTC_VECT(SCIF, 0x760), 169 INTC_VECT(WDT, 0x560), 170 }; 171 172 static struct intc_prio_reg prio_registers[] __initdata = { 173 { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 174 { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, 0, 0, 0 } }, 175 { 0xffd0000c, 0, 16, 4, /* IPRC */ { 0, 0, SCIF, HUDI } }, 176 { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, 177 }; 178 179 static DECLARE_INTC_DESC(intc_desc, "sh4-202", vectors, NULL, 180 NULL, prio_registers, NULL); 181 182 static struct intc_vect vectors_irlm[] __initdata = { 183 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), 184 INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), 185 }; 186 187 static DECLARE_INTC_DESC(intc_desc_irlm, "sh4-202_irlm", vectors_irlm, NULL, 188 NULL, prio_registers, NULL); 189 190 void __init plat_irq_setup(void) 191 { 192 register_intc_controller(&intc_desc); 193 } 194 195 #define INTC_ICR 0xffd00000UL 196 #define INTC_ICR_IRLM (1<<7) 197 198 void __init plat_irq_setup_pins(int mode) 199 { 200 switch (mode) { 201 case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ 202 __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 203 register_intc_controller(&intc_desc_irlm); 204 break; 205 default: 206 BUG(); 207 } 208 } 209