[Gta04-owner] [PATCH 1/3] OMAP3: McBSP: Change the way how the FIFO is handled
John Ogness
gta04 at ogness.net
Sun Sep 4 15:48:54 CEST 2011
Use the actual FIFO size in words as buffer_size on OMAP3.
Change the threshold configuration to use 1 based numbering, when
specifying the allowed threshold maximum or the McBSP threshold value.
Set the default maximum threshold to (buffer_size - 0x10) intialy.
>From users of McBSP, now it is expected to use this method.
Asking for threshold 1 means that the value written to threshold registers
are going to be 0, which means 1 word threshold.
Signed-off-by: John Ogness <john.ogness at linutronix.de>
---
This is essentially a backport of commit
451fd82dc148bd5ac9ed5b19b6915a1afe32b9cb from mainline.
arch/arm/mach-omap2/mcbsp.c | 10 +++++-----
arch/arm/plat-omap/mcbsp.c | 30 ++++++++++++++++++++----------
sound/soc/omap/omap-mcbsp.c | 29 ++++++++++++++---------------
3 files changed, 39 insertions(+), 30 deletions(-)
commit 1ffb1f4e0fe325796bf8590239965e5e0855f31c
Author: John Ogness <john.ogness at linutronix.de>
Date: Sun Sep 4 15:33:30 2011 +0200
mcbsp: correct fifo sizes and alsa constraints
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index baa4517..bfdb19e 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -128,7 +128,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .buffer_size = 0x6F,
+ .buffer_size = 0x80,
},
{
.phys_base = OMAP34XX_MCBSP2_BASE,
@@ -137,7 +137,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .buffer_size = 0x3FF,
+ .buffer_size = 0x500,
},
{
.phys_base = OMAP34XX_MCBSP3_BASE,
@@ -146,7 +146,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .buffer_size = 0x6F,
+ .buffer_size = 0x80,
},
{
.phys_base = OMAP34XX_MCBSP4_BASE,
@@ -155,7 +155,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .buffer_size = 0x6F,
+ .buffer_size = 0x80,
},
{
.phys_base = OMAP34XX_MCBSP5_BASE,
@@ -164,7 +164,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .buffer_size = 0x6F,
+ .buffer_size = 0x80,
},
};
#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 4a00177..4804076 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -200,9 +200,9 @@ EXPORT_SYMBOL(omap_mcbsp_config);
#ifdef CONFIG_ARCH_OMAP34XX
/*
- * omap_mcbsp_set_tx_threshold configures how to deal
- * with transmit threshold. the threshold value and handler can be
- * configure in here.
+ * omap_mcbsp_set_tx_threshold configures the transmit threshold in words.
+ * The threshold parameter is 1 based, and it is converted (threshold - 1)
+ * for the THRSH2 register.
*/
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
{
@@ -219,14 +219,15 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
mcbsp = id_to_mcbsp_ptr(id);
io_base = mcbsp->io_base;
- OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
+ if (threshold && threshold <= mcbsp->max_tx_thres)
+ OMAP_MCBSP_WRITE(io_base, THRSH2, threshold - 1);
}
EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
/*
- * omap_mcbsp_set_rx_threshold configures how to deal
- * with receive threshold. the threshold value and handler can be
- * configure in here.
+ * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
+ * The threshold parameter is 1 based, and it is converted (threshold - 1)
+ * for the THRSH1 register.
*/
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
{
@@ -243,7 +244,8 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
mcbsp = id_to_mcbsp_ptr(id);
io_base = mcbsp->io_base;
- OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
+ if (threshold && threshold <= mcbsp->max_rx_thres)
+ OMAP_MCBSP_WRITE(io_base, THRSH1, threshold - 1);
}
EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
@@ -1256,8 +1258,16 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
{
mcbsp->dma_op_mode = MCBSP_DMA_MODE_THRESHOLD;
if (cpu_is_omap34xx()) {
- mcbsp->max_tx_thres = max_thres(mcbsp);
- mcbsp->max_rx_thres = max_thres(mcbsp);
+ /*
+ * Initially configure the maximum thresholds to a safe value.
+ * The McBSP FIFO usage with these values should not go under
+ * 16 locations.
+ * If the whole FIFO without safety buffer is used, than there
+ * is a possibility that the DMA will be not able to push the
+ * new data on time, causing channel shifts in runtime.
+ */
+ mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
+ mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
/*
* REVISIT: Set dmap_op_mode to THRESHOLD as default
* for mcbsp2 instances.
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 945f2b6..554ff1b 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -157,9 +157,9 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
/* Configure McBSP internal buffer usage */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, samples - 1);
+ omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, samples);
else
- omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, samples - 1);
+ omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, samples);
}
static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
@@ -175,32 +175,31 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
err = omap_mcbsp_request(bus_id);
if (cpu_is_omap343x()) {
- int dma_op_mode = omap_mcbsp_get_dma_op_mode(bus_id);
int max_period;
/*
- * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer.
+ * McBSP2 in OMAP3 has 1280 word (16-bit) internal audio buffer.
* Set constraint for minimum buffer size to the same than FIFO
* size in order to avoid underruns in playback startup because
* HW is keeping the DMA request active until FIFO is filled.
*/
- if (bus_id == 1)
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- 4096, UINT_MAX);
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
max_period = omap_mcbsp_get_max_tx_threshold(bus_id);
else
max_period = omap_mcbsp_get_max_rx_threshold(bus_id);
-
- max_period++;
max_period <<= 1;
- if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- 32, max_period);
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ max_period, UINT_MAX);
+
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+ 32, max_period);
+
+ /* Make sure, that the period size is always even */
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
}
return err;
More information about the Gta04-owner
mailing list