IMX8 SAI TDM16 Issue

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

IMX8 SAI TDM16 Issue

跳至解决方案
793 次查看
millark
Contributor III

We are using an IMX8Nano kernel 5.15 custom board and have an issue with TDM16 on SAI5

The issue is that  for a TDM 16 stream, we randomly get channels switching out of step by 8 channels. We have added kernel trace and see the following debug from the fsl_sai driver

if (flags & FSL_SAI_CSR_FEF) {
dev_dbg(dev, "isr: Transmit underrun detected\n");

The driver should perform a FIFO reset in this condition, however this either doesn't happen or has no effect.

The next time the underrun occurs, the channels realign as the step in always 8 channels out in a 16 channel config.

The SAI is in slave mode with only transmit lines activated:

&sai5 {
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai5>;
fsl,dataline = <0 0x00 0xff>;
dmas = <&sdma2 8 24 0>, <&sdma2 9 24 0>;
fsl,txmasterflag = <1>;
status = "okay";
};
 
using the simpl-audio-card f
 
   output1 {
 
        compatible = "simple-audio-card";
        simple-audio-card,name = "SAI51";
simple-audio-card,status="okay";
simple-audio-card,bitclock-master = <&spdif_codec1>;
        simple-audio-card,frame-master = <&spdif_codec1>;
        simple-audio-card,format = "left_j";
               
        cpu1:  simple-audio-card,cpu {
                sound-dai = <&sai5>;
                dai-tdm-slot-num = <16>;
                dai-tdm-slot-width = <32>;
        };
 
        spdif_codec1:  simple-audio-card,codec {
                sound-dai = <&codec_out1>;
        };
        
 
    };
    
   
    codec_out1: 1output_txcodec {
        #sound-dai-cells = <0>;
        #address-cells = <0>;
        #size-cells = <0>;
        compatible = "linux,spdif-dit";
        sound-name-prefix = "spdif_codec1";  
        status = "okay";
    };
 
We have tried a few fixes for this from various posts on line, with no success. 
 
Has anyone else seen such an issue? We assume that this underrun is due the interupt being fired to early hence there is not enough data in the DMA for all channels.

We have no errors in our also playback logs and no errors in TDM8 mode.
 
Any help appreciated.,

 

0 项奖励
回复
1 解答
623 次查看
millark
Contributor III

We have pushed the problem aside. But there are some important lessons learnt here to share with other from a dts perspective:

fsl,dataline = <0 0x00 0xff>;

Be careful with this config if you have specified multiple data lines in the pin mappings. With this config combined with:

  cpu1:  simple-audio-card,cpu {
                sound-dai = <&sai5>;
                dai-tdm-slot-num = <16>;
                dai-tdm-slot-width = <32>;
        };
 
This will create a 32 channel interface as the slot num should reference the number of channels needed per data line not the total number of channels for the SAI interface.
 
Hence we were seeing dma of 64 bit as this was essentially a 32 channel operation and we only needed 16.
 
We switched to a 4 X TDM4 config like below:

4 DATA LINES 

pinctrl_sai5: sai5grp {
fsl,pins = <
MX8MN_IOMUXC_SAI2_MCLK_SAI5_MCLK        0xd6
MX8MN_IOMUXC_SAI2_RXC_SAI5_TX_BCLK 0xd6
MX8MN_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC 0xd6
MX8MN_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0 0xd6
MX8MN_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1 0xd6
MX8MN_IOMUXC_SAI2_TXC_SAI5_TX_DATA2 0xd6
MX8MN_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3 0xd6
>;
};

 

SAI5


&sai5 {

#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai5>;
fsl,dataline = <0 0x00 0xff>;
dmas = <&sdma2 8 24 0>, <&sdma2 9 24 0>;
fsl,txmasterflag = <1>; 
/delete-property/ fsl,shared-interrupt;
status = "okay";
};

 
Card and Codec
 
output1 {
 
        compatible = "simple-audio-card";
        simple-audio-card,name = "SAI51";
simple-audio-card,status="okay";
simple-audio-card,bitclock-master = <&spdif_codec1>;
        simple-audio-card,frame-master = <&spdif_codec1>;
        simple-audio-card,format = "left_j";
               
        cpu1:  simple-audio-card,cpu {
                sound-dai = <&sai5>;
                dai-tdm-slot-num = <4>;
                dai-tdm-slot-width = <32>;
        };
 
        spdif_codec1:  simple-audio-card,codec {
                sound-dai = <&codec_out1>;
        };
        
    };
    
   
    codec_out1: 1output_txcodec {
        #sound-dai-cells = <0>;
        #address-cells = <0>;
        #size-cells = <0>;
        compatible = "linux,spdif-dit";
        sound-name-prefix = "spdif_codec1";  
        status = "okay";
    };

 

Note the slo-num of 4. Each dataline now has 4 channels of data. You will need to use ALSA to map these as we have. We use a dmix to create 8 stereos, the mappings were :

C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
0    4   8    12  1     5    9    13   2   6    10    14   3     7     11     15

The channel count is like this because we didn't enable the fls,multi-lane and disabled shared interrupt

 

Hope this helps someone else.

 

在原帖中查看解决方案

标记 (1)
0 项奖励
回复
7 回复数
624 次查看
millark
Contributor III

We have pushed the problem aside. But there are some important lessons learnt here to share with other from a dts perspective:

fsl,dataline = <0 0x00 0xff>;

Be careful with this config if you have specified multiple data lines in the pin mappings. With this config combined with:

  cpu1:  simple-audio-card,cpu {
                sound-dai = <&sai5>;
                dai-tdm-slot-num = <16>;
                dai-tdm-slot-width = <32>;
        };
 
This will create a 32 channel interface as the slot num should reference the number of channels needed per data line not the total number of channels for the SAI interface.
 
Hence we were seeing dma of 64 bit as this was essentially a 32 channel operation and we only needed 16.
 
We switched to a 4 X TDM4 config like below:

4 DATA LINES 

pinctrl_sai5: sai5grp {
fsl,pins = <
MX8MN_IOMUXC_SAI2_MCLK_SAI5_MCLK        0xd6
MX8MN_IOMUXC_SAI2_RXC_SAI5_TX_BCLK 0xd6
MX8MN_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC 0xd6
MX8MN_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0 0xd6
MX8MN_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1 0xd6
MX8MN_IOMUXC_SAI2_TXC_SAI5_TX_DATA2 0xd6
MX8MN_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3 0xd6
>;
};

 

SAI5


&sai5 {

#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai5>;
fsl,dataline = <0 0x00 0xff>;
dmas = <&sdma2 8 24 0>, <&sdma2 9 24 0>;
fsl,txmasterflag = <1>; 
/delete-property/ fsl,shared-interrupt;
status = "okay";
};

 
Card and Codec
 
output1 {
 
        compatible = "simple-audio-card";
        simple-audio-card,name = "SAI51";
simple-audio-card,status="okay";
simple-audio-card,bitclock-master = <&spdif_codec1>;
        simple-audio-card,frame-master = <&spdif_codec1>;
        simple-audio-card,format = "left_j";
               
        cpu1:  simple-audio-card,cpu {
                sound-dai = <&sai5>;
                dai-tdm-slot-num = <4>;
                dai-tdm-slot-width = <32>;
        };
 
        spdif_codec1:  simple-audio-card,codec {
                sound-dai = <&codec_out1>;
        };
        
    };
    
   
    codec_out1: 1output_txcodec {
        #sound-dai-cells = <0>;
        #address-cells = <0>;
        #size-cells = <0>;
        compatible = "linux,spdif-dit";
        sound-name-prefix = "spdif_codec1";  
        status = "okay";
    };

 

Note the slo-num of 4. Each dataline now has 4 channels of data. You will need to use ALSA to map these as we have. We use a dmix to create 8 stereos, the mappings were :

C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
0    4   8    12  1     5    9    13   2   6    10    14   3     7     11     15

The channel count is like this because we didn't enable the fls,multi-lane and disabled shared interrupt

 

Hope this helps someone else.

 

标记 (1)
0 项奖励
回复
738 次查看
JorgeCas
NXP TechSupport
NXP TechSupport

Hello,

If you reduce the bit rate, does the error happen?

Best regards.

0 项奖励
回复
662 次查看
millark
Contributor III

So we have tested with 16bit audio and so far no errors. We will keep the test running on soak as it has only been a few hours. We can't use this in production, but an interesting test,

I guess this makes sense as the DMA controller is 32bit so for 32bit audio data at 16ch we are talking about 64bits of audio per sample, which will use two DMA slots, for an underrun the fifo gets out of sync by 1, representing half the data hence the 8 channel switch. 

We need to understand now about the fifo reset in 32bit mode when an underrun occurs and why this has no affect, I assume as it only clears 32bits of data and not the 64bits relating to a full sample.  Also as to why these underruns occur and why the dma interrupts can't keep up with the system.

0 项奖励
回复
645 次查看
JorgeCas
NXP TechSupport
NXP TechSupport

Hello,

Thank you for the update.

Just to confirm, please verify that the Transmit Channel Enable bit of SAI Transmit Configuration 3 Register (TCR3) is enabled for your design.

Best regards.

0 项奖励
回复
722 次查看
millark
Contributor III

I am not able to reduce the bit rate in this current test environment, as the audio being piped via alsa is fixed and the receiving end codec (clck src) is also fixed. I will try and test another way.

As an update, we set the clocks in master mode thinking it may have been related to clock stability when in slave mode, this had no affect.

We are running a dmix plugin in alsa that mixes the 16ch to 8 X 2ch and are now investigating there.

0 项奖励
回复
720 次查看
millark
Contributor III

We have ruled out DMIX itself as it also happens with other Alsa plugins like DSHARE

0 项奖励
回复
790 次查看
millark
Contributor III
We have no errors in our alsa playback logs and no errors in TDM8 mode.
0 项奖励
回复