By enabling dual fifo mode, it would allow SSI enter a better performance
to transimit/receive data without occasional hardware underrun/overrun.

[ Passed compile-test with mpc85xx_defconfig ]

Signed-off-by: Nicolin Chen <b42...@freescale.com>
---
 sound/soc/fsl/fsl_ssi.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 3797bf0..7ad01ce 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -146,6 +146,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;
@@ -416,6 +417,16 @@ 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);
+       } else {
+               write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, 0);
+               write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, 0);
+               write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, 0);
+       }
+
        return 0;
 }
 
@@ -952,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);
@@ -1006,6 +1017,17 @@ 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 /= 2;
+                       ssi_private->dma_params_tx.maxburst *= 2;
+                       ssi_private->dma_params_rx.maxburst /= 2;
+                       ssi_private->dma_params_rx.maxburst *= 2;
+               }
        } 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


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to