Currently, I am able to enable SAI0 and play audio at multiples of 48 kHz on it using this device tree overlay:
fragment@4000 {
target = <&sai0>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai0>;
#sound-dai-cells = <0>;
clocks = <&clk IMX8QM_AUD_SAI_0_IPG>,
<&clk IMX8QM_CLK_DUMMY>, // SAI does not have MCLK0 input
<&clk IMX8QM_AUD_SAI_0_MCLK>,
<&clk IMX8QM_CLK_DUMMY>,
<&clk IMX8QM_CLK_DUMMY>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
<&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
<&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
<&clk IMX8QM_AUD_SAI_0_MCLK>;
assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
fsl,sai-asynchronous;
fsl,txm-rxs;
status = "okay";
};
};
I would also like to support multiples of 44.1 kHz. The SAI driver will choose the best MCLK among its 4 MCLK device tree entries, so this should be possible if I add the proper entry to the clocks list.
I tried using IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV (which I have set to be the appropriate frequency in the device tree) for "mclk2". When I try to play at 44.1 kHz, the SAI driver chooses that MCLK and I see that it is turned on and in use in /sys/kernel/debug/clk/clk_summary; however, the SAI hardware does not output anything and eventually ALSA times out with an input/output error.
QUESTIONS:
1. Is it the case that on the i.MX8QM, the SAI functional unit has only one of its 3 MCLK inputs actually connected to a clock source?
2. How can I configure the device tree so that the appropriate MCLK will be provided when requested?
3. Is there a way to have the driver automatically configure the IMX8QM_AUD_SAI_0_MCLK to choose either audio PLL 0 or audio PLL 1 as its source?
Thanks for your help!
Bump! I have similar questions.
Hi mwilliams,
I can play all the 44K1 rates now using PLL 2, check out my post here: https://community.nxp.com/t5/i-MX-Processors/iMX8-SAI-I2S-clock-for-44100-88200-rates/m-p/1525737#M1... particularly this bit respecting the SAI setup.
// 44Ki based rates
// assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
// assigned-clock-rates = <22579200>;
48K based rates
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
assigned-clock-rates = <24576000>;
Most replies I got were already stated in my questions LOL! My headache now, it does not seem to be possbile to have the driver do both 44K1 and 48K based rates on the fly; considering the PLL source is fixed in the device tree and only one can be fed into the driver.
FYI - Copied for another post:
"Clocks 786432000 and 722534400 , respectively configure the output frequency of PLL1 and PLL2, one is an integer multiple of 24.576M, the other is an integer multiple of 22.5792M, then when you need 48K, use PLL1, when 44.1K, use PLL2."
Cheers.
EDIT: Working code using WM8523/4
&sai1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1>;
assigned-clocks = <&clk IMX8MM_CLK_SAI1>;
// assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
// assigned-clock-rates = <22579200>; //45158400 for 352K8 max
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
assigned-clock-rates = <24576000>; // 49152000 for 384K max
status = "okay";
};
Hi Sabine,
I apologize for the late reply.
The Device Tree seems to be correct, you could take a look into device_tree, and check the Linux clock description in devicetree_clock.
Also you could try to change to mclk1 instead of mclk2. You can refer this to chapter 18.1 Audio Clock Mux (ACM) specially 18.2.1.1 Block Diagram.
Regards,
Luis Pérez