[alsa-devel] fsl_ssi.c: Getting channel slips with fsl_ssi.c in TDM (network) mode.
Nicolin Chen
nicoleotsuka at gmail.com
Thu Oct 29 19:11:35 CET 2015
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
More information about the Alsa-devel
mailing list