[PATCH 07/12] clk: qcom: ipq-cmn-pll: Add EPHY-RAW clock support
From: Luo Jie
Date: Fri Jul 24 2026 - 11:13:00 EST
The EPHY-RAW clock is an IPQ5210-specific output from the CMN PLL that
provides the raw reference clock to the SoC-integrated Ethernet PHY
(EPHY), which supports up to 2.5G link speed. The output frequency is
selected via bit 10 (CMN_PLL_GEPHY_312P5M_125M_SEL) of the
CMN_PLL_PON_CONFIG register:
- 0: 125 MHz - for 1G/100M/10M link speed
- 1: 312.5 MHz - for 2.5G link speed
Signed-off-by: Luo Jie <jie.luo@xxxxxxxxxxxxxxxx>
---
drivers/clk/qcom/ipq-cmn-pll.c | 86 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c
index 1ae32052b563..dfc28c12468b 100644
--- a/drivers/clk/qcom/ipq-cmn-pll.c
+++ b/drivers/clk/qcom/ipq-cmn-pll.c
@@ -76,6 +76,7 @@
#define CMN_PLL_PON_MODE_SEL BIT(9)
#define CMN_PLL_PON_EN BIT(8)
#define CMN_PLL_PON_DIV_CTRL GENMASK(7, 0)
+#define CMN_PLL_GEPHY_312P5M_125M_SEL BIT(10)
#define CMN_PLL_POWER_ON_AND_RESET 0x780
#define CMN_ANA_EN_SW_RSTN BIT(6)
@@ -694,6 +695,87 @@ static struct clk_hw *ipq_cmn_pll_pon_refclk_register(struct platform_device *pd
return &pon_clk->hw;
}
+/*
+ * EPHY-RAW clock operations for IPQ5210.
+ * The output clock rate is selected via bit 10 of CMN_PLL_PON_CONFIG:
+ * 0: 125 MHz (for 1G link speed)
+ * 1: 312.5 MHz (for 2.5G link speed)
+ */
+static unsigned long clk_ephy_raw_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_cmn_pll *ephy_raw_clk = to_clk_cmn_pll(hw);
+ u32 val;
+
+ regmap_read(ephy_raw_clk->regmap, CMN_PLL_PON_CONFIG, &val);
+
+ if (val & CMN_PLL_GEPHY_312P5M_125M_SEL)
+ return 312500000UL;
+
+ return 125000000UL;
+}
+
+static int clk_ephy_raw_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ if (req->rate <= 125000000UL)
+ req->rate = 125000000UL;
+ else
+ req->rate = 312500000UL;
+
+ return 0;
+}
+
+static int clk_ephy_raw_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_cmn_pll *ephy_raw_clk = to_clk_cmn_pll(hw);
+
+ if (rate == 125000000UL)
+ return regmap_clear_bits(ephy_raw_clk->regmap,
+ CMN_PLL_PON_CONFIG,
+ CMN_PLL_GEPHY_312P5M_125M_SEL);
+
+ return regmap_set_bits(ephy_raw_clk->regmap,
+ CMN_PLL_PON_CONFIG,
+ CMN_PLL_GEPHY_312P5M_125M_SEL);
+}
+
+static const struct clk_ops clk_ephy_raw_ops = {
+ .recalc_rate = clk_ephy_raw_recalc_rate,
+ .determine_rate = clk_ephy_raw_determine_rate,
+ .set_rate = clk_ephy_raw_set_rate,
+};
+
+static struct clk_hw *ipq_cmn_pll_ephy_raw_register(struct platform_device *pdev,
+ struct regmap *regmap,
+ struct clk_hw *cmn_pll_hw)
+{
+ struct clk_parent_data pdata = { .hw = cmn_pll_hw };
+ struct clk_cmn_pll *ephy_raw_clk;
+ struct device *dev = &pdev->dev;
+ struct clk_init_data init = {};
+ int ret;
+
+ ephy_raw_clk = devm_kzalloc(dev, sizeof(*ephy_raw_clk), GFP_KERNEL);
+ if (!ephy_raw_clk)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = "ephy-raw";
+ init.parent_data = &pdata;
+ init.num_parents = 1;
+ init.ops = &clk_ephy_raw_ops;
+
+ ephy_raw_clk->hw.init = &init;
+ ephy_raw_clk->regmap = regmap;
+
+ ret = devm_clk_hw_register(dev, &ephy_raw_clk->hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &ephy_raw_clk->hw;
+}
+
static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
{
const struct cmn_pll_fixed_output_clk *p, *fixed_clk;
@@ -747,6 +829,10 @@ static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
hw = ipq_cmn_pll_pon_refclk_register(pdev,
cmn_pll->regmap,
cmn_pll_hw);
+ } else if (!strcmp(fixed_clk[i].name, "ephy-raw")) {
+ hw = ipq_cmn_pll_ephy_raw_register(pdev,
+ cmn_pll->regmap,
+ cmn_pll_hw);
} else {
continue;
}
--
2.43.0