Kwiboo / linux-rockchip

Linux kernel for Rockchip SoC
Other
26 stars 10 forks source link

RK3328 : 44.1khz audio do not work after playing 48khz audio #21

Closed Kwiboo closed 7 years ago

Kwiboo commented 7 years ago

44.1khz audio do not work after playing 48khz audio due to use of fractional divider PLL.

Playing 48khz audio clk_i2s0 is using integer divider and audio works as it should

LibreELEC:~ # cat /sys/kernel/debug/clk/clk_summary | grep i2s0
          clk_i2s0_div                    1            1     6144000          0 0
             i2s0_pre                     1            1     6144000          0 0
                clk_i2s0                  1            1     6144000          0 0
             clk_i2s0_frac                0            0     1411200          0 0

Playing 44.1khz audio after 48khz audio clk_i2s0 is using fractional divider and audio do not work

LibreELEC:~ # cat /sys/kernel/debug/clk/clk_summary | grep i2s0
          clk_i2s0_div                    1            1     6144000          0 0
             clk_i2s0_frac                1            1     5644800          0 0
                i2s0_pre                  1            1     5644800          0 0
                   clk_i2s0               1            1     5644800          0 0

The clk_i2s0_div clock is nowhere near the denominator is 20 times larger than numerator recommendation from TRM.

I was able to make a workaround by first setting the clk_i2s0 rate to 49152000, but I am sure there is a much better way to handle this.

Playing 44.1khz audio after 48khz audio using workaround clk_i2s0 is using fractional divider and audio works as it should

LibreELEC:~ # cat /sys/kernel/debug/clk/clk_summary | grep i2s0
          clk_i2s0_div                    1            1    49152000          0 0
             clk_i2s0_frac                1            1     5644800          0 0
                i2s0_pre                  1            1     5644800          0 0
                   clk_i2s0               1            1     5644800          0 0

Workaround patch

index 2c7e5ccca2dc..c8080a8d97e2 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -422,6 +422,11 @@ static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
        struct rk_i2s_dev *i2s = to_info(cpu_dai);
        int ret;

+       /* reset clock */
+       ret = clk_set_rate(i2s->mclk, 49152000);
+       if (ret)
+               dev_err(i2s->dev, "Fail to set mclk %d\n", ret);
+
        ret = clk_set_rate(i2s->mclk, freq);
        if (ret)
                dev_err(i2s->dev, "Fail to set mclk %d\n", ret);
Kwiboo commented 7 years ago

This issue was fixed with https://github.com/rockchip-linux/kernel/commit/a36a1a666f566782eb834c4d8be9efa623b96e02