Hi,
I am trying to use an external clock of 22579200 Hz on CLK_EXT3 Ball AG11 of an iMX8MM
This clock is supposed to provide the clock to SAI3 and SPDIF modules
Unfortunately the board freeze once it try to change the clock parent
This is pretty close to the thread : https://community.nxp.com/thread/496566
Here is my relevant dts declarations :
clocks {
clk_ext3: clock@4 {
compatible = "fixed-clock";
reg = <5>;
#clock-cells = <0>;
clock-frequency = <22579200>;
clock-output-names = "clk_ext3";
};
};
captina: captina {
compatible = "cp,captina";
#sound-dai-cells = <0>;/* simple-card needs */
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
clock-names = "mclk";
};
sound-captina {
compatible = "simple-audio-card";
simple-audio-card,name = "captina Card";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
/* Switch between Right and Left channels */
simple-audio-card,frame-inversion;
simple-audio-card,widgets =
"Line", "Line Out Jack",
"Line", "Line In Jack";
simple-audio-card,routing =
"Line Out Jack", "LOUT",
"Line Out Jack", "ROUT",
"LIN", "Line In Jack",
"RIN", "Line In Jack";
dailink0_master: simple-audio-card,cpu {
sound-dai = <&sai3>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
simple-audio-card,codec {
sound-dai = <&captina>;
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
clock-names = "mclk";
};
};
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
spdif-controller = <&spdif1>;
spdif-out;
spdif-in;
};
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
/* RXFS have to be tri state since TXFS also play on the same wire */
MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0xd6
/* MCLK input from oscillator */
MX8MM_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3 0x00000011
>;
};
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
#sound-dai-cells = <0>;/* simple-card needs */
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_CLK_EXT3>;
assigned-clock-rates = <22579200>;
status = "okay";
};
&spdif1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spdif1>;
assigned-clocks = <&clk IMX8MM_CLK_SPDIF1>;
assigned-clock-parents = <&clk IMX8MM_CLK_EXT3>;
assigned-clock-rates = <22579200>;
clocks = <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_24M>,
<&clk IMX8MM_CLK_SPDIF1>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk IMX8MM_AUDIO_PLL2_OUT>;
clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3",
"rxtx4", "rxtx5", "rxtx6", "rxtx7", "spba", "pll8k", "pll11k";
status = "okay";
};
when sai3 and spdif have their assigned-clock-parents like this :
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
The system doesn't freeze, but they are not sync on clk_ext3
Thank you by advance if you have any reference, any hints, any help, anything
Regards
Aurelien BOUIN
Solved! Go to Solution.
Hi Patrick,
I have applied the following patch in order to use CLK_EXT3 as SAI3 source in a i.MX8MM EVK:
http://code.bulix.org/vst00z-1125422
Kernel booted without any hang.
Please note that I have disabled the camera because on i.MX8MM EVK the GPIO1_IO06 pin is used as camera reset originally. Make sure there is no pin conflit on your dts as well.
Another experiment we did was to boot the kernel without supplying the EXT_CLK3 clock. In this case the kernel hangs and as soon as we turn on the external clock generator, then the boot proceeds.
So we see the same behavior in U-Boot and kernel: the clock switch is successful as long as EXT_CLK3 is present. If it is not present, then the system hangs.
Regards,
Fabio Estevam
Hi,
we also use EXT_CLK3 on imx8mm for our SAI clock. We have done the following:
That was all to get it to work together with SAI5 and SAI6.
Regards,
Wolfgang
Hi Aurelien
one can try to debug it in the same way as in GPT capture sample on M4 seems to hang on Linux boot
clk-imx8mm.c\imx\clk\drivers - linux-imx - i.MX Linux kernel
Just for test remove "simple-audio-card" and leave clk_ext3 at default clock-frequency = <133000000>;
as it is done in original dts
fsl-imx8mm.dtsi\freescale\dts\boot\arm64\arch - linux-imx - i.MX Linux kernel
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Igor,
Thank you for your support
Unfortunately disabling in my dts the clock part for clk_ext3, spdif and disabing the sound component doesn't change anything, the kernel still hang, this is what looks my device tree now :
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
/* RXFS have to be tri state since TXFS also play on the same wire */
MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0xd6
/* MCLK input from oscillator */
MX8MM_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3 0x00000011
>;
};&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
#sound-dai-cells = <0>;/* simple-card needs */
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_CLK_EXT3>;
assigned-clock-rates = <22579200>;
status = "okay";
};
Thank you by advance if you have any reference, any hints, any help, anything
Regards
Aurelien BOUIN
Hi Aurelien
one can try to debug and find where it hangs using
AN4553 Using Open Source Debugging Tools for Linux on i.MX Processors
https://www.nxp.com/docs/en/application-note/AN4553.pdf
Best regards
igor
Hi Igor,
Thank you for pointing me to this problem which is a bit different, the M4 hang when the linux boot because the linux is touching some registers used by the M4
In my case it is a lot more simpler, what I want to do is just use EXT_CLK3 as MCLK for SAI3 & SPDIF1 modules
I have try several things :
1. I have tested to modify the code into drivers/clk/imx/clk-imx8mm.c, adding thoses lines :
pr_info("i.MX8MM clock driver before setting CLK_EXT3");
clk_set_parent(clks[IMX8MM_CLK_SAI3], clks[IMX8MM_CLK_EXT3]);
clk_set_parent(clks[IMX8MM_CLK_SPDIF1], clks[IMX8MM_CLK_EXT3]);
pr_info("i.MX8MM clock driver after setting CLK_EXT3");
#just before :
imx_register_uart_clocks(uart_clks);
pr_info("i.MX8MM clock driver init done\n");
Unfortunately the iMX is hanging directly ... :
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 4.19.35-rt20-rc1 (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP PREEMPT RT Wed Jan 29 15:01:49 UTC 2020
[ 0.000000] Machine model: FSL i.MX8MM Emperor board id 1
[ 0.000000] earlycon: ec_imx6q0 at MMIO 0x0000000030890000 (options '115200')
2. I have change dts SAI3 and SPDIF1 part to use
captina: captina {
compatible = "cp,captina";
#sound-dai-cells = <0>;/* simple-card needs */
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
clock-names = "mclk";
};
sound-captina {
compatible = "simple-audio-card";
simple-audio-card,name = "captina Card";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
/* Switch between Right and Left channels */
simple-audio-card,frame-inversion;
simple-audio-card,widgets =
"Line", "Line Out Jack",
"Line", "Line In Jack";
simple-audio-card,routing =
"Line Out Jack", "LOUT",
"Line Out Jack", "ROUT",
"LIN", "Line In Jack",
"RIN", "Line In Jack";
dailink0_master: simple-audio-card,cpu {
sound-dai = <&sai3>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
simple-audio-card,codec {
sound-dai = <&captina>;
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
clock-names = "mclk";
};
};
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
spdif-controller = <&spdif1>;
spdif-out;
spdif-in;
};pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
/* RXFS have to be tri state since TXFS also play on the same wire */
MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0xd6/* MCLK input from oscillator */
MX8MM_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3 0x00000011
>;
};&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
#sound-dai-cells = <0>;/* simple-card needs */
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
assigned-clock-rates = <22579200>;
status = "okay";
};&spdif1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spdif1>;
assigned-clocks = <&clk IMX8MM_CLK_SPDIF1>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
assigned-clock-rates = <22579200>;
clocks = <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_24M>,
<&clk IMX8MM_CLK_SPDIF1>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
<&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk IMX8MM_AUDIO_PLL2_OUT>;
clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3",
"rxtx4", "rxtx5", "rxtx6", "rxtx7", "spba", "pll8k", "pll11k";
status = "okay";
};
The iMX8 boot without any problem, and I can play sound without troubles
I then check the pin muxing which actually was correct
Pages RM 1330 : IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO06
sudo memtool -32 0x30330040 1
return : 00000006
=>ALT6 => CCM_EXT_CLK3
Pages RM 1492 : IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO06
sudo memtool -32 0x303302A8 1
return : 00000011
Then I check
CCM_TARGET_ROOTn : page RM 487
CCM_TARGET_ROOT_SAI3 : page RM 411
Trying to set-up dynamically the source from audio_pll2 into ext_mlck does the same and freeze the linux :
When first read : when audio is in idle mode :
sudo memtool -32 0x3038a680 1
return : 0200001F
When first read : when audio is in playing mode :
sudo memtool -32 0x3038a680 1
return : 1200001F
When I force to use ext_clk3 :
sudo memtool -32 0x3038a680=0x0600001F
linux freeze ...
So I wonder if you have already get any work done with ext_clkX pins ?
Thank you by advance if you have any other reference, any hints, any help
Regards
Aurelien BOUIN
Hi Aurelien
one can try bit GPR_SAI3_EXT_MCLK_EN in IOMUXC_GPR_GPR2 register
Best regards
igor
Hello Igor,
This is something i already have patched without sucess, here is my patch into sound/soc/fsl/fsl_sai.c :
+static void display_gpr_register_value(struct platform_device *pdev, struct regmap *gpr, unsigned int reg)+{+ unsigned int value_read;+ regmap_read(gpr, reg, &value_read);+ dev_dbg(&pdev->dev, "gpr[0x%08X]=0x%016X\n", reg, value_read);+}+static int fsl_sai_probe(struct platform_device *pdev){struct device_node *np = pdev->dev.of_node;@@ -1481,6 +1509,52 @@ static int fsl_sai_probe(struct platform_device *pdev)fsl_sai_dai.symmetric_samplebits = 0;}+ if (of_find_property(np, "fsl,sai-use-ext-mclk", NULL)) {+ struct device_node *node;+ struct regmap *gpr;+ unsigned int reg_value;+ phandle phandle;+ u32 out_val[1];++ dev_dbg(&pdev->dev, "Enable External MCLK for SAI\n");+ /* The MCLK pin is an input that provide the clock to the sai */+ sai->use_external_mclk = true;+ /*+ * only for SAI3 for now+ */++ ret = of_property_read_u32_array(np, "gpr-ptr", out_val, 1);+ if (ret) {+ dev_dbg(&pdev->dev, "no gpr-ptr property\n");+ return -EINVAL;+ }+ phandle = *out_val;+ node = of_find_node_by_phandle(phandle);++ if (!node) {+ dev_dbg(&pdev->dev, "could not find gpr node by name\n");+ return -EINVAL;+ }+ gpr = syscon_node_to_regmap(node);+ if (IS_ERR(gpr)) {+ dev_dbg(&pdev->dev, "could not find gpr regmap\n");+ return PTR_ERR(gpr);+ }+ of_node_put(node);+ reg_value = BIT(2);+ display_gpr_register_value(pdev, gpr,IOMUXC_GPR2);+ /* Enable External MCLK for SAI */+ regmap_update_bits(gpr, IOMUXC_GPR2, reg_value,+ reg_value);+ display_gpr_register_value(pdev, gpr,IOMUXC_GPR2);+ /* GPR_SAI3_SEL1 to 1 into GPR7*/+ display_gpr_register_value(pdev, gpr,IOMUXC_GPR7);+ reg_value = BIT(5);+ regmap_update_bits(gpr, IOMUXC_GPR7, reg_value,+ reg_value);+ display_gpr_register_value(pdev, gpr,IOMUXC_GPR7);+ }+if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
Adding the variable into sound/soc/fsl/fsl_sai.h :
+++ b/sound/soc/fsl/fsl_sai.h@@ -261,6 +261,7 @@ struct fsl_sai {bool synchronous[2];bool is_stream_opened[2];bool is_dsd;+ bool use_external_mclk;
And add into the device tree &sai3 part :
fsl,sai-use-ext-mclk;/* custom handle */gpr-ptr = <&gpr>;
Still no luck !
We are currently in hardware remake ... so if you have any suggestion to get to our goal :
We want to run SPDIF TX and SAI3 Rx/Tx from the same external clock source
Per the documentation we can use EXT_CLK_3 to do this using ball EXT_CLK_3 ( GPIO1_IO06) on ball AG11
How can we get this clock to work – or is there an alternate clock input we can use to synchronize SPDIF_TX and SAI3 I2S. We want the clocks to be locked without using SRC or having any buffer slip issues with slight sample rate mismatches
Thank you again for your support,
Best regards,
Aurelien BOUIN
Albeit some time ago since you posted this reply, your code snippet has really helped me crack a similar problem!
Cheers.
Glad it helped !
Hi @Aurelien_BOUIN,
Still trying to crack it but your code really helped! Just trying to get the device tree on SAI1 behaving..
Hi Igor,
I have also tested without any success to set-up muxing for EXT_CLK3 GPIO1_IO06 into u-boot, to be sure that the muxing is correct before any clock adjustment
I guess at NXP/Freescale you have tested this feature, is there any application note ? example of implementation of external clock ? is it a hardware bug ?
Thank you for your feedback Igor,
Best Regards,
Aurelien BOUIN
Hi Aurelien,
If you do this in U-Boot:
mw.l 0x30330040 0x16
mw.l 0x3038a680 0x06000000
Do you get the system to hang?
Regards,
Fabio Estevam
Hi Fabio,
Just tested and yes the system also hang
Regards,
Aurelien BOUIN
Hi Aurelien,
We have reworked our i.MX8MM EVK so that we could inject a 20MHz clock from a clock generator into CLK_EXT3 and we ran the following commands in the U-Boot prompt:
=> mw.l 0x30330040 0x6
=> mw.l 0x3038a680 0x06000000
The results are:
1. When the CLK_EXT3 is present the clock switch happens successfully and the system does not hang
2. If we cut the CLK_EXT3 clock the system hangs.
Please double check your CLK_EXT3 circuitry and make sure the clock is being provided correctly. We suspect that the CLK_EXT3 clock is not being generated correctly on your board.
On the i.MX8MM EVK the NVCC_GPIO is at 1.8V, so the clock signal we provided at CLK_EXT3 has 1.8V amplitude.
Regards,
Fabio Estevam
Hello Fabio,
Here is an attached screenshot of our clock going into GPIO6:
GPIO6 after rework and after setting sudo memtool -32 0x30330040=0x6
So we know our clock is hooked up and is getting a clean signal. Then here is a step by step setting of the values so you can see when it hangs:
As far as we can tell, the only difference between our setup and yours is that we are running our GPIO on 3.3V logic and yours is 1.8V.
Please advise.
Grant
Fabio,
I tried doing the same thing but this time lowering the clock signal down to 1.8V logic. See here:
Probing GPIO6:
And here is the commands 1 by 1:
Still no luck! NVCC_GPIO1 is 3.3V on our board. This seems to be the only difference in our setups.
Grant
Fabio,
I will try from U-Boot as you suggested now.
Grant
Hi Grant,
I got notification of your reply below by e-mail, but did not see it here:
"It takes the commands in U-Boot but then once I try to boot when these registers are set the system hangs. See the attached file showing where our system hangs."
However, on Friday Aurelien reported that the U-Boot commands caused the system to hang.
What has changed in the hardware that caused U-Boot to not hang?
I want to make sure I understand the issue and the tests that are being made.
Thanks @Fabio. Grant is referring to is simply pausing autoboot, then manually setting the registers in uboot. If you see his log, you will see that when he finally does resume boot, he does experience the hang. This matches aurelihein's experience. Now that we have replicated your 1.8V clocking amplitude, and still get the hang, it would be good for us to see your source code and a build of what you are using so we can baseline-reference and attempt to replicate a working externally clocked SPDIF/SAI3. Is it possible for us to see your source and a binary image?
Hi Patrick,
I haven't tried to boot Linux with EXT_CLK3. Only tested switching SAI3 clock from U-Boot.
Will do it tomorrow and will let you know how it goes.