blob: 48d7bbf0d2e26653146d1d8f68bb8870ea70741e [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 Morimoto3841e6f2012-04-24 02:10:05 -070021#include <linux/dma-mapping.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080022#include <linux/kernel.h>
23#include <linux/init.h>
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -080024#include <linux/io.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080025#include <linux/platform_device.h>
26#include <linux/serial_sci.h>
Kuninori Morimoto643c3302012-06-25 03:36:49 -070027#include <linux/sh_dma.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080028#include <linux/sh_timer.h>
Kuninori Morimoto643c3302012-06-25 03:36:49 -070029#include <linux/dma-mapping.h>
Kuninori Morimotod7de9382012-06-25 03:43:10 -070030#include <mach/dma-register.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080031#include <mach/r8a7740.h>
Magnus Dammd3ab7222012-02-29 21:37:35 +090032#include <mach/common.h>
Rob Herring250a2722012-01-03 16:57:33 -060033#include <mach/irqs.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080034#include <asm/mach-types.h>
Magnus Dammd3ab7222012-02-29 21:37:35 +090035#include <asm/mach/map.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080036#include <asm/mach/arch.h>
Magnus Damm23e5bc02012-03-06 17:36:53 +090037#include <asm/mach/time.h>
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080038
Magnus Dammd3ab7222012-02-29 21:37:35 +090039static struct map_desc r8a7740_io_desc[] __initdata = {
40 /*
41 * for CPGA/INTC/PFC
42 * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
43 */
44 {
45 .virtual = 0xe6000000,
46 .pfn = __phys_to_pfn(0xe6000000),
47 .length = 160 << 20,
48 .type = MT_DEVICE_NONSHARED
49 },
50#ifdef CONFIG_CACHE_L2X0
51 /*
52 * for l2x0_init()
53 * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
54 */
55 {
56 .virtual = 0xf0002000,
57 .pfn = __phys_to_pfn(0xf0100000),
58 .length = PAGE_SIZE,
59 .type = MT_DEVICE_NONSHARED
60 },
61#endif
62};
63
64void __init r8a7740_map_io(void)
65{
66 iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
Kuninori Morimoto3841e6f2012-04-24 02:10:05 -070067
68 /*
69 * DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
70 * enough to allocate the frame buffer memory.
71 */
72 init_consistent_dma_size(12 << 20);
Magnus Dammd3ab7222012-02-29 21:37:35 +090073}
74
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080075/* SCIFA0 */
76static struct plat_sci_port scif0_platform_data = {
77 .mapbase = 0xe6c40000,
78 .flags = UPF_BOOT_AUTOCONF,
79 .scscr = SCSCR_RE | SCSCR_TE,
80 .scbrr_algo_id = SCBRR_ALGO_4,
81 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -080082 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c00)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -080083};
84
85static struct platform_device scif0_device = {
86 .name = "sh-sci",
87 .id = 0,
88 .dev = {
89 .platform_data = &scif0_platform_data,
90 },
91};
92
93/* SCIFA1 */
94static struct plat_sci_port scif1_platform_data = {
95 .mapbase = 0xe6c50000,
96 .flags = UPF_BOOT_AUTOCONF,
97 .scscr = SCSCR_RE | SCSCR_TE,
98 .scbrr_algo_id = SCBRR_ALGO_4,
99 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800100 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c20)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800101};
102
103static struct platform_device scif1_device = {
104 .name = "sh-sci",
105 .id = 1,
106 .dev = {
107 .platform_data = &scif1_platform_data,
108 },
109};
110
111/* SCIFA2 */
112static struct plat_sci_port scif2_platform_data = {
113 .mapbase = 0xe6c60000,
114 .flags = UPF_BOOT_AUTOCONF,
115 .scscr = SCSCR_RE | SCSCR_TE,
116 .scbrr_algo_id = SCBRR_ALGO_4,
117 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800118 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c40)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800119};
120
121static struct platform_device scif2_device = {
122 .name = "sh-sci",
123 .id = 2,
124 .dev = {
125 .platform_data = &scif2_platform_data,
126 },
127};
128
129/* SCIFA3 */
130static struct plat_sci_port scif3_platform_data = {
131 .mapbase = 0xe6c70000,
132 .flags = UPF_BOOT_AUTOCONF,
133 .scscr = SCSCR_RE | SCSCR_TE,
134 .scbrr_algo_id = SCBRR_ALGO_4,
135 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800136 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c60)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800137};
138
139static struct platform_device scif3_device = {
140 .name = "sh-sci",
141 .id = 3,
142 .dev = {
143 .platform_data = &scif3_platform_data,
144 },
145};
146
147/* SCIFA4 */
148static struct plat_sci_port scif4_platform_data = {
149 .mapbase = 0xe6c80000,
150 .flags = UPF_BOOT_AUTOCONF,
151 .scscr = SCSCR_RE | SCSCR_TE,
152 .scbrr_algo_id = SCBRR_ALGO_4,
153 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800154 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d20)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800155};
156
157static struct platform_device scif4_device = {
158 .name = "sh-sci",
159 .id = 4,
160 .dev = {
161 .platform_data = &scif4_platform_data,
162 },
163};
164
165/* SCIFA5 */
166static struct plat_sci_port scif5_platform_data = {
167 .mapbase = 0xe6cb0000,
168 .flags = UPF_BOOT_AUTOCONF,
169 .scscr = SCSCR_RE | SCSCR_TE,
170 .scbrr_algo_id = SCBRR_ALGO_4,
171 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800172 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d40)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800173};
174
175static struct platform_device scif5_device = {
176 .name = "sh-sci",
177 .id = 5,
178 .dev = {
179 .platform_data = &scif5_platform_data,
180 },
181};
182
183/* SCIFA6 */
184static struct plat_sci_port scif6_platform_data = {
185 .mapbase = 0xe6cc0000,
186 .flags = UPF_BOOT_AUTOCONF,
187 .scscr = SCSCR_RE | SCSCR_TE,
188 .scbrr_algo_id = SCBRR_ALGO_4,
189 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800190 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04c0)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800191};
192
193static struct platform_device scif6_device = {
194 .name = "sh-sci",
195 .id = 6,
196 .dev = {
197 .platform_data = &scif6_platform_data,
198 },
199};
200
201/* SCIFA7 */
202static struct plat_sci_port scif7_platform_data = {
203 .mapbase = 0xe6cd0000,
204 .flags = UPF_BOOT_AUTOCONF,
205 .scscr = SCSCR_RE | SCSCR_TE,
206 .scbrr_algo_id = SCBRR_ALGO_4,
207 .type = PORT_SCIFA,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800208 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04e0)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800209};
210
211static struct platform_device scif7_device = {
212 .name = "sh-sci",
213 .id = 7,
214 .dev = {
215 .platform_data = &scif7_platform_data,
216 },
217};
218
219/* SCIFB */
220static struct plat_sci_port scifb_platform_data = {
221 .mapbase = 0xe6c30000,
222 .flags = UPF_BOOT_AUTOCONF,
223 .scscr = SCSCR_RE | SCSCR_TE,
224 .scbrr_algo_id = SCBRR_ALGO_4,
225 .type = PORT_SCIFB,
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800226 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d60)),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800227};
228
229static struct platform_device scifb_device = {
230 .name = "sh-sci",
231 .id = 8,
232 .dev = {
233 .platform_data = &scifb_platform_data,
234 },
235};
236
237/* CMT */
238static struct sh_timer_config cmt10_platform_data = {
239 .name = "CMT10",
240 .channel_offset = 0x10,
241 .timer_bit = 0,
242 .clockevent_rating = 125,
243 .clocksource_rating = 125,
244};
245
246static struct resource cmt10_resources[] = {
247 [0] = {
248 .name = "CMT10",
249 .start = 0xe6138010,
250 .end = 0xe613801b,
251 .flags = IORESOURCE_MEM,
252 },
253 [1] = {
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800254 .start = evt2irq(0x0b00),
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800255 .flags = IORESOURCE_IRQ,
256 },
257};
258
259static struct platform_device cmt10_device = {
260 .name = "sh_cmt",
261 .id = 10,
262 .dev = {
263 .platform_data = &cmt10_platform_data,
264 },
265 .resource = cmt10_resources,
266 .num_resources = ARRAY_SIZE(cmt10_resources),
267};
268
269static struct platform_device *r8a7740_early_devices[] __initdata = {
270 &scif0_device,
271 &scif1_device,
272 &scif2_device,
273 &scif3_device,
274 &scif4_device,
275 &scif5_device,
276 &scif6_device,
277 &scif7_device,
278 &scifb_device,
279 &cmt10_device,
280};
281
Kuninori Morimoto643c3302012-06-25 03:36:49 -0700282/* DMA */
Kuninori Morimoto643c3302012-06-25 03:36:49 -0700283static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
284 {
Kuninori Morimotocb76eb82012-06-25 03:37:00 -0700285 .slave_id = SHDMA_SLAVE_SDHI0_TX,
286 .addr = 0xe6850030,
287 .chcr = CHCR_TX(XMIT_SZ_16BIT),
288 .mid_rid = 0xc1,
289 }, {
290 .slave_id = SHDMA_SLAVE_SDHI0_RX,
291 .addr = 0xe6850030,
292 .chcr = CHCR_RX(XMIT_SZ_16BIT),
293 .mid_rid = 0xc2,
294 }, {
295 .slave_id = SHDMA_SLAVE_SDHI1_TX,
296 .addr = 0xe6860030,
297 .chcr = CHCR_TX(XMIT_SZ_16BIT),
298 .mid_rid = 0xc9,
299 }, {
300 .slave_id = SHDMA_SLAVE_SDHI1_RX,
301 .addr = 0xe6860030,
302 .chcr = CHCR_RX(XMIT_SZ_16BIT),
303 .mid_rid = 0xca,
304 }, {
305 .slave_id = SHDMA_SLAVE_SDHI2_TX,
306 .addr = 0xe6870030,
307 .chcr = CHCR_TX(XMIT_SZ_16BIT),
308 .mid_rid = 0xcd,
309 }, {
310 .slave_id = SHDMA_SLAVE_SDHI2_RX,
311 .addr = 0xe6870030,
312 .chcr = CHCR_RX(XMIT_SZ_16BIT),
313 .mid_rid = 0xce,
314 }, {
Kuninori Morimoto643c3302012-06-25 03:36:49 -0700315 .slave_id = SHDMA_SLAVE_FSIA_TX,
316 .addr = 0xfe1f0024,
317 .chcr = CHCR_TX(XMIT_SZ_32BIT),
318 .mid_rid = 0xb1,
319 }, {
320 .slave_id = SHDMA_SLAVE_FSIA_RX,
321 .addr = 0xfe1f0020,
322 .chcr = CHCR_RX(XMIT_SZ_32BIT),
323 .mid_rid = 0xb2,
324 }, {
325 .slave_id = SHDMA_SLAVE_FSIB_TX,
326 .addr = 0xfe1f0064,
327 .chcr = CHCR_TX(XMIT_SZ_32BIT),
328 .mid_rid = 0xb5,
329 },
330};
331
332#define DMA_CHANNEL(a, b, c) \
333{ \
334 .offset = a, \
335 .dmars = b, \
336 .dmars_bit = c, \
337 .chclr_offset = (0x220 - 0x20) + a \
338}
339
340static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
341 DMA_CHANNEL(0x00, 0, 0),
342 DMA_CHANNEL(0x10, 0, 8),
343 DMA_CHANNEL(0x20, 4, 0),
344 DMA_CHANNEL(0x30, 4, 8),
345 DMA_CHANNEL(0x50, 8, 0),
346 DMA_CHANNEL(0x60, 8, 8),
347};
348
Kuninori Morimoto643c3302012-06-25 03:36:49 -0700349static struct sh_dmae_pdata dma_platform_data = {
350 .slave = r8a7740_dmae_slaves,
351 .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
352 .channel = r8a7740_dmae_channels,
353 .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
Kuninori Morimotod7de9382012-06-25 03:43:10 -0700354 .ts_low_shift = TS_LOW_SHIFT,
355 .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
356 .ts_high_shift = TS_HI_SHIFT,
357 .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
358 .ts_shift = dma_ts_shift,
359 .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
Kuninori Morimoto643c3302012-06-25 03:36:49 -0700360 .dmaor_init = DMAOR_DME,
361 .chclr_present = 1,
362};
363
364/* Resource order important! */
365static struct resource r8a7740_dmae0_resources[] = {
366 {
367 /* Channel registers and DMAOR */
368 .start = 0xfe008020,
369 .end = 0xfe00828f,
370 .flags = IORESOURCE_MEM,
371 },
372 {
373 /* DMARSx */
374 .start = 0xfe009000,
375 .end = 0xfe00900b,
376 .flags = IORESOURCE_MEM,
377 },
378 {
379 .name = "error_irq",
380 .start = evt2irq(0x20c0),
381 .end = evt2irq(0x20c0),
382 .flags = IORESOURCE_IRQ,
383 },
384 {
385 /* IRQ for channels 0-5 */
386 .start = evt2irq(0x2000),
387 .end = evt2irq(0x20a0),
388 .flags = IORESOURCE_IRQ,
389 },
390};
391
392/* Resource order important! */
393static struct resource r8a7740_dmae1_resources[] = {
394 {
395 /* Channel registers and DMAOR */
396 .start = 0xfe018020,
397 .end = 0xfe01828f,
398 .flags = IORESOURCE_MEM,
399 },
400 {
401 /* DMARSx */
402 .start = 0xfe019000,
403 .end = 0xfe01900b,
404 .flags = IORESOURCE_MEM,
405 },
406 {
407 .name = "error_irq",
408 .start = evt2irq(0x21c0),
409 .end = evt2irq(0x21c0),
410 .flags = IORESOURCE_IRQ,
411 },
412 {
413 /* IRQ for channels 0-5 */
414 .start = evt2irq(0x2100),
415 .end = evt2irq(0x21a0),
416 .flags = IORESOURCE_IRQ,
417 },
418};
419
420/* Resource order important! */
421static struct resource r8a7740_dmae2_resources[] = {
422 {
423 /* Channel registers and DMAOR */
424 .start = 0xfe028020,
425 .end = 0xfe02828f,
426 .flags = IORESOURCE_MEM,
427 },
428 {
429 /* DMARSx */
430 .start = 0xfe029000,
431 .end = 0xfe02900b,
432 .flags = IORESOURCE_MEM,
433 },
434 {
435 .name = "error_irq",
436 .start = evt2irq(0x22c0),
437 .end = evt2irq(0x22c0),
438 .flags = IORESOURCE_IRQ,
439 },
440 {
441 /* IRQ for channels 0-5 */
442 .start = evt2irq(0x2200),
443 .end = evt2irq(0x22a0),
444 .flags = IORESOURCE_IRQ,
445 },
446};
447
448static struct platform_device dma0_device = {
449 .name = "sh-dma-engine",
450 .id = 0,
451 .resource = r8a7740_dmae0_resources,
452 .num_resources = ARRAY_SIZE(r8a7740_dmae0_resources),
453 .dev = {
454 .platform_data = &dma_platform_data,
455 },
456};
457
458static struct platform_device dma1_device = {
459 .name = "sh-dma-engine",
460 .id = 1,
461 .resource = r8a7740_dmae1_resources,
462 .num_resources = ARRAY_SIZE(r8a7740_dmae1_resources),
463 .dev = {
464 .platform_data = &dma_platform_data,
465 },
466};
467
468static struct platform_device dma2_device = {
469 .name = "sh-dma-engine",
470 .id = 2,
471 .resource = r8a7740_dmae2_resources,
472 .num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
473 .dev = {
474 .platform_data = &dma_platform_data,
475 },
476};
477
Kuninori Morimotodbf382e2012-06-25 03:37:10 -0700478/* USB-DMAC */
Kuninori Morimotodbf382e2012-06-25 03:37:10 -0700479static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
480 {
481 .offset = 0,
482 }, {
483 .offset = 0x20,
484 },
485};
486
Kuninori Morimotodbf382e2012-06-25 03:37:10 -0700487static const struct sh_dmae_slave_config r8a7740_usb_dma_slaves[] = {
488 {
489 .slave_id = SHDMA_SLAVE_USBHS_TX,
490 .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
491 }, {
492 .slave_id = SHDMA_SLAVE_USBHS_RX,
493 .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
494 },
495};
496
497static struct sh_dmae_pdata usb_dma_platform_data = {
498 .slave = r8a7740_usb_dma_slaves,
499 .slave_num = ARRAY_SIZE(r8a7740_usb_dma_slaves),
500 .channel = r8a7740_usb_dma_channels,
501 .channel_num = ARRAY_SIZE(r8a7740_usb_dma_channels),
Kuninori Morimotod7de9382012-06-25 03:43:10 -0700502 .ts_low_shift = USBTS_LOW_SHIFT,
503 .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT,
504 .ts_high_shift = USBTS_HI_SHIFT,
505 .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT,
Kuninori Morimotodbf382e2012-06-25 03:37:10 -0700506 .ts_shift = dma_usbts_shift,
507 .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
508 .dmaor_init = DMAOR_DME,
509 .chcr_offset = 0x14,
510 .chcr_ie_bit = 1 << 5,
511 .dmaor_is_32bit = 1,
512 .needs_tend_set = 1,
513 .no_dmars = 1,
514 .slave_only = 1,
515};
516
517static struct resource r8a7740_usb_dma_resources[] = {
518 {
519 /* Channel registers and DMAOR */
520 .start = 0xe68a0020,
521 .end = 0xe68a0064 - 1,
522 .flags = IORESOURCE_MEM,
523 },
524 {
525 /* VCR/SWR/DMICR */
526 .start = 0xe68a0000,
527 .end = 0xe68a0014 - 1,
528 .flags = IORESOURCE_MEM,
529 },
530 {
531 /* IRQ for channels */
532 .start = evt2irq(0x0a00),
533 .end = evt2irq(0x0a00),
534 .flags = IORESOURCE_IRQ,
535 },
536};
537
538static struct platform_device usb_dma_device = {
539 .name = "sh-dma-engine",
540 .id = 3,
541 .resource = r8a7740_usb_dma_resources,
542 .num_resources = ARRAY_SIZE(r8a7740_usb_dma_resources),
543 .dev = {
544 .platform_data = &usb_dma_platform_data,
545 },
546};
547
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800548/* I2C */
549static struct resource i2c0_resources[] = {
550 [0] = {
551 .name = "IIC0",
552 .start = 0xfff20000,
553 .end = 0xfff20425 - 1,
554 .flags = IORESOURCE_MEM,
555 },
556 [1] = {
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800557 .start = intcs_evt2irq(0xe00),
558 .end = intcs_evt2irq(0xe60),
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800559 .flags = IORESOURCE_IRQ,
560 },
561};
562
563static struct resource i2c1_resources[] = {
564 [0] = {
565 .name = "IIC1",
566 .start = 0xe6c20000,
567 .end = 0xe6c20425 - 1,
568 .flags = IORESOURCE_MEM,
569 },
570 [1] = {
Kuninori Morimoto215d6cc2011-11-10 18:46:35 -0800571 .start = evt2irq(0x780), /* IIC1_ALI1 */
572 .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800573 .flags = IORESOURCE_IRQ,
574 },
575};
576
577static struct platform_device i2c0_device = {
578 .name = "i2c-sh_mobile",
579 .id = 0,
580 .resource = i2c0_resources,
581 .num_resources = ARRAY_SIZE(i2c0_resources),
582};
583
584static struct platform_device i2c1_device = {
585 .name = "i2c-sh_mobile",
586 .id = 1,
587 .resource = i2c1_resources,
588 .num_resources = ARRAY_SIZE(i2c1_resources),
589};
590
591static struct platform_device *r8a7740_late_devices[] __initdata = {
592 &i2c0_device,
593 &i2c1_device,
Kuninori Morimoto643c3302012-06-25 03:36:49 -0700594 &dma0_device,
595 &dma1_device,
596 &dma2_device,
Kuninori Morimotodbf382e2012-06-25 03:37:10 -0700597 &usb_dma_device,
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800598};
599
Kuninori Morimotod49679e2012-06-12 02:36:21 -0700600/*
601 * r8a7740 chip has lasting errata on MERAM buffer.
602 * this is work-around for it.
603 * see
604 * "Media RAM (MERAM)" on r8a7740 documentation
605 */
606#define MEBUFCNTR 0xFE950098
607void r8a7740_meram_workaround(void)
608{
609 void __iomem *reg;
610
611 reg = ioremap_nocache(MEBUFCNTR, 4);
612 if (reg) {
613 iowrite32(0x01600164, reg);
614 iounmap(reg);
615 }
616}
617
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800618#define ICCR 0x0004
619#define ICSTART 0x0070
620
621#define i2c_read(reg, offset) ioread8(reg + offset)
622#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)
623
624/*
625 * r8a7740 chip has lasting errata on I2C I/O pad reset.
626 * this is work-around for it.
627 */
628static void r8a7740_i2c_workaround(struct platform_device *pdev)
629{
630 struct resource *res;
631 void __iomem *reg;
632
633 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
634 if (unlikely(!res)) {
635 pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
636 return;
637 }
638
639 reg = ioremap(res->start, resource_size(res));
640 if (unlikely(!reg)) {
641 pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
642 return;
643 }
644
645 i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
646 i2c_read(reg, ICCR); /* dummy read */
647
648 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
649 i2c_read(reg, ICSTART); /* dummy read */
650
Kuninori Morimoto42287162012-04-13 02:41:06 -0700651 udelay(10);
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800652
653 i2c_write(reg, ICCR, 0x01);
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800654 i2c_write(reg, ICSTART, 0x00);
Kuninori Morimoto42287162012-04-13 02:41:06 -0700655
656 udelay(10);
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800657
658 i2c_write(reg, ICCR, 0x10);
Kuninori Morimoto42287162012-04-13 02:41:06 -0700659 udelay(10);
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800660 i2c_write(reg, ICCR, 0x00);
Kuninori Morimoto42287162012-04-13 02:41:06 -0700661 udelay(10);
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800662 i2c_write(reg, ICCR, 0x10);
Kuninori Morimoto42287162012-04-13 02:41:06 -0700663 udelay(10);
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800664
665 iounmap(reg);
666}
667
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800668void __init r8a7740_add_standard_devices(void)
669{
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800670 /* I2C work-around */
671 r8a7740_i2c_workaround(&i2c0_device);
672 r8a7740_i2c_workaround(&i2c1_device);
673
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800674 platform_add_devices(r8a7740_early_devices,
675 ARRAY_SIZE(r8a7740_early_devices));
Kuninori Morimoto6831f3a2011-11-10 18:46:23 -0800676 platform_add_devices(r8a7740_late_devices,
677 ARRAY_SIZE(r8a7740_late_devices));
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800678}
679
Magnus Damm23e5bc02012-03-06 17:36:53 +0900680static void __init r8a7740_earlytimer_init(void)
681{
682 r8a7740_clock_init(0);
683 shmobile_earlytimer_init();
684}
685
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800686void __init r8a7740_add_early_devices(void)
687{
688 early_platform_add_devices(r8a7740_early_devices,
689 ARRAY_SIZE(r8a7740_early_devices));
Magnus Dammd3ab7222012-02-29 21:37:35 +0900690
691 /* setup early console here as well */
692 shmobile_setup_console();
Magnus Damm23e5bc02012-03-06 17:36:53 +0900693
694 /* override timer setup with soc-specific code */
695 shmobile_timer.init = r8a7740_earlytimer_init;
Kuninori Morimoto6c01ba42011-11-10 18:45:52 -0800696}