diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2012-06-25 06:36:49 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-06-30 09:07:30 -0400 |
commit | 643c3307bbbe7e80c6693376137971fbdcbe1c82 (patch) | |
tree | fced648c1b0bd62d448570e217dbeb3b021375fc /arch/arm/mach-shmobile | |
parent | b379c48a31018ef3c902f4a0f8c420bbd4caa14c (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>
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r-- | arch/arm/mach-shmobile/clock-r8a7740.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/r8a7740.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7740.c | 198 |
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 */ | ||
592 | enum { | ||
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 */ | ||
282 | enum { | ||
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 | |||
307 | static 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 | |||
334 | static 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 | |||
343 | static const unsigned int ts_shift[] = TS_SHIFT; | ||
344 | |||
345 | static 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! */ | ||
361 | static 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! */ | ||
389 | static 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! */ | ||
417 | static 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 | |||
444 | static 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 | |||
454 | static 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 | |||
464 | static 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 */ |
280 | static struct resource i2c0_resources[] = { | 475 | static struct resource i2c0_resources[] = { |
281 | [0] = { | 476 | [0] = { |
@@ -322,6 +517,9 @@ static struct platform_device i2c1_device = { | |||
322 | static struct platform_device *r8a7740_late_devices[] __initdata = { | 517 | static 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 | /* |