Re: [PATCH] clk: rockchip: rk3588: let MCLK_SPDIF* rate requests reach the divider
Karl Asseily <[email protected]>
| Newsgroups | org.infradead.lists.linux-rockchip,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-clk,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CA+gvwbo2Brc+JLBZZxn03OyD51=7hw3-j08-5x4YoXG2Cx1z9g@mail.gmail.com> |
Please drop this patch. It is a no-op and my analysis was wrong. rockchip_clk_register_branch() adds CLK_SET_RATE_PARENT to every branch_gate at registration: case branch_gate: flags |= CLK_SET_RATE_PARENT; so the MCLK_SPDIF* gates already propagate and the flags column in the branch table makes no difference. The behaviour I was chasing was real, but the cause is elsewhere: simple-audio-card only calls the CPU DAI's set_sysclk() when the card node has an mclk-fs property, and rk_spdif_set_sysclk() is the only caller of clk_set_rate() in the S/PDIF path. Without mclk-fs no rate request is ever made, MCLK stays at whatever the bootloader left, and 44.1 kHz material goes out at 48 kHz. Adding mclk-fs to my card node fixed it. The before/after rates I quoted belong to that change, not to this one. Sorry for the noise. Karl On Thu, Aug 20, 2026 at 10:54 AM Karl Asseily <[email protected]> wrote: > > Every MCLK_SPDIFn gate is declared with flags 0, while the CLK_SPDIFn mux > immediately above it already carries CLK_SET_RATE_PARENT. The rockchip > S/PDIF driver calls clk_set_rate() on the gate, which has no .set_rate of > its own and, without CLK_SET_RATE_PARENT, no way to pass the request up. > The clock core therefore computes "new rate == current rate", returns 0, > and changes nothing. > > The visible effect is that S/PDIF is stuck on whatever divider the > bootloader left behind. On a board whose audio PLL is parked on the > 48 kHz family, every 44.1 kHz source goes out at 48 kHz, silently, with > nothing reporting an error. Measured on an RK3588 board playing 44.1 kHz > material, before and after: > > mclk_spdif0 12287999 Hz 48000 x 256 > mclk_spdif0 11289598 Hz 44100 x 256 > > Add CLK_SET_RATE_PARENT to all eight MCLK_SPDIF gates so the request > propagates to the fractional divider that can satisfy it. > > Propagation stops there. Each chain terminates at CLK_SPDIFn_SRC, which > is declared with flags 0, so a rate request cannot reach a shared PLL and > pull unrelated consumers off frequency. > > Two pairs of gates share a divider - mclk_spdif2 and mclk_spdif2_dp0 both > sit on clk_spdif2_dp0, and mclk_spdif5 and mclk_spdif5_dp1 on > clk_spdif5_dp1 - so a rate set on one moves the other. That sharing is in > the hardware and is not introduced here; before this change neither of > them could set a rate at all. > > Signed-off-by: Karl Asseily <[email protected]> > --- > > Notes: > Generated against broonie/sound.git for-next. clk-rk3588.c > carries no ASoC changes, so this should apply to any current tree. > > Tested on RK3588 hardware running 7.1.3: without this a 44.1 kHz stream leaves > the S/PDIF transmitter at 48 kHz; with it mclk_spdif0 retunes and the receiver > locks at 44.1 kHz. > > checkpatch --strict reports "Alignment should match open parenthesis" on the > touched lines. That continuation indentation is unchanged by this patch and > matches every other clock entry in the file; realigning only these eight would > make them the inconsistent ones. > > drivers/clk/rockchip/clk-rk3588.c | 16 ++++++++-------- > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c > index 2ba9976654c..b3d577dccfc 100644 > --- a/drivers/clk/rockchip/clk-rk3588.c > +++ b/drivers/clk/rockchip/clk-rk3588.c > @@ -960,7 +960,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { > RK3588_CLKSEL_CON(33), 0, > RK3588_CLKGATE_CON(9), 0, GFLAGS, > &rk3588_spdif0_fracmux), > - GATE(MCLK_SPDIF0, "mclk_spdif0", "clk_spdif0", 0, > + GATE(MCLK_SPDIF0, "mclk_spdif0", "clk_spdif0", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(9), 1, GFLAGS), > > GATE(HCLK_SPDIF1, "hclk_spdif1", "hclk_audio_root", 0, > @@ -973,7 +973,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { > RK3588_CLKSEL_CON(35), 0, > RK3588_CLKGATE_CON(9), 4, GFLAGS, > &rk3588_spdif1_fracmux), > - GATE(MCLK_SPDIF1, "mclk_spdif1", "clk_spdif1", 0, > + GATE(MCLK_SPDIF1, "mclk_spdif1", "clk_spdif1", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(9), 5, GFLAGS), > > COMPOSITE(ACLK_AV1_ROOT, "aclk_av1_root", gpll_cpll_aupll_p, 0, > @@ -1868,9 +1868,9 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { > RK3588_CLKSEL_CON(123), 0, > RK3588_CLKGATE_CON(57), 4, GFLAGS, > &rk3588_spdif2_dp0_fracmux), > - GATE(MCLK_SPDIF2_DP0, "mclk_spdif2_dp0", "clk_spdif2_dp0", 0, > + GATE(MCLK_SPDIF2_DP0, "mclk_spdif2_dp0", "clk_spdif2_dp0", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(57), 5, GFLAGS), > - GATE(MCLK_SPDIF2, "mclk_spdif2", "clk_spdif2_dp0", 0, > + GATE(MCLK_SPDIF2, "mclk_spdif2", "clk_spdif2_dp0", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(57), 6, GFLAGS), > COMPOSITE(CLK_SPDIF5_DP1_SRC, "clk_spdif5_dp1_src", gpll_aupll_p, 0, > RK3588_CLKSEL_CON(124), 7, 1, MFLAGS, 2, 5, DFLAGS, > @@ -1880,9 +1880,9 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { > RK3588_CLKSEL_CON(125), 0, > RK3588_CLKGATE_CON(57), 9, GFLAGS, > &rk3588_spdif5_dp1_fracmux), > - GATE(MCLK_SPDIF5_DP1, "mclk_spdif5_dp1", "clk_spdif5_dp1", 0, > + GATE(MCLK_SPDIF5_DP1, "mclk_spdif5_dp1", "clk_spdif5_dp1", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(57), 10, GFLAGS), > - GATE(MCLK_SPDIF5, "mclk_spdif5", "clk_spdif5_dp1", 0, > + GATE(MCLK_SPDIF5, "mclk_spdif5", "clk_spdif5_dp1", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(57), 11, GFLAGS), > COMPOSITE_NOMUX(CLK_AUX16M_0, "clk_aux16m_0", "gpll", 0, > RK3588_CLKSEL_CON(117), 0, 8, DFLAGS, > @@ -2059,7 +2059,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { > RK3588_CLKSEL_CON(149), 0, > RK3588_CLKGATE_CON(63), 6, GFLAGS, > &rk3588_spdif3_fracmux), > - GATE(MCLK_SPDIF3, "mclk_spdif3", "clk_spdif3", 0, > + GATE(MCLK_SPDIF3, "mclk_spdif3", "clk_spdif3", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(63), 7, GFLAGS), > COMPOSITE(CLK_SPDIF4_SRC, "clk_spdif4_src", gpll_aupll_p, 0, > RK3588_CLKSEL_CON(150), 7, 1, MFLAGS, 2, 5, DFLAGS, > @@ -2069,7 +2069,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { > RK3588_CLKSEL_CON(151), 0, > RK3588_CLKGATE_CON(63), 10, GFLAGS, > &rk3588_spdif4_fracmux), > - GATE(MCLK_SPDIF4, "mclk_spdif4", "clk_spdif4", 0, > + GATE(MCLK_SPDIF4, "mclk_spdif4", "clk_spdif4", CLK_SET_RATE_PARENT, > RK3588_CLKGATE_CON(63), 11, GFLAGS), > COMPOSITE(MCLK_SPDIFRX0, "mclk_spdifrx0", gpll_cpll_aupll_p, 0, > RK3588_CLKSEL_CON(152), 7, 2, MFLAGS, 2, 5, DFLAGS, > -- > 2.34.1 > _______________________________________________ Linux-rockchip mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-rockchip