On Thu, Oct 29, 2015 at 07:55:59AM -0700, Caleb Crome wrote:
Therefore, if setting watermark to 8, each FIFO has 7 (15 - 8) space left, the largest safe burst size could be 14 (7 * 2) actually.
Oh, does this depend on the data size? I'm using 16-bit data, so I guess the bursts are measured in 2 byte units? Does this mean that the burst size should be dynamically adjusted depending on word size (I guess done in hw_params)?
You don't need to do that. It's already been taken care in the DMA code.
Okay, so wm=8 and maxburst=14 definitely does not work at all,. wm=8, maxburst=8 works okay, but still not perfect.
Make sure you are using Dual FIFO configurations for both SDMA and SSI. You can refer to my change below (I've tested it with a two- channel test case being played in 44.1KHz 16-bit):
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index b8a5056..f4c7308 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -307,7 +307,7 @@ clocks = <&clks IMX6SX_CLK_SSI1_IPG>, <&clks IMX6SX_CLK_SSI1>; clock-names = "ipg", "baud"; - dmas = <&sdma 37 1 0>, <&sdma 38 1 0>; + dmas = <&sdma 37 22 0>, <&sdma 38 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; status = "disabled"; @@ -321,7 +321,7 @@ clocks = <&clks IMX6SX_CLK_SSI2_IPG>, <&clks IMX6SX_CLK_SSI2>; clock-names = "ipg", "baud"; - dmas = <&sdma 41 1 0>, <&sdma 42 1 0>; + dmas = <&sdma 41 22 0>, <&sdma 42 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; status = "disabled"; @@ -335,7 +335,7 @@ clocks = <&clks IMX6SX_CLK_SSI3_IPG>, <&clks IMX6SX_CLK_SSI3>; clock-names = "ipg", "baud"; - dmas = <&sdma 45 1 0>, <&sdma 46 1 0>; + dmas = <&sdma 45 22 0>, <&sdma 46 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; status = "disabled"; diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 674abf7..7cfe661 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1002,8 +1002,8 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, wm = ssi_private->fifo_depth;
regmap_write(regs, CCSR_SSI_SFCSR, - CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | - CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm)); + CCSR_SSI_SFCSR_TFWM0(8) | CCSR_SSI_SFCSR_RFWM0(8) | + CCSR_SSI_SFCSR_TFWM1(8) | CCSR_SSI_SFCSR_RFWM1(8));
if (ssi_private->use_dual_fifo) { regmap_update_bits(regs, CCSR_SSI_SRCR, CCSR_SSI_SRCR_RFEN1, @@ -1322,8 +1322,9 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, /* 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; + dev_info(&pdev->dev, "tunning burst size for Dual FIFO mode\n"); + ssi_private->dma_params_tx.maxburst = 16; + ssi_private->dma_params_rx.maxburst = 16; }
if (!ssi_private->use_dma) {
And make sure you have the dev_info() printed out in your console. /* 22 in the DT is to call the Dual FIFO SDMA script */
It started with:
frame 0: 00, 00, 10, 20, 30, 40, 50, 60, 70, 80, 90, a0, b0, c0, d0, e0 frame 1: f0, 01, 11, 21, 31, 41, 51, 61, 71, 81, 91, a1, b1, c1, d1, e1
If this happens, just try to let SDMA work before SSI starts to read FIFOs -- enabling TDMAE or RDMAE before enabling TE or RE:
@@ -1093,6 +1093,15 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_update_bits(regs, CCSR_SSI_SIER, + CCSR_SSI_SIER_TDMAE, + CCSR_SSI_SIER_TDMAE); + else + regmap_update_bits(regs, CCSR_SSI_SIER, + CCSR_SSI_SIER_RDMAE, + CCSR_SSI_SIER_RDMAE); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) fsl_ssi_tx_config(ssi_private, true); else fsl_ssi_rx_config(ssi_private, true);
Nicolin