Jump to content

RK3399 - dts - i2s clocking - need help


Recommended Posts

Hi there.


I have some audio project on different SOM/SOC boards, now my task is to bring an i2s DAC on RK3399. I use external high-quality clock for i2s and need to make the Rockchip the masterclock slave.

This is the case where I find no tail to pull yet, due to VERY cumbersome device tree, poorly documented and poorly explored. For instance, the CPU datasheet says that I2S_MCLK is output only, whilst I could find the opposite in the TRM. Moreover, the clock tree explained there, says that I can use CLKIN_I2S not only for i2s interfaces, but for spdif also!

(Also there is explained some "bitclock slave mode", it's even implemented in the DAI driver, but for my application it's barely usable because of jitter loops introduced by the FPGA.)


Now the question is - HOW. :) I attach the screenshot of the TRM depicting the clock source selection. The clock id I meant above, is 65 here, IO_CLK. Need to find out how these registers are linked together in the DTB!



The second question is related mainly to the driver, I will need a GPIO to switch between x44.1/x48 clock grids, but this looks more feasible than to dig the DTB stuff.


Please assist! Thank you.

Link to comment
Share on other sites

Help Armbian team helping you!


1. /sys/kernel/debug/clk/clk_summary says:

    pll_gpll                              1            1   800000000          0 0
       gpll                              26           34   800000000          0 0
          clk_i2s1_div                    1            1    22222223          0 0
             clk_i2s1_mux                 1            1    22222223          0 0
                clk_i2s1                  2            2    22222223          0 0
                   clk_i2sout_src         0            0    22222223          0 0
                      clk_i2sout          0            0    22222223          0 0
             clk_i2s1_frac                0            0      627199          0 0
          clk_i2s2_div                    0            1   400000000          0 0
             clk_i2s2_frac                0            1    11289600          0 0
                clk_i2s2_mux              0            1    11289600          0 0
                   clk_i2s2               0            1    11289600          0 0
          clk_i2s0_div                    0            0   800000000          0 0
             clk_i2s0_frac                0            0    40000000          0 0
          clk_spdif_rec_dptx              0            1   200000000          0 0


2. According to the Datasheet, GPIO4_A0/I2S_CLK is the clock pin. Out of the box, I see it as Output, and the masterclock is being fed by the RK.

I Need to make it input to "clkin_i2s".


3. No track of "clkin_i2s" found in pinctrl, nor in clk summary. Digging.

Link to comment
Share on other sites

On 4/17/2021 at 4:13 AM, tionebrr said:

It would be great to see your notes in a recap yes.


Actually everything's been done by a kind genius, mr. Zhang from the very Rockchip. He is a very responsive and caring person! I had only to slightly touch the simple-card-utils.c so the driver sets the clock accordingly to the sample rate (there was only fixed multiplier available OOB).


The docs, as I cited above, say nothing on whether clkin_i2s can be an input. Yes, it can, and even on the same pin. We don't even need to mod the code, everything's done in devicetree!

We just have to declare this clock in the DTS, and (in my case) set it as gpio-mux-clock, not a fixed one. This was my insane idea, I didn't believe it could work, but it did. The whole clock tree of this CPU looks beautifully logical, one can do miracles with it, once he catches the idea.

Finally we have a precious hi-end data source for a serious grade DAC. The difference from Sitara that I love is 6 cores, PCIE for m.2 SSD, MIPI for a nice display, and lots of nice peripheria.


So, the DTS:

+       osc45m: osc45m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <45158400>;
+       };
+       osc49m: osc49m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <49152000>;
+       };

        clkin_i2s: clkin_i2s {
-               compatible = "fixed-clock";
+               compatible = "gpio-mux-clock";
                #clock-cells = <0>;
-               clock-frequency = <12288000>;
                clock-output-names = "clkin_i2s";
+               clocks = <&osc45m>, <&osc49m>;
+               select-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;


Link to comment
Share on other sites

On 4/18/2021 at 5:46 PM, cu6apum said:

Uhm well, all those clairvoyants are on vacation right now. Would you please cat /sys/kernel/debug/clk summary here?


So, I wasn't actually testing your latent psychic powers. Mostly just seeing if you had useful notes or resources handy that you could share.


But if you think it'd help, clock summary here: http://ix.io/2WG7


The big issue that I (and a few other boards) have is a bunch of kernel spam every time the system tries to make sound ...


[  176.476379] rockchip-i2s ff890000.i2s: ASoC: error at snd_soc_dai_set_sysclk on ff890000.i2s: -22
[  176.477552] rockchip-i2s ff890000.i2s: Fail to set mclk -22
[  176.478065] rockchip-i2s ff890000.i2s: ASoC: error at snd_soc_dai_set_sysclk on ff890000.i2s: -22
[  181.759856] rockchip-i2s ff890000.i2s: Fail to set mclk -22
[  181.760364] rockchip-i2s ff890000.i2s: ASoC: error at snd_soc_dai_set_sysclk on ff890000.i2s: -22
[  181.762463] rockchip-i2s ff890000.i2s: Fail to set mclk -22
[  181.762961] rockchip-i2s ff890000.i2s: ASoC: error at snd_soc_dai_set_sysclk on ff890000.i2s: -22
[  181.764570] rockchip-i2s ff8a0000.i2s: Fail to set mclk -22
[  181.765069] rockchip-i2s ff8a0000.i2s: ASoC: error at snd_soc_dai_set_sysclk on ff8a0000.i2s: -22


Obviously something wrong with the clock definition in the DTB, and probably in the main RK3399 kernel dts, and may be worth trying to solve for everyone if possible.


Link to comment
Share on other sites

Device Tree: http://ix.io/2WUK


Based on my current understanding, I2S1 (ff890000) is a 3.5 mm audio jack, and I2S2 (ff8a0000) is HDMI.


Sound via HDMI appears to work after fiddling with pulseaudio settings a bit.


I've not gotten anything at all from the audio jack.


I've traced that error here: https://elixir.bootlin.com/linux/v5.10/source/sound/soc/rockchip/rockchip_i2s.c#L427


Unfortunately, my device tree-fu is weak and have not wrapped my head around what's missing in the DTB, or what to do about it.


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...