[PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers

Qiang Yu qiang.yu at oss.qualcomm.com
Mon May 18 22:47:16 PDT 2026


Some QMP PCIe PHY hardware blocks can be split into multiple sub-PHYs
under a single DT node, each requiring its own pipe clock registration and
DT resource mapping. The current helpers are tightly coupled to a single
qmp_pcie instance, which prevents reuse across sub-PHY instances.

Refactor __phy_pipe_clk_register() as a generic helper and reduce
phy_pipe_clk_register() to a thin wrapper around it. Similarly, extract
qmp_pcie_parse_dt_common() from qmp_pcie_parse_dt() to hold the register-
mapping and pipe-clock setup that will be shared between sub-PHY instances,
with pipe clock names parameterised per instance.

This is a preparatory step before adding multi-PHY support. No functional
change for existing platforms.

Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 1dee4733d4f2..6332f15f78ca 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -5116,32 +5116,34 @@ static void phy_clk_release_provider(void *res)
  *    clk  |   +-------+   |                   +-----+
  *         +---------------+
  */
-static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
+static int __phy_pipe_clk_register(struct device *dev, struct device_node *np,
+				   int clk_name_index, struct clk_fixed_rate *fixed)
 {
-	struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
 	struct clk_init_data init = { };
 	int ret;
 
-	ret = of_property_read_string_index(np, "clock-output-names", 0, &init.name);
+	ret = of_property_read_string_index(np, "clock-output-names", clk_name_index,
+					    &init.name);
 	if (ret) {
-		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
+		dev_err(dev, "%pOFn: No clock-output-names\n", np);
 		return ret;
 	}
 
 	init.ops = &clk_fixed_rate_ops;
 
-	/*
-	 * Controllers using QMP PHY-s use 125MHz pipe clock interface
-	 * unless other frequency is specified in the PHY config.
-	 */
-	if (qmp->cfg->pipe_clock_rate)
-		fixed->fixed_rate = qmp->cfg->pipe_clock_rate;
-	else
+	/* Default to 125MHz if caller did not pre-populate a rate. */
+	if (!fixed->fixed_rate)
 		fixed->fixed_rate = 125000000;
 
 	fixed->hw.init = &init;
 
-	return devm_clk_hw_register(qmp->dev, &fixed->hw);
+	return devm_clk_hw_register(dev, &fixed->hw);
+}
+
+static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
+{
+	qmp->pipe_clk_fixed.fixed_rate = qmp->cfg->pipe_clock_rate;
+	return __phy_pipe_clk_register(qmp->dev, np, 0, &qmp->pipe_clk_fixed);
 }
 
 /*
@@ -5336,26 +5338,18 @@ static int qmp_pcie_get_4ln_config(struct qmp_pcie *qmp)
 	return 0;
 }
 
-static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
+static int qmp_pcie_parse_dt_common(struct qmp_pcie *qmp, void __iomem *base,
+				    const char *pipe_clk_name,
+				    const char *pipediv2_clk_name)
 {
-	struct platform_device *pdev = to_platform_device(qmp->dev);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	const struct qmp_pcie_offsets *offs = cfg->offsets;
 	struct device *dev = qmp->dev;
-	void __iomem *base;
 	int ret;
 
 	if (!offs)
 		return -EINVAL;
 
-	ret = qmp_pcie_get_4ln_config(qmp);
-	if (ret)
-		return ret;
-
-	base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(base))
-		return PTR_ERR(base);
-
 	qmp->serdes = base + offs->serdes;
 	qmp->pcs = base + offs->pcs;
 	qmp->pcs_misc = base + offs->pcs_misc;
@@ -5368,12 +5362,6 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 		qmp->rx2 = base + offs->rx2;
 	}
 
-	if (qmp->cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
-		qmp->port_b = devm_platform_ioremap_resource(pdev, 1);
-		if (IS_ERR(qmp->port_b))
-			return PTR_ERR(qmp->port_b);
-	}
-
 	qmp->txz = base + offs->txz;
 	qmp->rxz = base + offs->rxz;
 
@@ -5381,17 +5369,41 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 		qmp->ln_shrd = base + offs->ln_shrd;
 
 	qmp->num_pipe_clks = 2;
-	qmp->pipe_clks[0].id = "pipe";
-	qmp->pipe_clks[1].id = "pipediv2";
+	qmp->pipe_clks[0].id = pipe_clk_name;
+	qmp->pipe_clks[1].id = pipediv2_clk_name;
 
 	ret = devm_clk_bulk_get(dev, 1, qmp->pipe_clks);
 	if (ret)
 		return ret;
 
-	ret = devm_clk_bulk_get_optional(dev, qmp->num_pipe_clks - 1, qmp->pipe_clks + 1);
+	return devm_clk_bulk_get_optional(dev, qmp->num_pipe_clks - 1,
+					  qmp->pipe_clks + 1);
+}
+
+static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
+{
+	struct platform_device *pdev = to_platform_device(qmp->dev);
+	void __iomem *base;
+	int ret;
+
+	ret = qmp_pcie_get_4ln_config(qmp);
+	if (ret)
+		return ret;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	ret = qmp_pcie_parse_dt_common(qmp, base, "pipe", "pipediv2");
 	if (ret)
 		return ret;
 
+	if (qmp->cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
+		qmp->port_b = devm_platform_ioremap_resource(pdev, 1);
+		if (IS_ERR(qmp->port_b))
+			return PTR_ERR(qmp->port_b);
+	}
+
 	return 0;
 }
 

-- 
2.34.1




More information about the linux-phy mailing list