Merge branch 'renesas-soc-core' into renesas-r8a7740
[deliverable/linux.git] / arch / arm / mach-shmobile / setup-r8a7740.c
CommitLineData
6c01ba44
KM
1/*
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 */
6831f3a9 20#include <linux/delay.h>
3841e6f5 21#include <linux/dma-mapping.h>
6c01ba44
KM
22#include <linux/kernel.h>
23#include <linux/init.h>
6831f3a9 24#include <linux/io.h>
6c01ba44
KM
25#include <linux/platform_device.h>
26#include <linux/serial_sci.h>
27#include <linux/sh_timer.h>
28#include <mach/r8a7740.h>
d3ab7221 29#include <mach/common.h>
250a2723 30#include <mach/irqs.h>
6c01ba44 31#include <asm/mach-types.h>
d3ab7221 32#include <asm/mach/map.h>
6c01ba44 33#include <asm/mach/arch.h>
23e5bc03 34#include <asm/mach/time.h>
6c01ba44 35
d3ab7221
MD
36static struct map_desc r8a7740_io_desc[] __initdata = {
37 /*
38 * for CPGA/INTC/PFC
39 * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
40 */
41 {
42 .virtual = 0xe6000000,
43 .pfn = __phys_to_pfn(0xe6000000),
44 .length = 160 << 20,
45 .type = MT_DEVICE_NONSHARED
46 },
47#ifdef CONFIG_CACHE_L2X0
48 /*
49 * for l2x0_init()
50 * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
51 */
52 {
53 .virtual = 0xf0002000,
54 .pfn = __phys_to_pfn(0xf0100000),
55 .length = PAGE_SIZE,
56 .type = MT_DEVICE_NONSHARED
57 },
58#endif
59};
60
61void __init r8a7740_map_io(void)
62{
63 iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
3841e6f5
KM
64
65 /*
66 * DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
67 * enough to allocate the frame buffer memory.
68 */
69 init_consistent_dma_size(12 << 20);
d3ab7221
MD
70}
71
6c01ba44
KM
72/* SCIFA0 */
73static struct plat_sci_port scif0_platform_data = {
74 .mapbase = 0xe6c40000,
75 .flags = UPF_BOOT_AUTOCONF,
76 .scscr = SCSCR_RE | SCSCR_TE,
77 .scbrr_algo_id = SCBRR_ALGO_4,
78 .type = PORT_SCIFA,
215d6cc9 79 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c00)),
6c01ba44
KM
80};
81
82static struct platform_device scif0_device = {
83 .name = "sh-sci",
84 .id = 0,
85 .dev = {
86 .platform_data = &scif0_platform_data,
87 },
88};
89
90/* SCIFA1 */
91static struct plat_sci_port scif1_platform_data = {
92 .mapbase = 0xe6c50000,
93 .flags = UPF_BOOT_AUTOCONF,
94 .scscr = SCSCR_RE | SCSCR_TE,
95 .scbrr_algo_id = SCBRR_ALGO_4,
96 .type = PORT_SCIFA,
215d6cc9 97 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c20)),
6c01ba44
KM
98};
99
100static struct platform_device scif1_device = {
101 .name = "sh-sci",
102 .id = 1,
103 .dev = {
104 .platform_data = &scif1_platform_data,
105 },
106};
107
108/* SCIFA2 */
109static struct plat_sci_port scif2_platform_data = {
110 .mapbase = 0xe6c60000,
111 .flags = UPF_BOOT_AUTOCONF,
112 .scscr = SCSCR_RE | SCSCR_TE,
113 .scbrr_algo_id = SCBRR_ALGO_4,
114 .type = PORT_SCIFA,
215d6cc9 115 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c40)),
6c01ba44
KM
116};
117
118static struct platform_device scif2_device = {
119 .name = "sh-sci",
120 .id = 2,
121 .dev = {
122 .platform_data = &scif2_platform_data,
123 },
124};
125
126/* SCIFA3 */
127static struct plat_sci_port scif3_platform_data = {
128 .mapbase = 0xe6c70000,
129 .flags = UPF_BOOT_AUTOCONF,
130 .scscr = SCSCR_RE | SCSCR_TE,
131 .scbrr_algo_id = SCBRR_ALGO_4,
132 .type = PORT_SCIFA,
215d6cc9 133 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c60)),
6c01ba44
KM
134};
135
136static struct platform_device scif3_device = {
137 .name = "sh-sci",
138 .id = 3,
139 .dev = {
140 .platform_data = &scif3_platform_data,
141 },
142};
143
144/* SCIFA4 */
145static struct plat_sci_port scif4_platform_data = {
146 .mapbase = 0xe6c80000,
147 .flags = UPF_BOOT_AUTOCONF,
148 .scscr = SCSCR_RE | SCSCR_TE,
149 .scbrr_algo_id = SCBRR_ALGO_4,
150 .type = PORT_SCIFA,
215d6cc9 151 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d20)),
6c01ba44
KM
152};
153
154static struct platform_device scif4_device = {
155 .name = "sh-sci",
156 .id = 4,
157 .dev = {
158 .platform_data = &scif4_platform_data,
159 },
160};
161
162/* SCIFA5 */
163static struct plat_sci_port scif5_platform_data = {
164 .mapbase = 0xe6cb0000,
165 .flags = UPF_BOOT_AUTOCONF,
166 .scscr = SCSCR_RE | SCSCR_TE,
167 .scbrr_algo_id = SCBRR_ALGO_4,
168 .type = PORT_SCIFA,
215d6cc9 169 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d40)),
6c01ba44
KM
170};
171
172static struct platform_device scif5_device = {
173 .name = "sh-sci",
174 .id = 5,
175 .dev = {
176 .platform_data = &scif5_platform_data,
177 },
178};
179
180/* SCIFA6 */
181static struct plat_sci_port scif6_platform_data = {
182 .mapbase = 0xe6cc0000,
183 .flags = UPF_BOOT_AUTOCONF,
184 .scscr = SCSCR_RE | SCSCR_TE,
185 .scbrr_algo_id = SCBRR_ALGO_4,
186 .type = PORT_SCIFA,
215d6cc9 187 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04c0)),
6c01ba44
KM
188};
189
190static struct platform_device scif6_device = {
191 .name = "sh-sci",
192 .id = 6,
193 .dev = {
194 .platform_data = &scif6_platform_data,
195 },
196};
197
198/* SCIFA7 */
199static struct plat_sci_port scif7_platform_data = {
200 .mapbase = 0xe6cd0000,
201 .flags = UPF_BOOT_AUTOCONF,
202 .scscr = SCSCR_RE | SCSCR_TE,
203 .scbrr_algo_id = SCBRR_ALGO_4,
204 .type = PORT_SCIFA,
215d6cc9 205 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04e0)),
6c01ba44
KM
206};
207
208static struct platform_device scif7_device = {
209 .name = "sh-sci",
210 .id = 7,
211 .dev = {
212 .platform_data = &scif7_platform_data,
213 },
214};
215
216/* SCIFB */
217static struct plat_sci_port scifb_platform_data = {
218 .mapbase = 0xe6c30000,
219 .flags = UPF_BOOT_AUTOCONF,
220 .scscr = SCSCR_RE | SCSCR_TE,
221 .scbrr_algo_id = SCBRR_ALGO_4,
222 .type = PORT_SCIFB,
215d6cc9 223 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d60)),
6c01ba44
KM
224};
225
226static struct platform_device scifb_device = {
227 .name = "sh-sci",
228 .id = 8,
229 .dev = {
230 .platform_data = &scifb_platform_data,
231 },
232};
233
234/* CMT */
235static struct sh_timer_config cmt10_platform_data = {
236 .name = "CMT10",
237 .channel_offset = 0x10,
238 .timer_bit = 0,
239 .clockevent_rating = 125,
240 .clocksource_rating = 125,
241};
242
243static struct resource cmt10_resources[] = {
244 [0] = {
245 .name = "CMT10",
246 .start = 0xe6138010,
247 .end = 0xe613801b,
248 .flags = IORESOURCE_MEM,
249 },
250 [1] = {
215d6cc9 251 .start = evt2irq(0x0b00),
6c01ba44
KM
252 .flags = IORESOURCE_IRQ,
253 },
254};
255
256static struct platform_device cmt10_device = {
257 .name = "sh_cmt",
258 .id = 10,
259 .dev = {
260 .platform_data = &cmt10_platform_data,
261 },
262 .resource = cmt10_resources,
263 .num_resources = ARRAY_SIZE(cmt10_resources),
264};
265
266static struct platform_device *r8a7740_early_devices[] __initdata = {
267 &scif0_device,
268 &scif1_device,
269 &scif2_device,
270 &scif3_device,
271 &scif4_device,
272 &scif5_device,
273 &scif6_device,
274 &scif7_device,
275 &scifb_device,
276 &cmt10_device,
277};
278
6831f3a9
KM
279/* I2C */
280static struct resource i2c0_resources[] = {
281 [0] = {
282 .name = "IIC0",
283 .start = 0xfff20000,
284 .end = 0xfff20425 - 1,
285 .flags = IORESOURCE_MEM,
286 },
287 [1] = {
215d6cc9
KM
288 .start = intcs_evt2irq(0xe00),
289 .end = intcs_evt2irq(0xe60),
6831f3a9
KM
290 .flags = IORESOURCE_IRQ,
291 },
292};
293
294static struct resource i2c1_resources[] = {
295 [0] = {
296 .name = "IIC1",
297 .start = 0xe6c20000,
298 .end = 0xe6c20425 - 1,
299 .flags = IORESOURCE_MEM,
300 },
301 [1] = {
215d6cc9
KM
302 .start = evt2irq(0x780), /* IIC1_ALI1 */
303 .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
6831f3a9
KM
304 .flags = IORESOURCE_IRQ,
305 },
306};
307
308static struct platform_device i2c0_device = {
309 .name = "i2c-sh_mobile",
310 .id = 0,
311 .resource = i2c0_resources,
312 .num_resources = ARRAY_SIZE(i2c0_resources),
313};
314
315static struct platform_device i2c1_device = {
316 .name = "i2c-sh_mobile",
317 .id = 1,
318 .resource = i2c1_resources,
319 .num_resources = ARRAY_SIZE(i2c1_resources),
320};
321
322static struct platform_device *r8a7740_late_devices[] __initdata = {
323 &i2c0_device,
324 &i2c1_device,
325};
326
d49679e5
KM
327/*
328 * r8a7740 chip has lasting errata on MERAM buffer.
329 * this is work-around for it.
330 * see
331 * "Media RAM (MERAM)" on r8a7740 documentation
332 */
333#define MEBUFCNTR 0xFE950098
334void r8a7740_meram_workaround(void)
335{
336 void __iomem *reg;
337
338 reg = ioremap_nocache(MEBUFCNTR, 4);
339 if (reg) {
340 iowrite32(0x01600164, reg);
341 iounmap(reg);
342 }
343}
344
6831f3a9
KM
345#define ICCR 0x0004
346#define ICSTART 0x0070
347
348#define i2c_read(reg, offset) ioread8(reg + offset)
349#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)
350
351/*
352 * r8a7740 chip has lasting errata on I2C I/O pad reset.
353 * this is work-around for it.
354 */
355static void r8a7740_i2c_workaround(struct platform_device *pdev)
356{
357 struct resource *res;
358 void __iomem *reg;
359
360 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
361 if (unlikely(!res)) {
362 pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
363 return;
364 }
365
366 reg = ioremap(res->start, resource_size(res));
367 if (unlikely(!reg)) {
368 pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
369 return;
370 }
371
372 i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
373 i2c_read(reg, ICCR); /* dummy read */
374
375 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
376 i2c_read(reg, ICSTART); /* dummy read */
377
4228716c 378 udelay(10);
6831f3a9
KM
379
380 i2c_write(reg, ICCR, 0x01);
6831f3a9 381 i2c_write(reg, ICSTART, 0x00);
4228716c
KM
382
383 udelay(10);
6831f3a9
KM
384
385 i2c_write(reg, ICCR, 0x10);
4228716c 386 udelay(10);
6831f3a9 387 i2c_write(reg, ICCR, 0x00);
4228716c 388 udelay(10);
6831f3a9 389 i2c_write(reg, ICCR, 0x10);
4228716c 390 udelay(10);
6831f3a9
KM
391
392 iounmap(reg);
393}
394
6c01ba44
KM
395void __init r8a7740_add_standard_devices(void)
396{
6831f3a9
KM
397 /* I2C work-around */
398 r8a7740_i2c_workaround(&i2c0_device);
399 r8a7740_i2c_workaround(&i2c1_device);
400
6c01ba44
KM
401 platform_add_devices(r8a7740_early_devices,
402 ARRAY_SIZE(r8a7740_early_devices));
6831f3a9
KM
403 platform_add_devices(r8a7740_late_devices,
404 ARRAY_SIZE(r8a7740_late_devices));
6c01ba44
KM
405}
406
23e5bc03
MD
407static void __init r8a7740_earlytimer_init(void)
408{
409 r8a7740_clock_init(0);
410 shmobile_earlytimer_init();
411}
412
6c01ba44
KM
413void __init r8a7740_add_early_devices(void)
414{
415 early_platform_add_devices(r8a7740_early_devices,
416 ARRAY_SIZE(r8a7740_early_devices));
d3ab7221
MD
417
418 /* setup early console here as well */
419 shmobile_setup_console();
23e5bc03
MD
420
421 /* override timer setup with soc-specific code */
422 shmobile_timer.init = r8a7740_earlytimer_init;
6c01ba44 423}
This page took 0.067214 seconds and 5 git commands to generate.