mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
126 lines
3.4 KiB
Diff
126 lines
3.4 KiB
Diff
From 3fee78120b2fe4e55bad621f5adc520fe37e3519 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Fri, 6 Jun 2025 18:18:23 +0300
|
|
Subject: [PATCH 089/113] FROMLIST(v4): phy: rockchip: samsung-hdptx: Compute
|
|
clk rate from PLL config
|
|
|
|
Improve ->recalc_rate() callback of hdptx_phy_clk_ops to calculate the
|
|
initial clock rate based on the actual PHY PLL configuration as
|
|
retrieved from the related hardware registers.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
---
|
|
.../phy/rockchip/phy-rockchip-samsung-hdptx.c | 91 ++++++++++++++++++-
|
|
1 file changed, 90 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
|
index 699b86732b8d..6e2443f78968 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
|
@@ -1851,12 +1851,101 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
|
|
rk_hdptx_phy_consumer_put(hdptx, true);
|
|
}
|
|
|
|
+#define PLL_REF_CLK 24000000ULL
|
|
+
|
|
+static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
|
+{
|
|
+ struct ropll_config ropll_hw;
|
|
+ u64 fout, sdm;
|
|
+ u32 mode, val;
|
|
+ int ret;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+
|
|
+ if (mode & LCPLL_LCVCO_MODE_EN_MASK)
|
|
+ return 0;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.pms_mdiv = val;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(005E), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdm_en = val & ROPLL_SDM_EN_MASK;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0064), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0065), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdm_num = val;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0060), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdm_deno = val;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0069), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdc_n = (val & ROPLL_SDC_N_RBR_MASK) + 3;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(006c), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdc_num = val;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0070), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.sdc_deno = val;
|
|
+
|
|
+ ret = regmap_read(hdptx->regmap, CMN_REG(0086), &val);
|
|
+ if (ret)
|
|
+ return 0;
|
|
+ ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1;
|
|
+
|
|
+ fout = PLL_REF_CLK * ropll_hw.pms_mdiv;
|
|
+ if (ropll_hw.sdm_en) {
|
|
+ sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno *
|
|
+ ropll_hw.pms_mdiv * ropll_hw.sdm_num,
|
|
+ 16 * ropll_hw.sdm_deno *
|
|
+ (ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num));
|
|
+
|
|
+ if (ropll_hw.sdm_num_sign)
|
|
+ fout = fout - sdm;
|
|
+ else
|
|
+ fout = fout + sdm;
|
|
+ }
|
|
+
|
|
+ return div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
|
|
+}
|
|
+
|
|
static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
|
|
unsigned long parent_rate)
|
|
{
|
|
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
|
+ u32 status;
|
|
+ u64 rate;
|
|
+ int ret;
|
|
+
|
|
+ if (hdptx->hw_rate)
|
|
+ return hdptx->hw_rate;
|
|
+
|
|
+ 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);
|
|
|
|
- return hdptx->hw_rate;
|
|
+ return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
|
|
}
|
|
|
|
static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
--
|
|
2.34.1
|
|
|