[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250708-phy-hdptx-frl-v1-9-cfe096e224f4@collabora.com>
Date: Tue, 08 Jul 2025 22:35:50 +0300
From: Cristian Ciocaltea <cristian.ciocaltea@...labora.com>
To: Vinod Koul <vkoul@...nel.org>,
Kishon Vijay Abraham I <kishon@...nel.org>,
Heiko Stuebner <heiko@...ech.de>, Algea Cao <algea.cao@...k-chips.com>
Cc: kernel@...labora.com, linux-phy@...ts.infradead.org,
linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
linux-rockchip@...ts.infradead.org
Subject: [PATCH 09/12] 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 HW registers.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@...labora.com>
---
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 90 ++++++++++++++++++++++-
1 file changed, 89 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 71b076de7b75f2ba08eae679ded77caa2ba86590..e86bbc270a4ca448f55ca58b4b5b52d378730d74 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1850,12 +1850,100 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
rk_hdptx_phy_consumer_put(hdptx, true);
}
+#define PLL_REF_CLK 24000000ULL
+
+static unsigned long 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;
+ }
+
+ fout = div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
+
+ return fout;
+}
+
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;
+ 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;
- return hdptx->hw_rate;
+ return rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
}
static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
--
2.50.0
Powered by blists - more mailing lists