Re: [PATCH v4 1/8] phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc

From: Andy Yan

Date: Thu Jul 16 2026 - 08:29:25 EST


Hello,
Cristian Ciocaltea <cristian.ciocaltea@xxxxxxxxxxxxx> 于2026年6月12日周五 07:45写道:
>
> The PHY PLL can be programmed by an external component, e.g. the
> bootloader, just before the recalc_rate() callback is invoked during
> devm_clk_hw_register() in the probe path.
>
> Therefore rk_hdptx_phy_clk_recalc_rate() finds the PLL enabled and
> attempts to compute the clock rate, while making use of the bpc value
> from the HDMI PHY configuration, which always defaults to 8 because
> phy_configure() was not run at that point. As a consequence, the
> (re)calculated rate is incorrect when the actual bpc was higher than 8.
>
> Do not rely on any of the hdmi_cfg members when computing the clock rate
> and, instead, read the required input data (i.e. bpc), directly from the
> hardware registers.
>
> Fixes: 3481fc04d969 ("phy: rockchip: samsung-hdptx: Compute clk rate from PLL config")
> Tested-by: Thomas Niederprüm <dubito@xxxxxxxxx>
> Tested-by: Simon Wright <simon@xxxxxxxxx>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@xxxxxxxxxxxxx>

Reviewed-by:Andy Yan <andyshrk@xxxxxxxxx>

Thanks
> ---
> drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 13 ++++---------
> 1 file changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 2d973bc37f07..710603afff86 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -2168,7 +2168,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
> struct lcpll_config lcpll_hw;
> struct ropll_config ropll_hw;
> u64 fout, sdm;
> - u32 mode, val;
> + u32 mode, bpc, val;
> int ret, i;
>
> ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
> @@ -2266,6 +2266,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
> if (ret)
> return 0;
> ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1;
> + bpc = (FIELD_GET(PLL_PCG_CLK_SEL_MASK, val) << 1) + 8;
>
> fout = PLL_REF_CLK * ropll_hw.pms_mdiv;
> if (ropll_hw.sdm_en) {
> @@ -2280,7 +2281,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
> fout = fout + sdm;
> }
>
> - return div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
> + return DIV_ROUND_CLOSEST_ULL(fout * 2 * 8, ropll_hw.pms_sdiv * 10 * bpc);
> }
>
> static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
> @@ -2288,19 +2289,13 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
> {
> struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
> u32 status;
> - u64 rate;
> int ret;
>
> ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
> if (ret || !(status & HDPTX_I_PLL_EN))
> return 0;
>
> - rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
> -
> - if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
> - return rate;
> -
> - return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
> + return rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
> }
>
> static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
>
> --
> 2.54.0
>
>