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