blob: fa15d81267ef643be3e9bc7a61665a69a8ae5748 [file] [log] [blame]
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -08001/*
2 * R8A7740 processor support
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -080020#include <linux/delay.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080021#include <linux/kernel.h>
22#include <linux/init.h>
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -080023#include <linux/io.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080024#include <linux/platform_device.h>
25#include <linux/serial_sci.h>
26#include <linux/sh_timer.h>
27#include <mach/r8a7740.h>
Rob Herring250a2722012-01-03 16:57:33 -060028#include <mach/irqs.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080029#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31
32/* SCIFA0 */
33static struct plat_sci_port scif0_platform_data = {
34 .mapbase = 0xe6c40000,
35 .flags = UPF_BOOT_AUTOCONF,
36 .scscr = SCSCR_RE | SCSCR_TE,
37 .scbrr_algo_id = SCBRR_ALGO_4,
38 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -080039 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c00)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080040};
41
42static struct platform_device scif0_device = {
43 .name = "sh-sci",
44 .id = 0,
45 .dev = {
46 .platform_data = &scif0_platform_data,
47 },
48};
49
50/* SCIFA1 */
51static struct plat_sci_port scif1_platform_data = {
52 .mapbase = 0xe6c50000,
53 .flags = UPF_BOOT_AUTOCONF,
54 .scscr = SCSCR_RE | SCSCR_TE,
55 .scbrr_algo_id = SCBRR_ALGO_4,
56 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -080057 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c20)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080058};
59
60static struct platform_device scif1_device = {
61 .name = "sh-sci",
62 .id = 1,
63 .dev = {
64 .platform_data = &scif1_platform_data,
65 },
66};
67
68/* SCIFA2 */
69static struct plat_sci_port scif2_platform_data = {
70 .mapbase = 0xe6c60000,
71 .flags = UPF_BOOT_AUTOCONF,
72 .scscr = SCSCR_RE | SCSCR_TE,
73 .scbrr_algo_id = SCBRR_ALGO_4,
74 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -080075 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c40)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080076};
77
78static struct platform_device scif2_device = {
79 .name = "sh-sci",
80 .id = 2,
81 .dev = {
82 .platform_data = &scif2_platform_data,
83 },
84};
85
86/* SCIFA3 */
87static struct plat_sci_port scif3_platform_data = {
88 .mapbase = 0xe6c70000,
89 .flags = UPF_BOOT_AUTOCONF,
90 .scscr = SCSCR_RE | SCSCR_TE,
91 .scbrr_algo_id = SCBRR_ALGO_4,
92 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -080093 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c60)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080094};
95
96static struct platform_device scif3_device = {
97 .name = "sh-sci",
98 .id = 3,
99 .dev = {
100 .platform_data = &scif3_platform_data,
101 },
102};
103
104/* SCIFA4 */
105static struct plat_sci_port scif4_platform_data = {
106 .mapbase = 0xe6c80000,
107 .flags = UPF_BOOT_AUTOCONF,
108 .scscr = SCSCR_RE | SCSCR_TE,
109 .scbrr_algo_id = SCBRR_ALGO_4,
110 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800111 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d20)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800112};
113
114static struct platform_device scif4_device = {
115 .name = "sh-sci",
116 .id = 4,
117 .dev = {
118 .platform_data = &scif4_platform_data,
119 },
120};
121
122/* SCIFA5 */
123static struct plat_sci_port scif5_platform_data = {
124 .mapbase = 0xe6cb0000,
125 .flags = UPF_BOOT_AUTOCONF,
126 .scscr = SCSCR_RE | SCSCR_TE,
127 .scbrr_algo_id = SCBRR_ALGO_4,
128 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800129 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d40)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800130};
131
132static struct platform_device scif5_device = {
133 .name = "sh-sci",
134 .id = 5,
135 .dev = {
136 .platform_data = &scif5_platform_data,
137 },
138};
139
140/* SCIFA6 */
141static struct plat_sci_port scif6_platform_data = {
142 .mapbase = 0xe6cc0000,
143 .flags = UPF_BOOT_AUTOCONF,
144 .scscr = SCSCR_RE | SCSCR_TE,
145 .scbrr_algo_id = SCBRR_ALGO_4,
146 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800147 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04c0)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800148};
149
150static struct platform_device scif6_device = {
151 .name = "sh-sci",
152 .id = 6,
153 .dev = {
154 .platform_data = &scif6_platform_data,
155 },
156};
157
158/* SCIFA7 */
159static struct plat_sci_port scif7_platform_data = {
160 .mapbase = 0xe6cd0000,
161 .flags = UPF_BOOT_AUTOCONF,
162 .scscr = SCSCR_RE | SCSCR_TE,
163 .scbrr_algo_id = SCBRR_ALGO_4,
164 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800165 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04e0)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800166};
167
168static struct platform_device scif7_device = {
169 .name = "sh-sci",
170 .id = 7,
171 .dev = {
172 .platform_data = &scif7_platform_data,
173 },
174};
175
176/* SCIFB */
177static struct plat_sci_port scifb_platform_data = {
178 .mapbase = 0xe6c30000,
179 .flags = UPF_BOOT_AUTOCONF,
180 .scscr = SCSCR_RE | SCSCR_TE,
181 .scbrr_algo_id = SCBRR_ALGO_4,
182 .type = PORT_SCIFB,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800183 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d60)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800184};
185
186static struct platform_device scifb_device = {
187 .name = "sh-sci",
188 .id = 8,
189 .dev = {
190 .platform_data = &scifb_platform_data,
191 },
192};
193
194/* CMT */
195static struct sh_timer_config cmt10_platform_data = {
196 .name = "CMT10",
197 .channel_offset = 0x10,
198 .timer_bit = 0,
199 .clockevent_rating = 125,
200 .clocksource_rating = 125,
201};
202
203static struct resource cmt10_resources[] = {
204 [0] = {
205 .name = "CMT10",
206 .start = 0xe6138010,
207 .end = 0xe613801b,
208 .flags = IORESOURCE_MEM,
209 },
210 [1] = {
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800211 .start = evt2irq(0x0b00),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800212 .flags = IORESOURCE_IRQ,
213 },
214};
215
216static struct platform_device cmt10_device = {
217 .name = "sh_cmt",
218 .id = 10,
219 .dev = {
220 .platform_data = &cmt10_platform_data,
221 },
222 .resource = cmt10_resources,
223 .num_resources = ARRAY_SIZE(cmt10_resources),
224};
225
226static struct platform_device *r8a7740_early_devices[] __initdata = {
227 &scif0_device,
228 &scif1_device,
229 &scif2_device,
230 &scif3_device,
231 &scif4_device,
232 &scif5_device,
233 &scif6_device,
234 &scif7_device,
235 &scifb_device,
236 &cmt10_device,
237};
238
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800239/* I2C */
240static struct resource i2c0_resources[] = {
241 [0] = {
242 .name = "IIC0",
243 .start = 0xfff20000,
244 .end = 0xfff20425 - 1,
245 .flags = IORESOURCE_MEM,
246 },
247 [1] = {
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800248 .start = intcs_evt2irq(0xe00),
249 .end = intcs_evt2irq(0xe60),
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800250 .flags = IORESOURCE_IRQ,
251 },
252};
253
254static struct resource i2c1_resources[] = {
255 [0] = {
256 .name = "IIC1",
257 .start = 0xe6c20000,
258 .end = 0xe6c20425 - 1,
259 .flags = IORESOURCE_MEM,
260 },
261 [1] = {
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800262 .start = evt2irq(0x780), /* IIC1_ALI1 */
263 .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800264 .flags = IORESOURCE_IRQ,
265 },
266};
267
268static struct platform_device i2c0_device = {
269 .name = "i2c-sh_mobile",
270 .id = 0,
271 .resource = i2c0_resources,
272 .num_resources = ARRAY_SIZE(i2c0_resources),
273};
274
275static struct platform_device i2c1_device = {
276 .name = "i2c-sh_mobile",
277 .id = 1,
278 .resource = i2c1_resources,
279 .num_resources = ARRAY_SIZE(i2c1_resources),
280};
281
282static struct platform_device *r8a7740_late_devices[] __initdata = {
283 &i2c0_device,
284 &i2c1_device,
285};
286
287#define ICCR 0x0004
288#define ICSTART 0x0070
289
290#define i2c_read(reg, offset) ioread8(reg + offset)
291#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)
292
293/*
294 * r8a7740 chip has lasting errata on I2C I/O pad reset.
295 * this is work-around for it.
296 */
297static void r8a7740_i2c_workaround(struct platform_device *pdev)
298{
299 struct resource *res;
300 void __iomem *reg;
301
302 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
303 if (unlikely(!res)) {
304 pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
305 return;
306 }
307
308 reg = ioremap(res->start, resource_size(res));
309 if (unlikely(!reg)) {
310 pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
311 return;
312 }
313
314 i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
315 i2c_read(reg, ICCR); /* dummy read */
316
317 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
318 i2c_read(reg, ICSTART); /* dummy read */
319
320 mdelay(100);
321
322 i2c_write(reg, ICCR, 0x01);
323 i2c_read(reg, ICCR);
324 i2c_write(reg, ICSTART, 0x00);
325 i2c_read(reg, ICSTART);
326
327 i2c_write(reg, ICCR, 0x10);
328 mdelay(100);
329 i2c_write(reg, ICCR, 0x00);
330 mdelay(100);
331 i2c_write(reg, ICCR, 0x10);
332 mdelay(100);
333
334 iounmap(reg);
335}
336
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800337void __init r8a7740_add_standard_devices(void)
338{
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800339 /* I2C work-around */
340 r8a7740_i2c_workaround(&i2c0_device);
341 r8a7740_i2c_workaround(&i2c1_device);
342
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800343 platform_add_devices(r8a7740_early_devices,
344 ARRAY_SIZE(r8a7740_early_devices));
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800345 platform_add_devices(r8a7740_late_devices,
346 ARRAY_SIZE(r8a7740_late_devices));
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800347}
348
349void __init r8a7740_add_early_devices(void)
350{
351 early_platform_add_devices(r8a7740_early_devices,
352 ARRAY_SIZE(r8a7740_early_devices));
353}