About SAI multi-lane mode and fsl_sai.c

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

About SAI multi-lane mode and fsl_sai.c

Jump to solution
1,203 Views
Takashi_Kashiwagi
Senior Contributor I
Hi Community and NXP TechSupport
 
I have using IMX8M Plus with yocto (kernel 5.15).
 
I would like to operate SAI1 in multi-lane mode using TXD0~7 and RXD0~7, but no signal is output from TXD0~7.
Also, when I set it to be used only for TXD0 and RXD0, the signal was output correctly from TXD0.
 
So I have some questions about the dts file, SAI's registers and fsl_sai.c. 
 
Q1. I set "fsl,sai-multi-lane" and "fsl,dataline" (not fsl,dataline,dsd) as follows. This option works, right?
```
&sai1 {
~~~
fsl,sai-multi-lane;
fsl,dataline = <0 0xFF 0xFF>;
fsl,sai-asynchronous;
~~~
};
```
Q2. Is there a dts file in which "fsl, sai-multi-lane" and "fsl, dataline" are working correctly (or used when verifying the operation of TXD0~7)?
I searched for https://github.com/nxp-imx/linux-imx/blob/lf-5.15.y but couldn't find it.
 
Q3. Is the value specified for the member variable "slots" of struct fsl_sai defined in fsl_sai.c 2 (=number of WORDs per lane)?
Or is it 16 (= total number of WORDs)?
 
Q4. When fsl,sai-multi-lane is specified, fsl_sai_hw_params sets FCOMB=0. What is your intention with this?
 
 
I would like to operate SAI1 under the following conditions.
* slave mode(TXFS, TXC, RXFS and RXC are provided by external custom codec)
* WORD LENGTH = 32bit
* Frequency = 48~768KHz
* format = left_j
* Channel = 16ch
* Lane = 8 (TXD0~7/RXD0~8)
* Slots per lane = 2
 
Also, the registers after executing fsl_sai_hw_params were as follows.
FSL_SAI_TCR1= 0x00000070
FSL_SAI_TCR2= 0x02000000
FSL_SAI_TCR3= 0x00FF0000
FSL_SAI_TCR4= 0x00011F30
FSL_SAI_TCR5= 0x1F1F1F00
FSL_SAI_TMR= 0xFFFFFFFC
 
Best Regards,
KASHIWAGI Takashi
0 Kudos
Reply
1 Solution
1,095 Views
Takashi_Kashiwagi
Senior Contributor I

Hi @JorgeCas san and community!

 

I've come to a good workaround, so I'll share it with you.

 

  • If you operate SAI multi-lane in TDM format, do not set "fsl,sai-multi-lane".device tree file as follows.

 

&sai1 {
	~~~
	//fsl,sai-multi-lane; do not set!!
	fsl,dataline = <8 0xFF 0xFF>;
	fsl,sai-asynchronous;
	~~~
};

 

 

Also, the data output when using alsalib(snd_pcm_writei) is as follows.
TXD0 = CH1/CH9
TXD1 = CH2/CH10
TXD2 = CH3/CH11
TXD3 = CH4/CH12
TXD4 = CH5/CH13
TXD5 = CH6/CH14
TXD6 = CH7/CH15
TXD7 = CH8/CH16
If necessary, you may want to swap it yourself or use channel mapping.

 

About "fsl,sai-multi-lane":
When "fsl,sai-multi-lane" is enabled, fsl_sai_hw_params() disables SAI's FIFO Combine Mode. If FCOMB is disabled, each register (TDR[0~7]/RDR[0~7]) must be accessed to read or write data. However, at least in If-5.15-y, the driver seems to only access TDR[0]/RDR[0].

 

Best Regards,

KASHIWAGI Takashi

View solution in original post

0 Kudos
Reply
7 Replies
1,159 Views
Takashi_Kashiwagi
Senior Contributor I

@JorgeCas san

 

Thank you for reply!

Thank you for the helpful information. Also, could you please answer Q1, Q2, Q3, and Q4?

 

I suggest you take a look on next thread.

As mentioned in this thread, when I enabled FCOMB as follows, data was now output to TXD0~7 via snd_pcm_writei(alsalib).

if (__sw_hweight8(dl_cfg[dl_cfg_idx].mask[tx]) <= 1 || sai->is_multi_lane)
    regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
        FSL_SAI_CR4_FCOMB_MASK, 0);
else
     regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
        FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT);
 
+if(sai->is_multi_lane)
+{
+    regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT);
+}

The order of the data was as follows. 
TXD0 - CH1, CH9
TXD1 - CH2, CH10
TXD2 - CH3, CH11
TXD3 - CH4, CH12
TXD4 - CH5, CH13
TXD5 - CH6, CH14
TXD6 - CH7, CH15
TXD7 - CH8, CH16

By the way, is this the correct way to handle FCOMB when fsl,sai-multi-lane is enabled?.

Are the problems pointed out in "Configuring-SAI-for-I2S-multi-line-with-linux" had not fixed?

* sbouthillier san says (in "Configuring-SAI-for-I2S-multi-line-with-linux"):

* The SAI driver is configured with 8 channels, a frame sync width of 32 bits, 2 words per frame and a word size of 32 bits. The driver is enabling the correct number of transmit channels (TCE) based on the number of channels and frame size, but it looks like only the FIFO of TXD0 is serviced by the DMA.

* I see in fsl_sai.c that there is some parameters (undocummented) that can be configured in the devicetree, fsl,sai-multi-lane and fsl,dataline.
In fsl_sai_hw_params(), when fsl,sai-multi-lane is set in the devicetree, the FIFO combine mode is disabled and the DMA seems to be configured differently.
What are these parameters for exactly?

 

ALSAhas a asound.conf file, and it has some ways to split and/or join audio cards.

Thank you for the information about aredord/aplay!

For now, our application calls alsalib's snd_pcm_writei/readi directly. I will refer to it later if I need it.

 

Best Regards,

KASHIWAGI Takashi

0 Kudos
Reply
1,140 Views
JorgeCas
NXP TechSupport
NXP TechSupport

Hello,

Q1.

Please refer to fsl-sai.txt.

Q2.

On our EVK reference designs there is no working examples of this type of applications using "fsl, sai-multi-lane" and "fsl, dataline".

Q3.

It should be the total number of WORDs.

Q4.

I suggest you take a look on SAI Transmit Configuration 4 Register (TCR4) and SAI Receive Configuration 4 Register (RCR4) of reference manual and the next link.

Best regards.

0 Kudos
Reply
1,128 Views
Takashi_Kashiwagi
Senior Contributor I

Hi @JorgeCas san

Thank you for answering my question.
 
I think I have a little idea where the problem is.
 
Apparently fsl_sai_hw_params does not need to disable FCOMB when not in DSD mode. However, the modified code disables FCOMB even when not in DSD mode.
 
In If-6.1y, the part where "sai->is_multi_lane" was referenced in the if statement was replaced with "sai->is_multi_fifo_dma".
 
In If5.15-y, multi-lane does not seem to work due to the addition of "MLK-16224-4: ASoC: fsl_sai: support multi fifo and DSD". 
As far as fsl_sai.c of If-6.1y is concerned, it seems that all I need to do is delete the part that disables FCOMB in "if(sai->is_multi_lane)" and the part related to sai->audio_config, have you other workarounds?
 
Or is it possible to get advice from committer Shengjiu Wang san?
 
 
 
 
[detail]
> Q1. Please refer to fsl-sai.txt.
> Q2. On our EVK reference designs there is no working examples of this type of applications using "fsl, sai-multi-lane" and "fsl, dataline".
I understand. However, the "i.MX 8M Plus Applications Processor Reference Manual" states that "SAI1 supports to up to 8 I2S/TDM Tx lanes and 8 I2S/TDM Rx lanes at 768kHz/32-bit". (How did NXP engneers check that it worked...?)
 
 
> Q3. It should be the total number of WORDs.
If so, when I set slots = 16, fsl_sai_hw_params sets pins to 1 on line 552.
I would like to use TXD0-7. In that case, the variable "pins" should be "8".
In this case(= total number of WORDs), the intended number of lanes will not be set. (Which option should I use to set the number of lanes?)
 
> Q4. I suggest you take a look on SAI Transmit Configuration 4 Register (TCR4) and SAI Receive Configuration 4 Register (RCR4) of reference manual and the next link.
I checked it and fsl_sai.c commit history.
Here's what I noticed:
* "fsl,fcomb-mode" seems to be an option that no longer exists.
> Usually, if mapping is TX0 and TX1, that will be easy for SAI and SDMA to handle, that SAI can use the FIFO combine mode, SDMA can use the normal script.
> so for DSD:
> 1. The SDMA should use the multi-fifo script, and SAI can'tuse the FIFO combine mode.
This commit fixes FCOMB to disable when sai->is_multi_lane=true. This is inconsistent with the commit comment. 
 
 
--
 
Best regards.
KASHIWAGI Takashi

 

 

0 Kudos
Reply
1,096 Views
Takashi_Kashiwagi
Senior Contributor I

Hi @JorgeCas san and community!

 

I've come to a good workaround, so I'll share it with you.

 

  • If you operate SAI multi-lane in TDM format, do not set "fsl,sai-multi-lane".device tree file as follows.

 

&sai1 {
	~~~
	//fsl,sai-multi-lane; do not set!!
	fsl,dataline = <8 0xFF 0xFF>;
	fsl,sai-asynchronous;
	~~~
};

 

 

Also, the data output when using alsalib(snd_pcm_writei) is as follows.
TXD0 = CH1/CH9
TXD1 = CH2/CH10
TXD2 = CH3/CH11
TXD3 = CH4/CH12
TXD4 = CH5/CH13
TXD5 = CH6/CH14
TXD6 = CH7/CH15
TXD7 = CH8/CH16
If necessary, you may want to swap it yourself or use channel mapping.

 

About "fsl,sai-multi-lane":
When "fsl,sai-multi-lane" is enabled, fsl_sai_hw_params() disables SAI's FIFO Combine Mode. If FCOMB is disabled, each register (TDR[0~7]/RDR[0~7]) must be accessed to read or write data. However, at least in If-5.15-y, the driver seems to only access TDR[0]/RDR[0].

 

Best Regards,

KASHIWAGI Takashi

0 Kudos
Reply
290 Views
gigli_korg
Contributor II


Hi Takashi Kashiwagi san,

as far I am developing audio application on our custom iMX(MP board, I am facing with multi-lane SAI peripheral problmems.
I found interesting this post and I ask to you what is the SoundCard driver ("simple-audio-card", "imx-audio-card", ... ) that have you used and how you have descriobed the links between the "cpu" side and the "codec" side (if any).

Thanks in advance

Best Regads

Stefano Gigli

0 Kudos
Reply
1,087 Views
JorgeCas
NXP TechSupport
NXP TechSupport

Great! Thank you for the feedback.

Best regards.

0 Kudos
Reply
1,166 Views
JorgeCas
NXP TechSupport
NXP TechSupport

Hello, I hope you are doing well.

I suggest you take a look on next thread.

Also, I was researching internally, and it seems that it is possible to use ALSA to control all playback. It is one of possible ways (maybe easiest way to do it).

ALSAhas a asound.conf file, and it has some ways to split and/or join audio cards.

In ALSA, customer can define its card and codec in kernel (dts and all config files). Then create a asound.conf in /etc.

In asound.conf, create a audio card and then, using an ALSA virtual device for each output (stereo or mono) via "dshare" propriety. So, ALSA is reponsable to produce all data that will be send through SAI (via driver), but all sequence of sound or empties slots will be dealed by ALSA in user space, so you don need to include this sequence of channels and its control on driver.

For dshare, customer can check for examples at:

AlsaProject

Alsa Opensrc Org - Independent ALSA and linux audio support site

With asound.conf, customer can check if devices are ok, using:

 

aplay -L

 

To play independently different sources, customer can use:

 

aplay -Dplug:name_of_dshare_card name_of_file

 

In order to play more than one file, use a sequence of parallel execution aplay xxx & aplay xxx & (...). For example if in config file it was defined outputs, you can use:

 

aplay -Dplug:output1 audio1.wav & aplay -Dplug:output2 audio2.wav & aplay -Dplug:output3 audio3.wav

 

It will play 3 different audio files in three different virtual devices that can be at same SAI.

Best regards.

0 Kudos
Reply