summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c4
-rw-r--r--firmware/target/arm/as3525/dma-pl081.c22
-rw-r--r--firmware/target/arm/as3525/dma-target.h3
-rw-r--r--firmware/target/arm/as3525/pcm-as3525.c4
4 files changed, 30 insertions, 3 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index b71941adad..edde02b593 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -568,6 +568,8 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
568 goto sd_transfer_error; 568 goto sd_transfer_error;
569 } 569 }
570 570
571 dma_retain();
572
571 while(count) 573 while(count)
572 { 574 {
573 /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH 575 /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH
@@ -628,6 +630,8 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
628 630
629 while (1) 631 while (1)
630 { 632 {
633 dma_release();
634
631#ifndef BOOTLOADER 635#ifndef BOOTLOADER
632 sd_enable(false); 636 sd_enable(false);
633#endif 637#endif
diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c
index 3de4e73c12..8ec2919714 100644
--- a/firmware/target/arm/as3525/dma-pl081.c
+++ b/firmware/target/arm/as3525/dma-pl081.c
@@ -26,6 +26,7 @@
26#include "panic.h" 26#include "panic.h"
27#include "kernel.h" 27#include "kernel.h"
28 28
29static int dma_used = 0;
29static struct wakeup transfer_completion_signal[2]; /* 2 channels */ 30static struct wakeup transfer_completion_signal[2]; /* 2 channels */
30static void (*dma_callback[2])(void); /* 2 channels */ 31static void (*dma_callback[2])(void); /* 2 channels */
31 32
@@ -34,11 +35,26 @@ inline void dma_wait_transfer(int channel)
34 wakeup_wait(&transfer_completion_signal[channel], TIMEOUT_BLOCK); 35 wakeup_wait(&transfer_completion_signal[channel], TIMEOUT_BLOCK);
35} 36}
36 37
38void dma_retain(void)
39{
40 if(++dma_used == 1)
41 {
42 CGU_PERI |= CGU_DMA_CLOCK_ENABLE;
43 DMAC_CONFIGURATION |= (1<<0);
44 }
45}
46
47void dma_release(void)
48{
49 if(--dma_used == 0)
50 {
51 DMAC_CONFIGURATION &= ~(1<<0);
52 CGU_PERI &= ~CGU_DMA_CLOCK_ENABLE;
53 }
54}
55
37void dma_init(void) 56void dma_init(void)
38{ 57{
39 /* Enable DMA controller */
40 CGU_PERI |= CGU_DMA_CLOCK_ENABLE;
41 DMAC_CONFIGURATION |= (1<<0); /* TODO: disable controller when not used */
42 DMAC_SYNC = 0; 58 DMAC_SYNC = 0;
43 VIC_INT_ENABLE |= INTERRUPT_DMAC; 59 VIC_INT_ENABLE |= INTERRUPT_DMAC;
44 60
diff --git a/firmware/target/arm/as3525/dma-target.h b/firmware/target/arm/as3525/dma-target.h
index 26037999f0..6e373b89a6 100644
--- a/firmware/target/arm/as3525/dma-target.h
+++ b/firmware/target/arm/as3525/dma-target.h
@@ -37,3 +37,6 @@ void dma_enable_channel(int channel, void *src, void *dst, int peri,
37 size_t size, int nwords, void (*callback)(void)); 37 size_t size, int nwords, void (*callback)(void));
38inline void dma_disable_channel(int channel); 38inline void dma_disable_channel(int channel);
39inline void dma_wait_transfer(int channel); 39inline void dma_wait_transfer(int channel);
40
41void dma_retain(void);
42void dma_release(void);
diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c
index cf0333f24c..e5cbdc48ee 100644
--- a/firmware/target/arm/as3525/pcm-as3525.c
+++ b/firmware/target/arm/as3525/pcm-as3525.c
@@ -94,6 +94,8 @@ void pcm_play_dma_start(const void *addr, size_t size)
94 dma_size = size; 94 dma_size = size;
95 dma_start_addr = (unsigned char*)addr; 95 dma_start_addr = (unsigned char*)addr;
96 96
97 dma_retain();
98
97 play_start_pcm(); 99 play_start_pcm();
98} 100}
99 101
@@ -102,6 +104,8 @@ void pcm_play_dma_stop(void)
102 dma_disable_channel(1); 104 dma_disable_channel(1);
103 dma_size = 0; 105 dma_size = 0;
104 106
107 dma_release();
108
105 CGU_PERI &= ~CGU_I2SOUT_APB_CLOCK_ENABLE; 109 CGU_PERI &= ~CGU_I2SOUT_APB_CLOCK_ENABLE;
106 CGU_AUDIO &= ~(1<<11); 110 CGU_AUDIO &= ~(1<<11);
107} 111}