summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/config/gigabeats.h1
-rw-r--r--firmware/export/pcm.h4
-rw-r--r--firmware/pcm.c62
-rw-r--r--firmware/target/arm/as3525/pcm-as3525.c13
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c27
-rw-r--r--firmware/target/arm/pcm-pp.c22
-rw-r--r--firmware/target/arm/pcm-telechips.c7
-rw-r--r--firmware/target/arm/s5l8700/pcm-s5l8700.c6
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c34
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c5
10 files changed, 78 insertions, 103 deletions
diff --git a/firmware/export/config/gigabeats.h b/firmware/export/config/gigabeats.h
index 2e48923..19a8fa4 100644
--- a/firmware/export/config/gigabeats.h
+++ b/firmware/export/config/gigabeats.h
@@ -220,6 +220,7 @@
/* #define HAVE_ADJUSTABLE_CPU_FREQ */
#define HAVE_PCM_DMA_ADDRESS
+#define HAVE_PCM_REC_DMA_ADDRESS
#define BOOTFILE_EXT "gigabeat"
#define BOOTFILE "rockbox." BOOTFILE_EXT
diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h
index 0f8222f..0e71814 100644
--- a/firmware/export/pcm.h
+++ b/firmware/export/pcm.h
@@ -140,7 +140,6 @@ void pcm_calculate_rec_peaks(int *left, int *right);
/** The following are for internal use between pcm.c and target-
specific portion **/
-extern volatile const void *pcm_rec_peak_addr;
/* the registered callback function for when more data is available */
extern volatile pcm_more_callback_type2 pcm_callback_more_ready;
/* DMA transfer in is currently active */
@@ -150,9 +149,10 @@ extern volatile bool pcm_recording;
void pcm_rec_dma_init(void);
void pcm_rec_dma_close(void);
void pcm_rec_dma_start(void *addr, size_t size);
+void pcm_rec_dma_record_more(void *start, size_t size);
void pcm_rec_dma_stop(void);
void pcm_rec_dma_stopped_callback(void);
-const void * pcm_rec_dma_get_peak_buffer(int *count);
+const void * pcm_rec_dma_get_peak_buffer(void);
#endif /* HAVE_RECORDING */
diff --git a/firmware/pcm.c b/firmware/pcm.c
index edd4113..8d2ec2b 100644
--- a/firmware/pcm.c
+++ b/firmware/pcm.c
@@ -40,7 +40,6 @@
* pcm_play_unlock
* Semi-private -
* pcm_play_dma_init
- * pcm_play_dma_init
* pcm_play_dma_start
* pcm_play_dma_stop
* pcm_play_dma_pause
@@ -66,10 +65,10 @@
* pcm_rec_dma_init
* pcm_rec_dma_close
* pcm_rec_dma_start
+ * pcm_rec_dma_record_more
* pcm_rec_dma_stop
* pcm_rec_dma_get_peak_buffer
* Data Read/Written within TSP -
- * pcm_rec_peak_addr (R/W)
* pcm_callback_more_ready (R)
* pcm_recording (R)
*
@@ -210,6 +209,9 @@ void pcm_init(void)
/* Common code to pcm_play_data and pcm_play_pause */
static void pcm_play_data_start(unsigned char *start, size_t size)
{
+ start = (unsigned char *)(((uintptr_t)start + 3) & ~3);
+ size &= ~3;
+
if (!(start && size))
{
pcm_more_callback_type get_more = pcm_callback_for_more;
@@ -218,6 +220,9 @@ static void pcm_play_data_start(unsigned char *start, size_t size)
{
logf(" get_more");
get_more(&start, &size);
+
+ start = (unsigned char *)(((uintptr_t)start + 3) & ~3);
+ size &= ~3;
}
}
@@ -359,7 +364,7 @@ bool pcm_is_paused(void)
/** Low level pcm recording apis **/
/* Next start for recording peaks */
-const volatile void *pcm_rec_peak_addr SHAREDBSS_ATTR = NULL;
+static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL;
/* the registered callback function for when more data is available */
volatile pcm_more_callback_type2
pcm_callback_more_ready SHAREDBSS_ATTR = NULL;
@@ -373,17 +378,23 @@ volatile bool pcm_recording SHAREDBSS_ATTR = false;
void pcm_calculate_rec_peaks(int *left, int *right)
{
static int peaks[2];
- int count;
- const void *addr = pcm_rec_dma_get_peak_buffer(&count);
if (pcm_recording)
{
- if (count > 0)
+ const void *peak_addr = pcm_rec_peak_addr;
+ const void *addr = pcm_rec_dma_get_peak_buffer();
+
+ if (addr != NULL)
{
- pcm_peak_peeker(addr, count, peaks);
+ int count = (int)(((intptr_t)addr - (intptr_t)peak_addr) >> 2);
- if (addr == pcm_rec_peak_addr)
- pcm_rec_peak_addr = (int32_t *)addr + count;
+ if (count > 0)
+ {
+ pcm_peak_peeker(peak_addr, count, peaks);
+
+ if (peak_addr == pcm_rec_peak_addr)
+ pcm_rec_peak_addr = addr;
+ }
}
/* else keep previous peak values */
}
@@ -443,6 +454,10 @@ void pcm_record_data(pcm_more_callback_type2 more_ready,
{
logf("pcm_record_data");
+ /* 32-bit aligned and sized data only */
+ start = (void *)(((uintptr_t)start + 3) & ~3);
+ size &= ~3;
+
if (!(start && size))
{
logf(" no buffer");
@@ -453,6 +468,13 @@ void pcm_record_data(pcm_more_callback_type2 more_ready,
pcm_callback_more_ready = more_ready;
+#ifdef HAVE_PCM_REC_DMA_ADDRESS
+ /* Need a physical DMA address translation, if not already physical. */
+ pcm_rec_peak_addr = pcm_dma_addr(start);
+#else
+ pcm_rec_peak_addr = start;
+#endif
+
logf(" pcm_rec_dma_start");
pcm_apply_settings();
pcm_rec_dma_start(start, size);
@@ -477,6 +499,28 @@ void pcm_stop_recording(void)
pcm_rec_unlock();
} /* pcm_stop_recording */
+void pcm_record_more(void *start, size_t size)
+{
+ start = (void *)(((uintptr_t)start + 3) & ~3);
+ size = size & ~3;
+
+ if (!size)
+ {
+ pcm_rec_dma_stop();
+ pcm_rec_dma_stopped_callback();
+ return;
+ }
+
+#ifdef HAVE_PCM_REC_DMA_ADDRESS
+ /* Need a physical DMA address translation, if not already physical. */
+ pcm_rec_peak_addr = pcm_dma_addr(start);
+#else
+ pcm_rec_peak_addr = start;
+#endif
+
+ pcm_rec_dma_record_more(start, size);
+}
+
bool pcm_is_recording(void)
{
return pcm_recording;
diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c
index 53a3f0c..4d78899 100644
--- a/firmware/target/arm/as3525/pcm-as3525.c
+++ b/firmware/target/arm/as3525/pcm-as3525.c
@@ -202,7 +202,7 @@ void pcm_rec_unlock(void)
}
-void pcm_record_more(void *start, size_t size)
+void pcm_rec_dma_record_more(void *start, size_t size)
{
rec_start_addr = start;
rec_size = size;
@@ -331,16 +331,9 @@ void pcm_rec_dma_init(void)
}
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
- const void *peak_buffer;
-
- pcm_rec_lock();
- *count = rec_size >> 2;
- peak_buffer = (const void*)rec_start_addr;
- pcm_rec_unlock();
-
- return peak_buffer;
+ return (const void*)rec_start_addr;
}
#endif /* HAVE_RECORDING */
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
index c0651ca..02051fa 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
@@ -432,17 +432,13 @@ void pcm_rec_unlock(void)
}
}
-void pcm_record_more(void *start, size_t size)
+void pcm_rec_dma_record_more(void *start, size_t size)
{
- start = (void *)(((unsigned long)start + 3) & ~3);
- size &= ~3;
-
/* Invalidate - buffer must be coherent */
dump_dcache_range(start, size);
start = (void *)addr_virt_to_phys((unsigned long)start);
- pcm_rec_peak_addr = start;
dma_rec_bd.buf_addr = start;
dma_rec_bd.mode.count = size;
dma_rec_bd.mode.command = TRANSFER_16BIT;
@@ -469,12 +465,6 @@ void pcm_rec_dma_start(void *addr, size_t size)
{
pcm_rec_dma_stop();
- addr = (void *)(((unsigned long)addr + 3) & ~3);
- size &= ~3;
-
- if (size <= 0)
- return;
-
if (!sdma_channel_reset(DMA_REC_CH_NUM))
return;
@@ -482,7 +472,6 @@ void pcm_rec_dma_start(void *addr, size_t size)
dump_dcache_range(addr, size);
addr = (void *)addr_virt_to_phys((unsigned long)addr);
- pcm_rec_peak_addr = addr;
dma_rec_bd.buf_addr = addr;
dma_rec_bd.mode.count = size;
dma_rec_bd.mode.command = TRANSFER_16BIT;
@@ -524,10 +513,10 @@ void pcm_rec_dma_init(void)
sdma_channel_set_priority(DMA_REC_CH_NUM, DMA_REC_CH_PRIORITY);
}
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
static unsigned long pda NOCACHEBSS_ATTR;
- unsigned long buf, addr, end, bufend;
+ unsigned long buf, end, bufend;
int oldstatus;
/* read burst dma destination address register in channel context */
@@ -536,19 +525,13 @@ const void * pcm_rec_dma_get_peak_buffer(int *count)
oldstatus = disable_irq_save();
end = pda;
buf = (unsigned long)dma_rec_bd.buf_addr;
- addr = (unsigned long)pcm_rec_peak_addr;
bufend = buf + dma_rec_bd.mode.count;
restore_irq(oldstatus);
/* Be addresses are coherent (no buffer change during read) */
- if (addr >= buf && addr < bufend &&
- end >= buf && end < bufend)
- {
- *count = (end >> 2) - (addr >> 2);
- return (void *)(addr & ~3);
- }
+ if (end >= buf && end < bufend)
+ return (void *)(end & ~3);
- *count = 0;
return NULL;
}
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c
index bd12b13..bad3f59 100644
--- a/firmware/target/arm/pcm-pp.c
+++ b/firmware/target/arm/pcm-pp.c
@@ -431,9 +431,6 @@ static void play_stop_pcm(void)
void pcm_play_dma_start(const void *addr, size_t size)
{
- addr = (void *)(((long)addr + 2) & ~3);
- size &= ~3;
-
#if NUM_CORES > 1
/* This will become more important later - and different ! */
dma_play_data.core = processor_id(); /* save initiating core */
@@ -441,9 +438,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
pcm_play_dma_stop();
- if (size == 0)
- return;
-
#ifdef CPU_PP502x
if ((unsigned long)addr < UNCACHED_BASE_ADDR) {
/* Flush any pending cache writes */
@@ -691,9 +685,8 @@ void fiq_record(void)
#endif /* SANSA_E200 */
/* Continue transferring data in */
-void pcm_record_more(void *start, size_t size)
+void pcm_rec_dma_record_more(void *start, size_t size)
{
- pcm_rec_peak_addr = start; /* Start peaking at dest */
dma_rec_data.addr = (unsigned long)start; /* Start of RX buffer */
dma_rec_data.size = size; /* Bytes to transfer */
}
@@ -718,7 +711,6 @@ void pcm_rec_dma_start(void *addr, size_t size)
{
pcm_rec_dma_stop();
- pcm_rec_peak_addr = addr;
dma_rec_data.addr = (unsigned long)addr;
dma_rec_data.size = size;
#if NUM_CORES > 1
@@ -749,17 +741,9 @@ void pcm_rec_dma_init(void)
pcm_rec_dma_stop();
} /* pcm_init */
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
- unsigned long addr, end;
-
- int status = disable_fiq_save();
- addr = (unsigned long)pcm_rec_peak_addr;
- end = dma_rec_data.addr;
- restore_fiq(status);
-
- *count = (end >> 2) - (addr >> 2);
- return (void *)(addr & ~3);
+ return (void *)((unsigned long)dma_rec_data.addr & ~3);
} /* pcm_rec_dma_get_peak_buffer */
#endif /* HAVE_RECORDING */
diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c
index f0ef667..9d14fa5 100644
--- a/firmware/target/arm/pcm-telechips.c
+++ b/firmware/target/arm/pcm-telechips.c
@@ -141,8 +141,8 @@ static void play_stop_pcm(void)
void pcm_play_dma_start(const void *addr, size_t size)
{
- dma_play_data.p = (void *)(((uintptr_t)addr + 2) & ~3);
- dma_play_data.size = (size & ~3);
+ dma_play_data.p = addr;
+ dma_play_data.size = size;
#if NUM_CORES > 1
/* This will become more important later - and different ! */
@@ -229,9 +229,8 @@ void pcm_rec_unlock(void)
{
}
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
- *count = 0;
return NULL;
}
diff --git a/firmware/target/arm/s5l8700/pcm-s5l8700.c b/firmware/target/arm/s5l8700/pcm-s5l8700.c
index 1edb05f..7798f41 100644
--- a/firmware/target/arm/s5l8700/pcm-s5l8700.c
+++ b/firmware/target/arm/s5l8700/pcm-s5l8700.c
@@ -367,7 +367,7 @@ void pcm_rec_unlock(void)
{
}
-void pcm_record_more(void *start, size_t size)
+void pcm_rec_dma_record_more(void *start, size_t size)
{
(void)start;
(void)size;
@@ -393,9 +393,9 @@ void pcm_rec_dma_init(void)
}
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
- (void)count;
+ return NULL;
}
#endif /* HAVE_RECORDING */
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index 209d227..f9c0764 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -235,12 +235,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
/* Stop any DMA in progress */
pcm_play_dma_stop();
- addr = (void *)(((long)addr + 3) & ~3);
- size &= ~3;
-
- if (size <= 0)
- return;
-
/* Set up DMA transfer */
SAR0 = (unsigned long)addr; /* Source address */
DAR0 = (unsigned long)&PDOR3; /* Destination address */
@@ -382,12 +376,6 @@ void pcm_rec_dma_start(void *addr, size_t size)
/* stop any DMA in progress */
pcm_rec_dma_stop();
- addr = (void *)(((long)addr + 3) & ~3);
- size &= ~3;
-
- if (size <= 0)
- return;
-
and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL);
/* Start the DMA transfer.. */
@@ -396,7 +384,6 @@ void pcm_rec_dma_start(void *addr, size_t size)
INTERRUPTCLEAR = (1 << 25) | (1 << 24) | (1 << 23) | (1 << 22);
#endif
- pcm_rec_peak_addr = (unsigned long *)addr; /* Start peaking at dest */
SAR1 = (unsigned long)&PDIR2; /* Source address */
DAR1 = (unsigned long)addr; /* Destination address */
BCR1 = (unsigned long)size; /* Bytes to transfer */
@@ -490,30 +477,15 @@ void DMA1(void)
} /* DMA1 */
/* Continue transferring data in - call from interrupt callback */
-void pcm_record_more(void *start, size_t size)
+void pcm_rec_dma_record_more(void *start, size_t size)
{
- start = (void *)(((long)start + 3) & ~3);
- size &= ~3;
-
- pcm_rec_peak_addr = (unsigned long *)start; /* Start peaking at dest */
DAR1 = (unsigned long)start; /* Destination address */
BCR1 = (unsigned long)size; /* Bytes to transfer */
or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
} /* pcm_record_more */
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
- unsigned long addr, end;
-
- /* Make sure interrupt doesn't change the second value after we read the
- * first value. */
- int level = set_irq_level(DMA_IRQ_LEVEL);
- addr = (unsigned long)pcm_rec_peak_addr;
- end = DAR1;
- restore_irq(level);
-
- addr >>= 2;
- *count = (end >> 2) - addr;
- return (void *)(addr << 2);
+ return (void *)(DAR1 & ~3);
} /* pcm_rec_dma_get_peak_buffer */
#endif
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
index a4ecd0b..993f70b 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
@@ -288,13 +288,12 @@ void pcm_rec_unlock(void)
{
}
-const void * pcm_rec_dma_get_peak_buffer(int *count)
+const void * pcm_rec_dma_get_peak_buffer(void)
{
- *count = 0;
return NULL;
}
-void pcm_record_more(void *start, size_t size)
+void pcm_rec_dma_record_more(void *start, size_t size)
{
(void) start;
(void) size;