How to set AUD_MCLK to fixed in L4T 35.5.0

Hardware:
	Jetson AGX Orin based CustomBoard
BSP:
	L4T 35.5.0 

We are using the TLV320AIC3110 as an AUDIO CODEC in AGX Orin based environment.
The Tegra side is operated as Master and the CODEC side as Slave, and MCLK is supplied from the Tegra SoC.

Basic Play/Record is available.
However, during playback, we confirmed that PLL_A_OUT0 and MCLK change dynamically depending on the sampling rate.

・startup

[   33.977991] pll_a_out0 = 45158400 Hz, aud_mclk = 11289600 Hz, sample rate = 44100 Hz

・playing

[   47.195316] pll_a_out0 = 49152000 Hz, aud_mclk = 12288000 Hz, sample rate = 48000 Hz

This seems to be the cause of the noise in sine wave playback, etc.

To change AUD_MCLK to exactly 120000000 Hz with fixed settings, we have already tried the following steps.

AUD_MCLK for Codec SYSCLK
https://docs.nvidia.com/jetson/archives/r35.4.1/DeveloperGuide/text/SD/Communications/AudioSetupAndDevelopment.html#aud-mclk-for-codec-sysclk

[cvb/tegra234-p3737-audio-codec-tlv320aic311x.dtsi]

	tegra_sound: sound {
		compatible = "nvidia,tegra186-ape";
		nvidia-audio-card,name = "NVIDIA Jetson AGX Orin APE";

		clocks = <&bpmp_clks TEGRA234_CLK_PLLA>,
			 <&bpmp_clks TEGRA234_CLK_PLLA_OUT0>,
			 <&bpmp_clks TEGRA234_CLK_AUD_MCLK>;
		clock-names = "pll_a", "pll_a_out0", "extern1";
		assigned-clocks = <&bpmp_clks TEGRA234_CLK_AUD_MCLK>;
		assigned-clock-parents = <&bpmp_clks TEGRA234_CLK_PLLA_OUT0>;
+		assigned-clock-rates = <0>, <12000000>;

		nvidia-audio-card,widgets =
			"Microphone", "TI-TLV320 Microphone Jack",
			"Headphone", "TI-TLV320 Headphone Jack",
			"Speaker", "TI-TLV320 Speaker Left",
			"Speaker", "TI-TLV320 Speaker Right";

		nvidia-audio-card,routing =
			"TI-TLV320 MIC1LP", "TI-TLV320 Microphone Jack",
			"TI-TLV320 MIC1RP", "TI-TLV320 Microphone Jack",
			"TI-TLV320 MIC1LP", "TI-TLV320 MICBIAS",
			"TI-TLV320 MIC1RP", "TI-TLV320 MICBIAS",
			"TI-TLV320 Headphone Jack", "TI-TLV320 HPL",
			"TI-TLV320 Headphone Jack", "TI-TLV320 HPR",
			"TI-TLV320 Speaker Left", "TI-TLV320 SPL",
			"TI-TLV320 Speaker Right", "TI-TLV320 SPR";

		nvidia-audio-card,mclk-fs = <256>;
		status = "okay";
	};

However, as shown below, the assigned-clock-rates do not seem to be reflected.

# speaker-test -c2 -D plughw:APE -twav -l 1

speaker-test 1.2.2

Playback device is plughw:APE
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 32 to 8192
Period size range from 32 to 4096
Using max buffer size 8192
Periods = 4
[  608.887521] pll_a_out0 = 49152000 Hz, aud_mclk = 12288000 Hz, sample rate = 48000 Hz
was set period_size = 2048
was set buffer_size = 8192
 0 - Front Left
 1 - Front Right
Time per period = 2.857470

# cat /sys/kernel/debug/clk/clk_summary | grep aud_mclk
          aud_mclk                                     15       15        0    12287988    12288000          0     0  50000

Could you please tell me how to fix AUD_MCLK at an arbitrary rate?

We have confirmed that AUD_MCLK can be fixed by the following settings.

[cvb/tegra234-p3737-audio-codec-tlv320aic311x.dtsi]

	tegra_sound: sound {
		compatible = "nvidia,tegra186-ape";
		nvidia-audio-card,name = "NVIDIA Jetson AGX Orin APE";

		fixed-pll;
		clocks = <&bpmp_clks TEGRA234_CLK_PLLA>,
			 <&bpmp_clks TEGRA234_CLK_PLLA_OUT0>,
			 <&bpmp_clks TEGRA234_CLK_AUD_MCLK>;
		clock-names = "pll_a", "pll_a_out0", "extern1";
		assigned-clocks = <&bpmp_clks TEGRA234_CLK_AUD_MCLK>;
		assigned-clock-parents = <&bpmp_clks TEGRA234_CLK_PLLA_OUT0>;
		assigned-clock-rates = <12000000>;

		nvidia-audio-card,widgets =
			"Microphone", "TI-TLV320 Microphone Jack",
			"Headphone", "TI-TLV320 Headphone Jack",
			"Speaker", "TI-TLV320 Speaker Left",
			"Speaker", "TI-TLV320 Speaker Right";

		nvidia-audio-card,routing =
			"TI-TLV320 MIC1LP", "TI-TLV320 Microphone Jack",
			"TI-TLV320 MIC1RP", "TI-TLV320 Microphone Jack",
			"TI-TLV320 MIC1LP", "TI-TLV320 MICBIAS",
			"TI-TLV320 MIC1RP", "TI-TLV320 MICBIAS",
			"TI-TLV320 Headphone Jack", "TI-TLV320 HPL",
			"TI-TLV320 Headphone Jack", "TI-TLV320 HPR",
			"TI-TLV320 Speaker Left", "TI-TLV320 SPL",
			"TI-TLV320 Speaker Right", "TI-TLV320 SPR";

		/* nvidia-audio-card,mclk-fs = <256>; */
		status = "okay";
	};

However, the actual rates seem to be as follows.
For aud_mclk, the req_rate is 120000000, but the actual rate is 12287988.

    pll_a                                               1        1        0   294911718   294911718          0     0  50000
       plla_out0                                        1        1        0    49151953    49151953          0     0  50000
          aud_mclk                                     13       13        0    12287988    12000000          0     0  50000

Do we need to change the rate of PLL_A and PLL_A_OUT0?
How can we do that?

We found the following definitions.

[hardware/nvidia/soc/t23x/kernel-dts/tegra234-soc/tegra234-soc-audio.dtsi]

		tegra_axbar: ahub {
			compatible = "nvidia,tegra234-ahub";
			wakeup-disable;
			reg = <0x0 0x02900800 0x0 0x800>;
			clocks = <&bpmp_clks TEGRA234_CLK_AHUB>,
				<&bpmp_clks TEGRA234_CLK_PLLA_OUT0>,
				<&bpmp_clks TEGRA234_CLK_APB2APE>,
				<&bpmp_clks TEGRA234_CLK_APE>;
			clock-names = "ahub", "parent", "apb2ape", "xbar.ape";
			assigned-clocks = <&bpmp_clks TEGRA234_CLK_PLLA>,
					<&bpmp_clks TEGRA234_CLK_PLLA_OUT0>,
					<&bpmp_clks TEGRA234_CLK_AHUB>;
			assigned-parent-clocks =
				<0>,
				<&bpmp_clks TEGRA234_CLK_PLLA>,
				<&bpmp_clks TEGRA234_CLK_PLLP_OUT0>;
			assigned-clock-rates = <294912000>,
						<49152000>,
						<81600000>;
			status = "disabled";

Is “assigned-parent-clocks” a typo?

We found a place in the kernel source where assigned-clock-parents is parsed,
but could not find any place where assigned-parent-clocks is.

./drivers/clk/clk-conf.c:20:	num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
./drivers/clk/clk-conf.c:27:		rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
./drivers/clk/clk-conf.c:137: * listed in its 'assigned-clocks' or 'assigned-clock-parents' properties.
./sound/soc/tegra/tegra_asoc_utils.c:404:	if (!of_find_property(dev->of_node, "assigned-clock-parents", NULL) &&
./sound/soc/tegra/tegra_asoc_utils.c:409:			 "Please update DT to use assigned-clock-parents\n");

Hi,

You need to set the AUD_MCLK parent as PLLP_OUT0 in sound node.

Yes it is a typo, but internally it will be taken care for ahub node.

Hi,

You need to set the AUD_MCLK parent as PLLP_OUT0 in sound node.

We fixed sound node like below.

	tegra_sound: sound {
...
		assigned-clocks = <&bpmp_clks TEGRA234_CLK_AUD_MCLK>;
-		assigned-clock-parents = <&bpmp_clks TEGRA234_CLK_PLLA_OUT0>;
+		assigned-clock-parents = <&bpmp_clks TEGRA234_CLK_PLLP_OUT0>;
-		assigned-clock-rates = <12288000>;
+		assigned-clock-rates = <12000000>;

And confirmed that aud_mclk is fixed accurate 12000000.

# cat /sys/kernel/debug/clk/clk_summary
...
 pllp_out0                                             13       13        0   408000000   408000000          0     0  50000
 *[        default_freq                                       0]
    aud_mclk                                           10       10        0    12000000    12000000          0     0  50000

Thank you for your support.