mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc
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: 3481fc04d9 ("phy: rockchip: samsung-hdptx: Compute clk rate from PLL config")
Tested-by: Thomas Niederprüm <dubito@online.de>
Tested-by: Simon Wright <simon@symple.nz>
Tested-by: Diederik de Haas <diederik@cknow-tech.com> # NanoPC-T6 LTS
Reviewed-by: Andy Yan <andyshrk@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Link: https://patch.msgid.link/20260811-hdptx-clk-fixes-v6-1-75bca0ee5753@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
8fd2b30d18
commit
f0c2c9c58a
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user