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

Andy Yan andyshrk at gmail.com
Thu Jul 16 05:27:19 PDT 2026


Hello,
Cristian Ciocaltea <cristian.ciocaltea at collabora.com> 于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 at online.de>
> Tested-by: Simon Wright <simon at symple.nz>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>

   Reviewed-by:Andy Yan <andyshrk at gmail.com>

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
>
>



More information about the Linux-rockchip mailing list