diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2008-12-04 22:54:06 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2008-12-04 22:54:06 +0000 |
commit | e97191faa7d685637c987dc91fc70a2cd64df57b (patch) | |
tree | f94f694a466ba9e859dbe1fe5564238a7f3d7216 /firmware | |
parent | 3e4f3fe70e8ed404ea07c12e4fe9f5a25e55b16d (diff) | |
download | rockbox-e97191faa7d685637c987dc91fc70a2cd64df57b.tar.gz rockbox-e97191faa7d685637c987dc91fc70a2cd64df57b.zip |
Sansa AMS: Disable DMA clocks when not in use
Add dma_retain() and dma_release() to reference count the users
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19344 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/as3525/dma-pl081.c | 22 | ||||
-rw-r--r-- | firmware/target/arm/as3525/dma-target.h | 3 | ||||
-rw-r--r-- | firmware/target/arm/as3525/pcm-as3525.c | 4 |
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 | ||
29 | static int dma_used = 0; | ||
29 | static struct wakeup transfer_completion_signal[2]; /* 2 channels */ | 30 | static struct wakeup transfer_completion_signal[2]; /* 2 channels */ |
30 | static void (*dma_callback[2])(void); /* 2 channels */ | 31 | static 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 | ||
38 | void 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 | |||
47 | void 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 | |||
37 | void dma_init(void) | 56 | void 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)); |
38 | inline void dma_disable_channel(int channel); | 38 | inline void dma_disable_channel(int channel); |
39 | inline void dma_wait_transfer(int channel); | 39 | inline void dma_wait_transfer(int channel); |
40 | |||
41 | void dma_retain(void); | ||
42 | void 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 | } |