aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-06-25 06:36:49 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-06-30 09:07:30 -0400
commit643c3307bbbe7e80c6693376137971fbdcbe1c82 (patch)
treefced648c1b0bd62d448570e217dbeb3b021375fc
parentb379c48a31018ef3c902f4a0f8c420bbd4caa14c (diff)
ARM: shmobile: r8a7740: add DMAEngine support for FSI
Current shdmac can support FSI DMAC on r8a7740. This support reduce CPU duty when sound was playback. This patch is based on v1.0 manual Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Magnus Damm <damm@opensource.se> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c8
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7740.h8
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c198
3 files changed, 213 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 7b9e4ab34fa2..39b131101167 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -463,6 +463,7 @@ enum {
463 463
464 MSTP230, 464 MSTP230,
465 MSTP222, 465 MSTP222,
466 MSTP218, MSTP217, MSTP216,
466 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, 467 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
467 468
468 MSTP329, MSTP328, MSTP323, MSTP320, 469 MSTP329, MSTP328, MSTP323, MSTP320,
@@ -485,6 +486,9 @@ static struct clk mstp_clks[MSTP_NR] = {
485 486
486 [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ 487 [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
487 [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ 488 [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
489 [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
490 [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
491 [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
488 [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ 492 [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
489 [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ 493 [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
490 [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ 494 [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
@@ -563,7 +567,9 @@ static struct clk_lookup lookups[] = {
563 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), 567 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
564 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), 568 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
565 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), 569 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
566 570 CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
571 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
572 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
567 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), 573 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
568 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), 574 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
569 575
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
index 6468fcc5ee49..f71507b3f917 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
@@ -588,4 +588,12 @@ enum {
588 GPIO_FN_TRACEAUD_FROM_MEMC, 588 GPIO_FN_TRACEAUD_FROM_MEMC,
589}; 589};
590 590
591/* DMA slave IDs */
592enum {
593 SHDMA_SLAVE_INVALID,
594 SHDMA_SLAVE_FSIA_RX,
595 SHDMA_SLAVE_FSIA_TX,
596 SHDMA_SLAVE_FSIB_TX,
597};
598
591#endif /* __ASM_R8A7740_H__ */ 599#endif /* __ASM_R8A7740_H__ */
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 366311b3dc73..516a7ec55620 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -24,7 +24,9 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/serial_sci.h> 26#include <linux/serial_sci.h>
27#include <linux/sh_dma.h>
27#include <linux/sh_timer.h> 28#include <linux/sh_timer.h>
29#include <linux/dma-mapping.h>
28#include <mach/r8a7740.h> 30#include <mach/r8a7740.h>
29#include <mach/common.h> 31#include <mach/common.h>
30#include <mach/irqs.h> 32#include <mach/irqs.h>
@@ -276,6 +278,199 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
276 &cmt10_device, 278 &cmt10_device,
277}; 279};
278 280
281/* DMA */
282enum {
283 XMIT_SZ_8BIT = 0,
284 XMIT_SZ_16BIT = 1,
285 XMIT_SZ_32BIT = 2,
286 XMIT_SZ_64BIT = 7,
287 XMIT_SZ_128BIT = 3,
288 XMIT_SZ_256BIT = 4,
289 XMIT_SZ_512BIT = 5,
290};
291
292/* log2(size / 8) - used to calculate number of transfers */
293#define TS_SHIFT { \
294 [XMIT_SZ_8BIT] = 0, \
295 [XMIT_SZ_16BIT] = 1, \
296 [XMIT_SZ_32BIT] = 2, \
297 [XMIT_SZ_64BIT] = 3, \
298 [XMIT_SZ_128BIT] = 4, \
299 [XMIT_SZ_256BIT] = 5, \
300 [XMIT_SZ_512BIT] = 6, \
301}
302
303#define TS_INDEX2VAL(i) ((((i) & 0x3) << 3) | (((i) & 0xc) << (20 - 2)))
304#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
305#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
306
307static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
308 {
309 .slave_id = SHDMA_SLAVE_FSIA_TX,
310 .addr = 0xfe1f0024,
311 .chcr = CHCR_TX(XMIT_SZ_32BIT),
312 .mid_rid = 0xb1,
313 }, {
314 .slave_id = SHDMA_SLAVE_FSIA_RX,
315 .addr = 0xfe1f0020,
316 .chcr = CHCR_RX(XMIT_SZ_32BIT),
317 .mid_rid = 0xb2,
318 }, {
319 .slave_id = SHDMA_SLAVE_FSIB_TX,
320 .addr = 0xfe1f0064,
321 .chcr = CHCR_TX(XMIT_SZ_32BIT),
322 .mid_rid = 0xb5,
323 },
324};
325
326#define DMA_CHANNEL(a, b, c) \
327{ \
328 .offset = a, \
329 .dmars = b, \
330 .dmars_bit = c, \
331 .chclr_offset = (0x220 - 0x20) + a \
332}
333
334static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
335 DMA_CHANNEL(0x00, 0, 0),
336 DMA_CHANNEL(0x10, 0, 8),
337 DMA_CHANNEL(0x20, 4, 0),
338 DMA_CHANNEL(0x30, 4, 8),
339 DMA_CHANNEL(0x50, 8, 0),
340 DMA_CHANNEL(0x60, 8, 8),
341};
342
343static const unsigned int ts_shift[] = TS_SHIFT;
344
345static struct sh_dmae_pdata dma_platform_data = {
346 .slave = r8a7740_dmae_slaves,
347 .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
348 .channel = r8a7740_dmae_channels,
349 .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
350 .ts_low_shift = 3,
351 .ts_low_mask = 0x18,
352 .ts_high_shift = (20 - 2),
353 .ts_high_mask = 0x00300000,
354 .ts_shift = ts_shift,
355 .ts_shift_num = ARRAY_SIZE(ts_shift),
356 .dmaor_init = DMAOR_DME,
357 .chclr_present = 1,
358};
359
360/* Resource order important! */
361static struct resource r8a7740_dmae0_resources[] = {
362 {
363 /* Channel registers and DMAOR */
364 .start = 0xfe008020,
365 .end = 0xfe00828f,
366 .flags = IORESOURCE_MEM,
367 },
368 {
369 /* DMARSx */
370 .start = 0xfe009000,
371 .end = 0xfe00900b,
372 .flags = IORESOURCE_MEM,
373 },
374 {
375 .name = "error_irq",
376 .start = evt2irq(0x20c0),
377 .end = evt2irq(0x20c0),
378 .flags = IORESOURCE_IRQ,
379 },
380 {
381 /* IRQ for channels 0-5 */
382 .start = evt2irq(0x2000),
383 .end = evt2irq(0x20a0),
384 .flags = IORESOURCE_IRQ,
385 },
386};
387
388/* Resource order important! */
389static struct resource r8a7740_dmae1_resources[] = {
390 {
391 /* Channel registers and DMAOR */
392 .start = 0xfe018020,
393 .end = 0xfe01828f,
394 .flags = IORESOURCE_MEM,
395 },
396 {
397 /* DMARSx */
398 .start = 0xfe019000,
399 .end = 0xfe01900b,
400 .flags = IORESOURCE_MEM,
401 },
402 {
403 .name = "error_irq",
404 .start = evt2irq(0x21c0),
405 .end = evt2irq(0x21c0),
406 .flags = IORESOURCE_IRQ,
407 },
408 {
409 /* IRQ for channels 0-5 */
410 .start = evt2irq(0x2100),
411 .end = evt2irq(0x21a0),
412 .flags = IORESOURCE_IRQ,
413 },
414};
415
416/* Resource order important! */
417static struct resource r8a7740_dmae2_resources[] = {
418 {
419 /* Channel registers and DMAOR */
420 .start = 0xfe028020,
421 .end = 0xfe02828f,
422 .flags = IORESOURCE_MEM,
423 },
424 {
425 /* DMARSx */
426 .start = 0xfe029000,
427 .end = 0xfe02900b,
428 .flags = IORESOURCE_MEM,
429 },
430 {
431 .name = "error_irq",
432 .start = evt2irq(0x22c0),
433 .end = evt2irq(0x22c0),
434 .flags = IORESOURCE_IRQ,
435 },
436 {
437 /* IRQ for channels 0-5 */
438 .start = evt2irq(0x2200),
439 .end = evt2irq(0x22a0),
440 .flags = IORESOURCE_IRQ,
441 },
442};
443
444static struct platform_device dma0_device = {
445 .name = "sh-dma-engine",
446 .id = 0,
447 .resource = r8a7740_dmae0_resources,
448 .num_resources = ARRAY_SIZE(r8a7740_dmae0_resources),
449 .dev = {
450 .platform_data = &dma_platform_data,
451 },
452};
453
454static struct platform_device dma1_device = {
455 .name = "sh-dma-engine",
456 .id = 1,
457 .resource = r8a7740_dmae1_resources,
458 .num_resources = ARRAY_SIZE(r8a7740_dmae1_resources),
459 .dev = {
460 .platform_data = &dma_platform_data,
461 },
462};
463
464static struct platform_device dma2_device = {
465 .name = "sh-dma-engine",
466 .id = 2,
467 .resource = r8a7740_dmae2_resources,
468 .num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
469 .dev = {
470 .platform_data = &dma_platform_data,
471 },
472};
473
279/* I2C */ 474/* I2C */
280static struct resource i2c0_resources[] = { 475static struct resource i2c0_resources[] = {
281 [0] = { 476 [0] = {
@@ -322,6 +517,9 @@ static struct platform_device i2c1_device = {
322static struct platform_device *r8a7740_late_devices[] __initdata = { 517static struct platform_device *r8a7740_late_devices[] __initdata = {
323 &i2c0_device, 518 &i2c0_device,
324 &i2c1_device, 519 &i2c1_device,
520 &dma0_device,
521 &dma1_device,
522 &dma2_device,
325}; 523};
326 524
327/* 525/*