[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6ee839eec507d6b928beb7c04765acfa9cca8d7a.1384352281.git.b42378@freescale.com>
Date: Wed, 13 Nov 2013 22:55:26 +0800
From: Nicolin Chen <b42378@...escale.com>
To: <vinod.koul@...el.com>, <dan.j.williams@...el.com>,
<s.hauer@...gutronix.de>, <timur@...i.org>, <shawn.guo@...aro.org>,
<broonie@...nel.org>
CC: <linux-arm-kernel@...ts.infradead.org>,
<devicetree@...r.kernel.org>, <linux-doc@...r.kernel.org>,
<linux-kernel@...r.kernel.org>, <dmaengine@...r.kernel.org>,
<linuxppc-dev@...ts.ozlabs.org>, <alsa-devel@...a-project.org>,
<rob.herring@...xeda.com>, <mark.rutland@....com>,
<swarren@...dotorg.org>, <pawel.moll@....com>,
<ijc+devicetree@...lion.org.uk>
Subject: [PATCH v7 3/4] ASoC: fsl_ssi: Add dual fifo mode support
By enabling dual fifo mode, it would allow SSI enter a better performance
to transimit/receive data without occasional hardware underrun/overrun.
Signed-off-by: Nicolin Chen <b42378@...escale.com>
Acked-by: Timur Tabi <timur@...i.org>
Acked-by: Mark Brown <broonie@...aro.org>
---
sound/soc/fsl/fsl_ssi.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 35e2773..f43be6d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -143,6 +143,7 @@ struct fsl_ssi_private {
bool ssi_on_imx;
bool imx_ac97;
bool use_dma;
+ bool use_dual_fifo;
struct clk *clk;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -413,6 +414,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
}
+ if (ssi_private->use_dual_fifo) {
+ write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1);
+ write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1);
+ write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN);
+ }
+
return 0;
}
@@ -480,6 +487,15 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
ssi_private->second_stream = substream;
}
+ /* When using dual fifo mode, it is safer to ensure an even period
+ * size. If appearing to an odd number while DMA always starts its
+ * task from fifo0, fifo1 would be neglected at the end of each
+ * period. But SSI would still access fifo1 with an invalid data.
+ */
+ if (ssi_private->use_dual_fifo)
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
+
return 0;
}
@@ -947,7 +963,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ssi_private->fifo_depth = 8;
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
- u32 dma_events[2];
+ u32 dma_events[2], dmas[4];
ssi_private->ssi_on_imx = true;
ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1001,6 +1017,15 @@ static int fsl_ssi_probe(struct platform_device *pdev)
dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
+ if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
+ && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
+ ssi_private->use_dual_fifo = true;
+ /* When using dual fifo mode, we need to keep watermark
+ * as even numbers due to dma script limitation.
+ */
+ ssi_private->dma_params_tx.maxburst &= ~0x1;
+ ssi_private->dma_params_rx.maxburst &= ~0x1;
+ }
} else if (ssi_private->use_dma) {
/* The 'name' should not have any slashes in it. */
ret = devm_request_irq(&pdev->dev, ssi_private->irq,
--
1.8.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists