Devicetree
 help / color / mirror / Atom feed
* [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY
@ 2026-05-19  5:47 Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible Qiang Yu
                   ` (8 more replies)
  0 siblings, 9 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel,
	Dmitry Baryshkov

Hi all,

This RFC proposes a revised model for Glymur Gen5x8 PCIe PHY support.

On Glymur, PCIe3 uses one shared Gen5x8 QMP PHY hardware block that can
operate in different link topologies (x8 or x4+x4). The previous series
approach was not accepted, so this RFC reworks the design to better match
the hardware model and DT expectations.

This RFC focuses on the link-mode model and associated binding/API changes
while keeping prerequisite/independent patches separate.

What this RFC changes:

- Keep a single PHY provider node for the shared Gen5x8 hardware block.
- Select active topology on the provider side via `link-mode`.
- Use `#phy-cells = <1>` so consumers can pass logical PHY index to get
  different phy structure.
- Keep legacy (non-link-mode) platforms on the existing path.
- Validate mode consistency at probe:
  - if HW mode matches DT mode, continue;
  - if mismatch, allow only when selected mode has complete PHY setting
    tables for all logical PHYs; otherwise fail probe.
- Keep programming link-mode register during `power_on`, so DT-selected
  mode is re-applied when TCSR register may be reset after low-power mode.

Mode/cfg selection model:

- Introduce mode-indexed match data:
  - first dimension: `link_mode`
  - second dimension: `logical_phy_index`
- Effective lookup is:
    cfg = mode_cfgs[active_link_mode].cfgs[logical_phy_index]

This allows one shared provider to expose different logical PHY sets per
mode.

Impact:
- Keep existing qmp-pcie PHY operation flow (`phy_ops`) unchanged as much
  as possible.
- Constrain the new design mainly to cfg selection and provider/xlate
  wiring.
- Reuse existing init/power/reset flows with selected cfg, minimizing code
  churn and behavioral risk.
- This RFC is implemented and validated on Glymur Gen5x8, it is designed
  to be extensible to other multi-mode QMP PCIe PHYs, although additional
  platform-specific requirements may still be needed.

This series depends on a prerequisite patch by Krzysztof Kozlowski:
https://lore.kernel.org/r/20260420133616.88740-2-krzysztof.kozlowski@oss.qualcomm.com

Thanks,
Qiang

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
Changes in v4:
- Replaced the static bifurcation probe model with a link-mode
  architecture: the active topology (x8 or x4+x4) is selected via a
  new "qcom,link-mode" DT property and written to a TCSR register at
  power-on. This replaces v3 patches 4 and 5 with four new patches
  (driver refactor, secondary PHY clock/reset lists, link-mode probe
  infrastructure, and Glymur config).
- Updated dt-bindings to describe "qcom,link-mode", #phy-cells = <1>,
  per-mode validation rules, and added a new header with
  QMP_PHY_SELECTOR_* and QMP_PCIE_GLYMUR_MODE_* macros.
- Patches 2 and 3 (multiple power-domains, multiple nocsr resets) are
  unchanged from v3.
- Link to v3: https://lore.kernel.org/r/20260412-glymur_gen5x8_phy_0413-v3-0-affcebc16b8b@oss.qualcomm.com

Changes in v3:
- Add description of each power-domain.
- Add 64bit prefetchable memory range required by some EPs eg. AI100 ultra.
- Move PCIe3a after PCIe3b and move PCIe3a PHY before PCIe3b PHY.
- Link to v2: https://lore.kernel.org/all/20260323-glymur_gen5x8_phy_0323-v2-0-ce0fc07f0e52@oss.qualcomm.com/

Changes in v2:
- Remove pd_list from qmp_pcie struct as it is not used in phy driver.
- align clk-names on "
- Link to v1: https://lore.kernel.org/all/20260304-glymur_gen5x8_phy-v1-0-849e9a72e125@oss.qualcomm.com/

To: Vinod Koul <vkoul@kernel.org>
To: Neil Armstrong <neil.armstrong@linaro.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Philipp Zabel <p.zabel@pengutronix.de>
To: Bjorn Andersson <andersson@kernel.org>
To: Konrad Dybcio <konradybcio@kernel.org>
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Qiang Yu (9):
      dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible
      dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros
      phy: qcom: qmp-pcie: Add multiple power-domains support
      phy: qcom: qmp-pcie: Support multiple nocsr resets
      phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
      phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector
      phy: qcom: qmp-pcie: Add link-mode multi-PHY probe infrastructure
      phy: qcom: qmp-pcie: Add Glymur Gen5x8 PHY config and match data
      arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY

 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   | 140 ++++-
 arch/arm64/boot/dts/qcom/glymur-crd.dtsi           |   5 +
 arch/arm64/boot/dts/qcom/glymur.dtsi               | 333 ++++++++++-
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 631 ++++++++++++++++++---
 include/dt-bindings/phy/phy-qcom-qmp.h             |   8 +
 5 files changed, 1021 insertions(+), 96 deletions(-)
---
base-commit: 4359f733f8edf6be944b9f28ccb6a6c6e9a24aaa
change-id: 20260518-link_mode_0519-708494cee2da

Best regards,
--  
Qiang Yu <qiang.yu@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-06-16 14:03   ` Konrad Dybcio
  2026-05-19  5:47 ` [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros Qiang Yu
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

The Glymur SoC uses a single PCIe Gen5 PHY hardware block for the
PCIe3a/PCIe3b controllers. This block supports two link modes:

1. x4+x4: two 4-lane PHY instances are exposed
2. x8: one 8-lane PHY instance is exposed

Add qcom,glymur-qmp-gen5x8-pcie-phy as a multi-mode PHY compatible and
document the new link-mode property, which selects the active link mode
via a TCSR syscon register.

Document the required clocks, resets, and power-domains for both PHY
instances active in x8 mode. Use #phy-cells = <1> for this compatible,
where the cell value is the PHY index within the active link mode.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   | 140 ++++++++++++++++++---
 1 file changed, 126 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index 3a35120a77ec..5877e40244ba 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -18,6 +18,7 @@ properties:
     enum:
       - qcom,glymur-qmp-gen4x2-pcie-phy
       - qcom,glymur-qmp-gen5x4-pcie-phy
+      - qcom,glymur-qmp-gen5x8-pcie-phy
       - qcom,kaanapali-qmp-gen3x2-pcie-phy
       - qcom,qcs615-qmp-gen3x1-pcie-phy
       - qcom,qcs8300-qmp-gen4x2-pcie-phy
@@ -58,7 +59,7 @@ properties:
 
   clocks:
     minItems: 5
-    maxItems: 6
+    maxItems: 10
 
   clock-names:
     minItems: 5
@@ -68,20 +69,29 @@ properties:
       - const: ref
       - enum: [rchng, refgen]
       - const: pipe
-      - const: pipediv2
+      - enum: [pipediv2, phy_b_aux]
+      - const: cfg_ahb_b
+      - const: rchng_b
+      - const: pipe_b
+      - const: pipediv2_b
 
   power-domains:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: PCIe PHY power domain.
+      - description: Additional PCIe PHY power domain (if present).
 
   resets:
     minItems: 1
-    maxItems: 2
+    maxItems: 4
 
   reset-names:
     minItems: 1
     items:
       - const: phy
       - const: phy_nocsr
+      - const: phy_b
+      - const: phy_b_nocsr
 
   vdda-phy-supply: true
 
@@ -98,13 +108,29 @@ properties:
           - description: offset of PCIe 4-lane configuration register
           - description: offset of configuration bit for this PHY
 
+  qcom,link-mode:
+    description:
+      Configures the link mode of the PCIe PHY. Some PHYs support multiple
+      link modes, such as a single x8 link or two independent x4 links. The
+      link mode selection is performed by writing to a register in the TCSR
+      syscon, specified as a phandle to the syscon, the register offset, and
+      the link mode value.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle of TCSR syscon
+          - description: offset of link mode register
+          - description: link mode value
+
   "#clock-cells": true
 
   clock-output-names:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: Name of the first pipe clock output.
+      - description: Name of the second pipe clock output (if present).
 
-  "#phy-cells":
-    const: 0
+  "#phy-cells": true
 
 required:
   - compatible
@@ -130,19 +156,40 @@ allOf:
               - qcom,sc8280xp-qmp-gen3x4-pcie-phy
               - qcom,x1e80100-qmp-gen4x4-pcie-phy
               - qcom,x1p42100-qmp-gen4x4-pcie-phy
+              - qcom,glymur-qmp-gen5x8-pcie-phy
     then:
       properties:
         reg:
           items:
             - description: port a
             - description: port b
-      required:
-        - qcom,4ln-config-sel
     else:
       properties:
         reg:
           maxItems: 1
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,sc8280xp-qmp-gen3x4-pcie-phy
+              - qcom,x1e80100-qmp-gen4x4-pcie-phy
+              - qcom,x1p42100-qmp-gen4x4-pcie-phy
+    then:
+      required:
+        - qcom,4ln-config-sel
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,glymur-qmp-gen5x8-pcie-phy
+    then:
+      required:
+        - qcom,link-mode
+
   - if:
       properties:
         compatible:
@@ -198,8 +245,40 @@ allOf:
       properties:
         clocks:
           minItems: 6
+          maxItems: 6
         clock-names:
           minItems: 6
+          maxItems: 6
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,glymur-qmp-gen5x8-pcie-phy
+    then:
+      properties:
+        clocks:
+          minItems: 10
+          maxItems: 10
+        clock-names:
+          items:
+            - const: aux
+            - const: cfg_ahb
+            - const: ref
+            - const: rchng
+            - const: pipe
+            - const: phy_b_aux
+            - const: cfg_ahb_b
+            - const: rchng_b
+            - const: pipe_b
+            - const: pipediv2_b
+        power-domains:
+          minItems: 2
+    else:
+      properties:
+        power-domains:
+          maxItems: 1
 
   - if:
       properties:
@@ -223,11 +302,24 @@ allOf:
         reset-names:
           minItems: 2
     else:
-      properties:
-        resets:
-          maxItems: 1
-        reset-names:
-          maxItems: 1
+      if:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - qcom,glymur-qmp-gen5x8-pcie-phy
+      then:
+        properties:
+          resets:
+            minItems: 4
+          reset-names:
+            minItems: 4
+      else:
+        properties:
+          resets:
+            maxItems: 1
+          reset-names:
+            maxItems: 1
 
   - if:
       properties:
@@ -237,6 +329,7 @@ allOf:
               - qcom,sm8450-qmp-gen4x2-pcie-phy
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
+              - qcom,glymur-qmp-gen5x8-pcie-phy
     then:
       properties:
         "#clock-cells":
@@ -246,6 +339,25 @@ allOf:
         "#clock-cells":
           const: 0
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,glymur-qmp-gen5x8-pcie-phy
+    then:
+      properties:
+        clock-output-names:
+          minItems: 2
+        "#phy-cells":
+          const: 1
+    else:
+      properties:
+        clock-output-names:
+          maxItems: 1
+        "#phy-cells":
+          const: 0
+
 examples:
   - |
     #include <dt-bindings/clock/qcom,gcc-sc8280xp.h>

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-06-16 14:07   ` Konrad Dybcio
  2026-05-19  5:47 ` [PATCH RFC v4 3/9] phy: qcom: qmp-pcie: Add multiple power-domains support Qiang Yu
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

Add two sets of constants to phy-qcom-qmp.h to support upcoming multiple
link mode QMP PHY:

- QMP_PHY_SELECTOR_0 / QMP_PHY_SELECTOR_1: generic logical PHY index
  values for QMP providers that expose multiple PHY instances under a
  single DT node (i.e. #phy-cells = <1>).

- QMP_PCIE_GLYMUR_MODE_X8 / QMP_PCIE_GLYMUR_MODE_X4X4: link-mode
  values for the Glymur Gen5x8 PCIe PHY "qcom,link-mode" syscon property,
  selecting between the x8 single-PHY and x4+x4 dual-PHY topologies.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 include/dt-bindings/phy/phy-qcom-qmp.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/phy/phy-qcom-qmp.h
index 6b43ea9e0051..befa76f8392f 100644
--- a/include/dt-bindings/phy/phy-qcom-qmp.h
+++ b/include/dt-bindings/phy/phy-qcom-qmp.h
@@ -21,4 +21,12 @@
 #define QMP_PCIE_PIPE_CLK		0
 #define QMP_PCIE_PHY_AUX_CLK		1
 
+/* Generic QMP logical PHY selectors */
+#define QMP_PHY_SELECTOR_0		0
+#define QMP_PHY_SELECTOR_1		1
+
+/* Glymur QMP PCIe link modes (for link-mode property value) */
+#define QMP_PCIE_GLYMUR_MODE_X8		0
+#define QMP_PCIE_GLYMUR_MODE_X4X4	1
+
 #endif /* _DT_BINDINGS_PHY_QMP */

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 3/9] phy: qcom: qmp-pcie: Add multiple power-domains support
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 4/9] phy: qcom: qmp-pcie: Support multiple nocsr resets Qiang Yu
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel,
	Dmitry Baryshkov

The Glymur SoC's 3rd PCIe instance supports 8-lane mode using two PHYs in
a bifurcated configuration. Each PHY has its own power domain (phy_gdsc)
that must be powered on before initialization per hardware requirements.

Current PHY power management assumes a single power domain per PHY,
preventing proper setup for this dual-PHY scenario. Add support for
multiple power domains by using devm_pm_domain_attach_list() to attach
power domains manually, while maintaining compatibility with single
power domain PHYs.

Enable runtime PM to allow power domain control when the PCIe driver
calls phy_power_on/phy_power_off:

- Single power domain: QMP PHY platform device directly attaches to
  power domain and controls it during runtime resume/suspend
- Multiple power domains: devm_pm_domain_attach_list() creates virtual
  devices as power domain suppliers, linked to the QMP PHY platform
  device as consumer

This ensures power domains are properly attached and turned on/off
for both single and multiple power domain configurations.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 75afbd15aaf4..832b5d93105b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -17,6 +17,7 @@
 #include <linux/phy/pcie.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
@@ -5329,6 +5330,7 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 
 static int qmp_pcie_probe(struct platform_device *pdev)
 {
+	struct dev_pm_domain_list *pd_list;
 	struct device *dev = &pdev->dev;
 	struct phy_provider *phy_provider;
 	struct device_node *np;
@@ -5348,6 +5350,16 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 	WARN_ON_ONCE(!qmp->cfg->pwrdn_ctrl);
 	WARN_ON_ONCE(!qmp->cfg->phy_status);
 
+	ret = devm_pm_domain_attach_list(dev, NULL, &pd_list);
+	if (ret < 0 && ret != -EEXIST) {
+		dev_err(dev, "Failed to attach power domain\n");
+		return ret;
+	}
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
 	ret = qmp_pcie_clk_init(qmp);
 	if (ret)
 		return ret;

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 4/9] phy: qcom: qmp-pcie: Support multiple nocsr resets
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
                   ` (2 preceding siblings ...)
  2026-05-19  5:47 ` [PATCH RFC v4 3/9] phy: qcom: qmp-pcie: Add multiple power-domains support Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers Qiang Yu
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

Refactor nocsr reset handling to support multiple nocsr resets required
for PHY configurations with bifurcated operation modes.

The Glymur SoC's 3rd PCIe instance supports 8-lane mode using two PHYs
in bifurcation, where each PHY requires its own nocsr reset to be
controlled simultaneously. The current implementation only supports a
single nocsr reset per PHY configuration.

Add num_nocsr and nocsr_list fields to struct qmp_phy_cfg to represent the
number and names of a group of nocsr reset names. Initialize these fields
for all PHYs that have nocsr resets, allowing the driver to correctly
acquire multiple nocsr resets during probe and control them as an array
by using reset_control_bulk APIs.

The refactoring maintains backward compatibility for existing single
nocsr reset configurations while enabling support for multi-PHY
scenarios like Glymur's 8-lane bifurcation mode.

Additionally, introduces x1e80100_qmp_gen3x2_pciephy_cfg as a separate
configuration from sm8550_qmp_gen3x2_pciephy_cfg since the x1e80100 Gen3x2
PHY requires nocsr reset support while the sm8550 Gen3x2 PHY does not.

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

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 832b5d93105b..1dee4733d4f2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3281,6 +3281,11 @@ struct qmp_phy_cfg {
 	/* resets to be requested */
 	const char * const *reset_list;
 	int num_resets;
+
+	/* nocsr resets to be requested */
+	const char * const *nocsr_reset_list;
+	int num_nocsr_resets;
+
 	/* regulators to be requested */
 	const char * const *vreg_list;
 	int num_vregs;
@@ -3327,7 +3332,7 @@ struct qmp_pcie {
 	int num_pipe_clks;
 
 	struct reset_control_bulk_data *resets;
-	struct reset_control *nocsr_reset;
+	struct reset_control_bulk_data *nocsr_reset;
 	struct regulator_bulk_data *vregs;
 
 	struct phy *phy;
@@ -3392,6 +3397,10 @@ static const char * const sdm845_pciephy_reset_l[] = {
 	"phy",
 };
 
+static const char * const sm8550_pciephy_nocsr_reset_l[] = {
+	"phy_nocsr",
+};
+
 static const struct qmp_pcie_offsets qmp_pcie_offsets_qhp = {
 	.serdes		= 0,
 	.pcs		= 0x1800,
@@ -4348,6 +4357,8 @@ static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {
 	},
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= sm8550_qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4380,6 +4391,8 @@ static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = {
 	},
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= sm8550_qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4480,6 +4493,35 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = {
 	.phy_status		= PHYSTATUS_4_20,
 };
 
+static const struct qmp_phy_cfg x1e80100_qmp_gen3x2_pciephy_cfg = {
+	.lanes = 2,
+
+	.offsets		= &qmp_pcie_offsets_v5,
+
+	.tbls = {
+		.serdes		= sm8550_qmp_gen3x2_pcie_serdes_tbl,
+		.serdes_num	= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_serdes_tbl),
+		.tx		= sm8550_qmp_gen3x2_pcie_tx_tbl,
+		.tx_num		= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_tx_tbl),
+		.rx		= sm8550_qmp_gen3x2_pcie_rx_tbl,
+		.rx_num		= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_rx_tbl),
+		.pcs		= sm8550_qmp_gen3x2_pcie_pcs_tbl,
+		.pcs_num	= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_tbl),
+		.pcs_misc	= sm8550_qmp_gen3x2_pcie_pcs_misc_tbl,
+		.pcs_misc_num	= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_misc_tbl),
+	},
+	.reset_list		= sdm845_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= pciephy_v5_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS,
+};
+
 static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = {
 	.lanes = 2,
 
@@ -4502,6 +4544,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4535,6 +4579,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4566,6 +4612,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4581,6 +4629,8 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
 
 	.reset_list             = sdm845_pciephy_reset_l,
 	.num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list              = qmp_phy_vreg_l,
 	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs                   = pciephy_v6_regs_layout,
@@ -4609,6 +4659,8 @@ static const struct qmp_phy_cfg qmp_v8_gen3x2_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v8_regs_layout,
@@ -4624,6 +4676,8 @@ static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 
@@ -4640,6 +4694,8 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 
@@ -4768,7 +4824,7 @@ static int qmp_pcie_init(struct phy *phy)
 		}
 	}
 
-	ret = reset_control_assert(qmp->nocsr_reset);
+	ret = reset_control_bulk_assert(cfg->num_nocsr_resets, qmp->nocsr_reset);
 	if (ret) {
 		dev_err(qmp->dev, "no-csr reset assert failed\n");
 		goto err_assert_reset;
@@ -4805,7 +4861,7 @@ static int qmp_pcie_exit(struct phy *phy)
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 
 	if (qmp->nocsr_reset)
-		reset_control_assert(qmp->nocsr_reset);
+		reset_control_bulk_assert(cfg->num_nocsr_resets, qmp->nocsr_reset);
 	else
 		reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 
@@ -4849,7 +4905,7 @@ static int qmp_pcie_power_on(struct phy *phy)
 	if (ret)
 		return ret;
 
-	ret = reset_control_deassert(qmp->nocsr_reset);
+	ret = reset_control_bulk_deassert(cfg->num_nocsr_resets, qmp->nocsr_reset);
 	if (ret) {
 		dev_err(qmp->dev, "no-csr reset deassert failed\n");
 		goto err_disable_pipe_clk;
@@ -4998,14 +5054,25 @@ static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
 	for (i = 0; i < cfg->num_resets; i++)
 		qmp->resets[i].id = cfg->reset_list[i];
 
-	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
+	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets,
+						    qmp->resets);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get resets\n");
 
-	qmp->nocsr_reset = devm_reset_control_get_optional_exclusive(dev, "phy_nocsr");
-	if (IS_ERR(qmp->nocsr_reset))
-		return dev_err_probe(dev, PTR_ERR(qmp->nocsr_reset),
-							"failed to get no-csr reset\n");
+	if (!cfg->num_nocsr_resets)
+		return 0;
+	qmp->nocsr_reset = devm_kcalloc(dev, cfg->num_nocsr_resets,
+				   sizeof(*qmp->nocsr_reset), GFP_KERNEL);
+	if (!qmp->nocsr_reset)
+		return -ENOMEM;
+
+	for (i = 0; i < cfg->num_nocsr_resets; i++)
+		qmp->nocsr_reset[i].id = cfg->nocsr_reset_list[i];
+
+	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_nocsr_resets,
+						    qmp->nocsr_reset);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get no-csr reset\n");
 
 	return 0;
 }
@@ -5520,7 +5587,7 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 		.data = &sm8750_qmp_gen3x2_pciephy_cfg,
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy",
-		.data = &sm8550_qmp_gen3x2_pciephy_cfg,
+		.data = &x1e80100_qmp_gen3x2_pciephy_cfg,
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy",
 		.data = &x1e80100_qmp_gen4x2_pciephy_cfg,

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
                   ` (3 preceding siblings ...)
  2026-05-19  5:47 ` [PATCH RFC v4 4/9] phy: qcom: qmp-pcie: Support multiple nocsr resets Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-05-20 16:25   ` Dmitry Baryshkov
  2026-05-19  5:47 ` [PATCH RFC v4 6/9] phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector Qiang Yu
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

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@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


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 6/9] phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
                   ` (4 preceding siblings ...)
  2026-05-19  5:47 ` [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 7/9] phy: qcom: qmp-pcie: Add link-mode multi-PHY probe infrastructure Qiang Yu
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

PHY instances sharing a single DT node each need their own clocks and
resets. The current driver uses a single hardcoded clock list with no
way to select per-instance resources. Add the infrastructure needed
before wiring up multi-PHY probe.

qmp_pciephy_secondary_clk_l[] and qmp_pcie_get_clk_list(id) are added
to select the appropriate clock list by PHY selector index.
qmp_pcie_num_clks() replaces the hard-coded ARRAY_SIZE(qmp_pciephy_clk_l)
in qmp_pcie_init(), qmp_pcie_exit(), and qmp_pcie_clk_init().

struct qmp_pcie::phy is replaced with an id field so each instance can
identify its index within a multi-PHY provider.

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

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 6332f15f78ca..b100302be12a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3335,7 +3335,7 @@ struct qmp_pcie {
 	struct reset_control_bulk_data *nocsr_reset;
 	struct regulator_bulk_data *vregs;
 
-	struct phy *phy;
+	u32 id;
 	int mode;
 
 	struct clk_fixed_rate pipe_clk_fixed;
@@ -3379,6 +3379,24 @@ static const char * const qmp_pciephy_clk_l[] = {
 	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux",
 };
 
+static const char * const qmp_pciephy_secondary_clk_l[] = {
+	"ref", "phy_b_aux", "cfg_ahb_b", "rchng_b",
+};
+
+static int qmp_pcie_get_clk_list(u32 id, const char * const **clk_list)
+{
+	switch (id) {
+	case QMP_PHY_SELECTOR_0:
+		*clk_list = qmp_pciephy_clk_l;
+		return ARRAY_SIZE(qmp_pciephy_clk_l);
+	case QMP_PHY_SELECTOR_1:
+		*clk_list = qmp_pciephy_secondary_clk_l;
+		return ARRAY_SIZE(qmp_pciephy_secondary_clk_l);
+	default:
+		return -EINVAL;
+	}
+}
+
 /* list of regulators */
 static const char * const qmp_phy_vreg_l[] = {
 	"vdda-phy", "vdda-pll",
@@ -4781,6 +4799,13 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
 	qmp_configure(qmp->dev, ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
 }
 
+static int qmp_pcie_num_clks(const struct qmp_pcie *qmp)
+{
+	const char * const *clk_list;
+
+	return qmp_pcie_get_clk_list(qmp->id, &clk_list);
+}
+
 static int qmp_pcie_init(struct phy *phy)
 {
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
@@ -4840,7 +4865,7 @@ static int qmp_pcie_init(struct phy *phy)
 		}
 	}
 
-	ret = clk_bulk_prepare_enable(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks);
+	ret = clk_bulk_prepare_enable(qmp_pcie_num_clks(qmp), qmp->clks);
 	if (ret)
 		goto err_assert_reset;
 
@@ -4865,7 +4890,7 @@ static int qmp_pcie_exit(struct phy *phy)
 	else
 		reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 
-	clk_bulk_disable_unprepare(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks);
+	clk_bulk_disable_unprepare(qmp_pcie_num_clks(qmp), qmp->clks);
 
 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 
@@ -5079,16 +5104,21 @@ static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
 
 static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
 {
+	const char * const *clk_list;
 	struct device *dev = qmp->dev;
-	int num = ARRAY_SIZE(qmp_pciephy_clk_l);
+	int num;
 	int i;
 
+	num = qmp_pcie_get_clk_list(qmp->id, &clk_list);
+	if (num < 0)
+		return num;
+
 	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
 	if (!qmp->clks)
 		return -ENOMEM;
 
 	for (i = 0; i < num; i++)
-		qmp->clks[i].id = qmp_pciephy_clk_l[i];
+		qmp->clks[i].id = clk_list[i];
 
 	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
 }
@@ -5414,6 +5444,7 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 	struct phy_provider *phy_provider;
 	struct device_node *np;
 	struct qmp_pcie *qmp;
+	struct phy *phy;
 	int ret;
 
 	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
@@ -5468,14 +5499,14 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 
 	qmp->mode = PHY_MODE_PCIE_RC;
 
-	qmp->phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
-	if (IS_ERR(qmp->phy)) {
-		ret = PTR_ERR(qmp->phy);
+	phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
+	if (IS_ERR(phy)) {
+		ret = PTR_ERR(phy);
 		dev_err(dev, "failed to create PHY: %d\n", ret);
 		goto err_node_put;
 	}
 
-	phy_set_drvdata(qmp->phy, qmp);
+	phy_set_drvdata(phy, qmp);
 
 	of_node_put(np);
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 7/9] phy: qcom: qmp-pcie: Add link-mode multi-PHY probe infrastructure
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
                   ` (5 preceding siblings ...)
  2026-05-19  5:47 ` [PATCH RFC v4 6/9] phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 8/9] phy: qcom: qmp-pcie: Add Glymur Gen5x8 PHY config and match data Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY Qiang Yu
  8 siblings, 0 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

Some QMP PCIe PHY hardware blocks support multiple link topologies (e.g.
x8 or x4+x4) selected via a TCSR register. The existing probe path has
no way to model this: it assumes a single cfg per DT node and instantiates
exactly one PHY.

Introduce a link-mode probe path where match data carries a per-mode cfg
table. At probe time the driver reads the DT-selected mode, looks up the
corresponding cfg array, and instantiates only the sub-PHYs required by
that mode. A #phy-cells = <1> provider is registered so consumers can
address individual sub-PHYs by index.

Three new data structures support this: qmp_pcie_data holds per-provider
state including the phy array, active mode, and regmap for the mode
register; qmp_pcie_link_mode_cfg maps a mode index to its per-PHY cfg
array; qmp_pcie_match_data is the top-level match data for link-mode
platforms.

On the probe side, qmp_pcie_probe() is reworked to instantiate one
qmp_pcie per active sub-PHY and register the appropriate clock and phy
providers. Per-instance DT parsing and phy object creation are factored
into helpers to keep the probe path clean. The active link mode is written
to the TCSR register at power-on to handle re-initialisation after
low-power transitions.

Platforms without a "link-mode" property continue to use the existing
single-cfg path and of_phy_simple_xlate unchanged.

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

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index b100302be12a..d78d57fb64d6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/phy/pcie.h>
@@ -3342,6 +3343,28 @@ struct qmp_pcie {
 	struct clk_fixed_rate aux_clk_fixed;
 };
 
+struct qmp_pcie_data {
+	struct phy **phys;
+	u32 active_link_mode;
+	int num_phys;
+	struct regmap *link_mode_map;
+	u32 link_mode_offset;
+	struct mutex link_mode_lock;
+
+	int num_pipe_outputs;
+	struct clk_fixed_rate *pipe_out_clks;
+};
+
+struct qmp_pcie_link_mode_cfg {
+	const struct qmp_phy_cfg *cfgs[QMP_PHY_SELECTOR_1 + 1];
+	u32 num_phys;
+};
+
+struct qmp_pcie_match_data {
+	const struct qmp_pcie_link_mode_cfg *mode_cfgs;
+	u32 num_modes;
+};
+
 static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
 {
 	u32 reg;
@@ -4897,6 +4920,27 @@ static int qmp_pcie_exit(struct phy *phy)
 	return 0;
 }
 
+static int qmp_pcie_config_link_mode(struct qmp_pcie *qmp)
+{
+	struct qmp_pcie_data *qmp_data = dev_get_drvdata(qmp->dev);
+	int ret;
+
+	if (!qmp_data)
+		return 0;
+
+	mutex_lock(&qmp_data->link_mode_lock);
+
+	ret = regmap_write(qmp_data->link_mode_map, qmp_data->link_mode_offset,
+			   qmp_data->active_link_mode);
+	if (ret)
+		goto out_unlock;
+
+out_unlock:
+	mutex_unlock(&qmp_data->link_mode_lock);
+
+	return ret;
+}
+
 static int qmp_pcie_power_on(struct phy *phy)
 {
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
@@ -4907,6 +4951,10 @@ static int qmp_pcie_power_on(struct phy *phy)
 	unsigned int mask, val;
 	int ret;
 
+	ret = qmp_pcie_config_link_mode(qmp);
+	if (ret)
+		return ret;
+
 	/*
 	 * Write CSR register for PHY that doesn't support no_csr reset or has not
 	 * been initialized.
@@ -5229,6 +5277,20 @@ static struct clk_hw *qmp_pcie_clk_hw_get(struct of_phandle_args *clkspec, void
 	return ERR_PTR(-EINVAL);
 }
 
+static struct clk_hw *qmp_pcie_clk_hw_get_link_mode(struct of_phandle_args *clkspec, void *data)
+{
+	struct qmp_pcie_data *qmp_data = data;
+	unsigned int idx = 0;
+
+	if (clkspec->args_count)
+		idx = clkspec->args[0];
+
+	if (idx < (unsigned int)qmp_data->num_pipe_outputs)
+		return &qmp_data->pipe_out_clks[idx].hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
 static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np)
 {
 	int ret;
@@ -5258,6 +5320,37 @@ static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np
 	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
 }
 
+static int qmp_pcie_register_clocks_link_mode(struct device *dev,
+					      struct device_node *np,
+					      struct qmp_pcie_data *qmp_data)
+{
+	int num_pipe_outputs;
+	int i;
+	int ret;
+
+	num_pipe_outputs = of_property_count_strings(np, "clock-output-names");
+	if (num_pipe_outputs < 0)
+		num_pipe_outputs = 1;
+
+	qmp_data->num_pipe_outputs = num_pipe_outputs;
+	qmp_data->pipe_out_clks = devm_kcalloc(dev, num_pipe_outputs,
+					       sizeof(*qmp_data->pipe_out_clks), GFP_KERNEL);
+	if (!qmp_data->pipe_out_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < num_pipe_outputs; i++) {
+		ret = __phy_pipe_clk_register(dev, np, i, &qmp_data->pipe_out_clks[i]);
+		if (ret)
+			return ret;
+	}
+
+	ret = of_clk_add_hw_provider(np, qmp_pcie_clk_hw_get_link_mode, qmp_data);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, phy_clk_release_provider, np);
+}
+
 static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np)
 {
 	struct platform_device *pdev = to_platform_device(qmp->dev);
@@ -5437,36 +5530,102 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 	return 0;
 }
 
-static int qmp_pcie_probe(struct platform_device *pdev)
+static int qmp_pcie_read_link_mode(struct device *dev, struct regmap **mode_map,
+				   u32 *mode_offset,
+				   u32 *active_link_mode,
+				   u32 *hw_link_mode)
 {
-	struct dev_pm_domain_list *pd_list;
-	struct device *dev = &pdev->dev;
-	struct phy_provider *phy_provider;
-	struct device_node *np;
-	struct qmp_pcie *qmp;
-	struct phy *phy;
+	struct regmap *map;
+	unsigned int args[2];
+	unsigned int mode;
 	int ret;
 
-	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
-	if (!qmp)
+	map = syscon_regmap_lookup_by_phandle_args(dev->of_node, "qcom,link-mode",
+						   ARRAY_SIZE(args), args);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+
+	ret = regmap_read(map, args[0], &mode);
+	if (ret)
+		return ret;
+
+	*mode_map = map;
+	*mode_offset = args[0];
+	*active_link_mode = args[1];
+	*hw_link_mode = mode;
+
+	return 0;
+}
+
+static int qmp_pcie_validate_link_mode(struct device *dev,
+				       const struct qmp_pcie_link_mode_cfg *mode_cfg,
+				       u32 active_link_mode, u32 hw_link_mode)
+{
+	int i;
+
+	if (active_link_mode == hw_link_mode)
+		return 0;
+
+	for (i = 0; i < mode_cfg->num_phys; i++) {
+		const struct qmp_phy_cfg *cfg = mode_cfg->cfgs[i];
+
+		if (!cfg || !cfg->tbls.serdes_num) {
+			dev_err(dev,
+				"missing phy settings for link-mode %u, logical-phy %d (hw=%u)\n",
+				active_link_mode, i, hw_link_mode);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int qmp_pcie_parse_dt_non_primary(struct qmp_pcie *qmp)
+{
+	struct platform_device *pdev = to_platform_device(qmp->dev);
+	struct device *dev = qmp->dev;
+	char *pipe_clk_name;
+	char *pipediv2_clk_name;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, qmp->id);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	pipe_clk_name = devm_kasprintf(dev, GFP_KERNEL, "pipe_%c", 'a' + qmp->id);
+	pipediv2_clk_name = devm_kasprintf(dev, GFP_KERNEL, "pipediv2_%c", 'a' + qmp->id);
+	if (!pipe_clk_name || !pipediv2_clk_name)
 		return -ENOMEM;
 
-	qmp->dev = dev;
+	return qmp_pcie_parse_dt_common(qmp, base, pipe_clk_name, pipediv2_clk_name);
+}
+
+static int qmp_pcie_probe_phy(struct qmp_pcie *qmp, struct device_node *np,
+			      struct phy **out_phy)
+{
+	struct device *dev = qmp->dev;
+	struct device_node *phy_np;
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	int ret;
 
-	qmp->cfg = of_device_get_match_data(dev);
-	if (!qmp->cfg)
+	if (!cfg)
 		return -EINVAL;
 
-	WARN_ON_ONCE(!qmp->cfg->pwrdn_ctrl);
-	WARN_ON_ONCE(!qmp->cfg->phy_status);
+	WARN_ON_ONCE(!cfg->pwrdn_ctrl);
+	WARN_ON_ONCE(!cfg->phy_status);
 
-	ret = devm_pm_domain_attach_list(dev, NULL, &pd_list);
-	if (ret < 0 && ret != -EEXIST) {
-		dev_err(dev, "Failed to attach power domain\n");
-		return ret;
-	}
+	qmp->mode = PHY_MODE_PCIE_RC;
 
-	ret = devm_pm_runtime_enable(dev);
+	if (qmp->id == QMP_PHY_SELECTOR_0) {
+		phy_np = np;
+		if (np != dev->of_node)
+			ret = qmp_pcie_parse_dt_legacy(qmp, np);
+		else
+			ret = qmp_pcie_parse_dt(qmp);
+	} else {
+		phy_np = dev->of_node;
+		ret = qmp_pcie_parse_dt_non_primary(qmp);
+	}
 	if (ret)
 		return ret;
 
@@ -5482,35 +5641,147 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	/* Check for legacy binding with child node. */
-	np = of_get_next_available_child(dev->of_node, NULL);
-	if (np) {
-		ret = qmp_pcie_parse_dt_legacy(qmp, np);
-	} else {
-		np = of_node_get(dev->of_node);
-		ret = qmp_pcie_parse_dt(qmp);
+	*out_phy = devm_phy_create(dev, phy_np, &qmp_pcie_phy_ops);
+	if (IS_ERR(*out_phy)) {
+		ret = PTR_ERR(*out_phy);
+		return ret;
 	}
-	if (ret)
-		goto err_node_put;
 
-	ret = qmp_pcie_register_clocks(qmp, np);
+	phy_set_drvdata(*out_phy, qmp);
+
+	return 0;
+}
+
+static struct phy *qmp_pcie_link_mode_xlate(struct device *dev,
+					    const struct of_phandle_args *args)
+{
+	struct qmp_pcie_data *qmp_data = dev_get_drvdata(dev);
+	unsigned int idx;
+
+	if (!qmp_data)
+		return ERR_PTR(-EINVAL);
+
+	if (args->args_count < 1)
+		return ERR_PTR(-EINVAL);
+
+	idx = args->args[0];
+
+	if (idx < (unsigned int)qmp_data->num_phys)
+		return qmp_data->phys[idx] ?: ERR_PTR(-EINVAL);
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int qmp_pcie_probe(struct platform_device *pdev)
+{
+	struct dev_pm_domain_list *pd_list;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = NULL;
+	struct phy_provider *phy_provider;
+	const struct qmp_phy_cfg *cfg = NULL;
+	const struct qmp_pcie_match_data *mode_data;
+	const struct qmp_pcie_link_mode_cfg *mode_cfg;
+	const void *match_data;
+	struct qmp_pcie_data *qmp_data = NULL;
+	struct regmap *link_mode_map = NULL;
+	struct qmp_pcie *qmp;
+	struct phy **phys;
+	u32 link_mode_offset = 0;
+	u32 hw_link_mode = 0;
+	u32 link_mode = 0;
+	bool use_link_mode = false;
+	int i;
+	int num_phys = 1;
+	int ret;
+
+	ret = devm_pm_domain_attach_list(dev, NULL, &pd_list);
+	if (ret < 0 && ret != -EEXIST) {
+		dev_err(dev, "Failed to attach power domain\n");
+		return ret;
+	}
+
+	ret = devm_pm_runtime_enable(dev);
 	if (ret)
-		goto err_node_put;
+		return ret;
 
-	qmp->mode = PHY_MODE_PCIE_RC;
+	match_data = of_device_get_match_data(dev);
+	if (!match_data)
+		return -EINVAL;
+
+	ret = qmp_pcie_read_link_mode(dev, &link_mode_map, &link_mode_offset,
+				      &link_mode, &hw_link_mode);
+	if (ret == -ENOENT)
+		cfg = match_data;
+	else if (ret)
+		return dev_err_probe(dev, ret, "failed to read qcom,link-mode\n");
+
+	if (!ret) {
+		use_link_mode = true;
+		mode_data = match_data;
+		if (link_mode >= mode_data->num_modes) {
+			dev_err(dev, "invalid qcom,link-mode: %u\n", link_mode);
+			return -EINVAL;
+		}
 
-	phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
-	if (IS_ERR(phy)) {
-		ret = PTR_ERR(phy);
-		dev_err(dev, "failed to create PHY: %d\n", ret);
-		goto err_node_put;
+		mode_cfg = &mode_data->mode_cfgs[link_mode];
+		num_phys = mode_cfg->num_phys;
+
+		ret = qmp_pcie_validate_link_mode(dev, mode_cfg, link_mode, hw_link_mode);
+		if (ret)
+			return ret;
 	}
 
-	phy_set_drvdata(phy, qmp);
+	qmp = devm_kcalloc(dev, num_phys, sizeof(*qmp), GFP_KERNEL);
+	if (!qmp)
+		return -ENOMEM;
 
-	of_node_put(np);
+	phys = devm_kcalloc(dev, num_phys, sizeof(*phys), GFP_KERNEL);
+	if (!phys)
+		return -ENOMEM;
+
+	if (use_link_mode) {
+		qmp_data = devm_kzalloc(dev, sizeof(*qmp_data), GFP_KERNEL);
+		if (!qmp_data)
+			return -ENOMEM;
+		qmp_data->phys = phys;
+		qmp_data->active_link_mode = link_mode;
+		qmp_data->link_mode_map = link_mode_map;
+		qmp_data->link_mode_offset = link_mode_offset;
+		qmp_data->num_phys = num_phys;
+		mutex_init(&qmp_data->link_mode_lock);
+	}
+
+	np = of_get_next_available_child(dev->of_node, NULL);
+	if (!np)
+		np = of_node_get(dev->of_node);
+
+	for (i = 0; i < num_phys; i++) {
+		const struct qmp_phy_cfg *phy_cfg = use_link_mode ? mode_cfg->cfgs[i] : cfg;
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+		qmp[i].dev = dev;
+		qmp[i].id = i;
+		qmp[i].cfg = phy_cfg;
+		ret = qmp_pcie_probe_phy(&qmp[i], np, &phys[i]);
+		if (ret)
+			goto err_node_put;
+	}
+
+	if (use_link_mode) {
+		ret = qmp_pcie_register_clocks_link_mode(dev, np, qmp_data);
+		if (ret)
+			goto err_node_put;
+
+		dev_set_drvdata(dev, qmp_data);
+		phy_provider = devm_of_phy_provider_register(dev, qmp_pcie_link_mode_xlate);
+	} else {
+		ret = qmp_pcie_register_clocks(qmp, np);
+		if (ret)
+			goto err_node_put;
+
+		phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	}
+
+	of_node_put(np);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 8/9] phy: qcom: qmp-pcie: Add Glymur Gen5x8 PHY config and match data
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
                   ` (6 preceding siblings ...)
  2026-05-19  5:47 ` [PATCH RFC v4 7/9] phy: qcom: qmp-pcie: Add link-mode multi-PHY probe infrastructure Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-05-19  5:47 ` [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY Qiang Yu
  8 siblings, 0 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

On Glymur, PCIe3 uses a single Gen5x8 QMP PHY hardware block that can
operate in two link topologies: x8 as one 8-lane PHY, or x4+x4 as two
independent 4-lane PHYs. Both topologies are served by the same DT node
since they share the same hardware block and TCSR mode register.

Per-topology reset and clock lists are introduced alongside the PHY
configs to reflect the different resource ownership in each mode. The
per-mode PHY configurations and match data are then added to wire the
two topologies into the link-mode infrastructure introduced in the
previous patch.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 80 +++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index d78d57fb64d6..d4aeb3e00955 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3399,7 +3399,7 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 
 /* list of clocks required by phy */
 static const char * const qmp_pciephy_clk_l[] = {
-	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux",
+	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux", "phy_b_aux",
 };
 
 static const char * const qmp_pciephy_secondary_clk_l[] = {
@@ -4746,6 +4746,81 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
 	.phy_status		= PHYSTATUS_4_20,
 };
 
+static const char * const qmp_pciephy_secondary_reset_l[] = {
+	"phy_b",
+};
+
+static const char * const qmp_pciephy_secondary_nocsr_reset_l[] = {
+	"phy_b_nocsr",
+};
+
+static const char * const glymur_pciephy_reset_l[] = {
+	"phy", "phy_b"
+};
+
+static const char * const glymur_pciephy_nocsr_reset_l[] = {
+	"phy_nocsr", "phy_b_nocsr",
+};
+
+static const struct qmp_phy_cfg glymur_qmp_gen5x4_secondary_pciephy_cfg = {
+	.lanes			= 4,
+
+	.offsets		= &qmp_pcie_offsets_v8_50,
+
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.reset_list		= qmp_pciephy_secondary_reset_l,
+	.num_resets		= ARRAY_SIZE(qmp_pciephy_secondary_reset_l),
+	.nocsr_reset_list	= qmp_pciephy_secondary_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(qmp_pciephy_secondary_nocsr_reset_l),
+
+	.regs			= pciephy_v8_50_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+};
+
+static const struct qmp_phy_cfg glymur_qmp_gen5x8_pciephy_cfg = {
+	.lanes = 8,
+
+	.offsets		= &qmp_pcie_offsets_v8_50,
+
+	.reset_list		= glymur_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(glymur_pciephy_reset_l),
+	.nocsr_reset_list	= glymur_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(glymur_pciephy_nocsr_reset_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+
+	.regs			= pciephy_v8_50_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+};
+
+static const struct qmp_pcie_link_mode_cfg glymur_qmp_gen5x8_mode_cfgs[] = {
+	[QMP_PCIE_GLYMUR_MODE_X8] = {
+		/* x8 */
+		.cfgs = {
+			[QMP_PHY_SELECTOR_0] = &glymur_qmp_gen5x8_pciephy_cfg,
+		},
+		.num_phys = 1,
+	},
+	[QMP_PCIE_GLYMUR_MODE_X4X4] = {
+		/* x4 + x4 */
+		.cfgs = {
+			[QMP_PHY_SELECTOR_0] = &glymur_qmp_gen5x4_pciephy_cfg,
+			[QMP_PHY_SELECTOR_1] = &glymur_qmp_gen5x4_secondary_pciephy_cfg,
+		},
+		.num_phys = 2,
+	},
+};
+
+static const struct qmp_pcie_match_data glymur_qmp_gen5x8_match_data = {
+	.mode_cfgs = glymur_qmp_gen5x8_mode_cfgs,
+	.num_modes = ARRAY_SIZE(glymur_qmp_gen5x8_mode_cfgs),
+};
+
 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -5797,6 +5872,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
 		.data = &glymur_qmp_gen5x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,glymur-qmp-gen5x8-pcie-phy",
+		.data = &glymur_qmp_gen5x8_match_data,
 	}, {
 		.compatible = "qcom,ipq6018-qmp-pcie-phy",
 		.data = &ipq6018_pciephy_cfg,

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY
  2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
                   ` (7 preceding siblings ...)
  2026-05-19  5:47 ` [PATCH RFC v4 8/9] phy: qcom: qmp-pcie: Add Glymur Gen5x8 PHY config and match data Qiang Yu
@ 2026-05-19  5:47 ` Qiang Yu
  2026-06-17 11:19   ` Konrad Dybcio
  8 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel

Glymur PCIe3 uses a single shared Gen5x8 QMP PHY block. Model PCIe3a and
PCIe3b as consumers of that shared PHY provider instead of separate PHY
nodes.

Update the DTS wiring to:
- point GCC PCIe3A/3B pipe parents to the shared PHY clock outputs
- add PCIe3a controller node and route PCIe3a/PCIe3b port phys to
  &pcie3_phy using two-cell PHY arguments
- configure the shared PHY node with link-mode and dual pipe outputs

Use QMP_PCIE_GLYMUR_MODE_* dt-binding macros for mode selection.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/glymur-crd.dtsi |   5 +
 arch/arm64/boot/dts/qcom/glymur.dtsi     | 333 ++++++++++++++++++++++++++++++-
 2 files changed, 336 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
index 6e2e06ae6c8a..72a86881d36c 100644
--- a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
@@ -451,6 +451,11 @@ &pcie3b {
 	pinctrl-names = "default";
 };
 
+&pcie3_phy {
+	vdda-phy-supply = <&vreg_l3c_e1_0p89>;
+	vdda-pll-supply = <&vreg_l2c_e1_1p14>;
+};
+
 &pcie3b_port0 {
 	reset-gpios = <&tlmm 155 GPIO_ACTIVE_LOW>;
 	wake-gpios = <&tlmm 157 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index 9ea297588d07..87530c233050 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -757,8 +757,8 @@ gcc: clock-controller@100000 {
 				 <0>,				/* USB 2 Phy PCIE PIPEGMUX */
 				 <0>,				/* USB 2 Phy PIPEGMUX */
 				 <0>,				/* USB 2 Phy SYS PCIE PIPEGMUX */
-				 <0>,				/* PCIe 3a */
-				 <0>,				/* PCIe 3b */
+				 <&pcie3_phy 0>,		/* PCIe 3a pipe */
+				 <&pcie3_phy 1>,		/* PCIe 3b pipe */
 				 <&pcie4_phy>,			/* PCIe 4 */
 				 <&pcie5_phy>,			/* PCIe 5 */
 				 <&pcie6_phy>,			/* PCIe 6 */
@@ -2285,6 +2285,59 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
 			};
 		};
 
+		pcie3_phy: phy@f00000 {
+			compatible = "qcom,glymur-qmp-gen5x8-pcie-phy";
+			reg = <0x0 0x00f00000 0x0 0x10000>,
+			      <0x0 0x00f10000 0x0 0x10000>;
+
+			clocks = <&gcc GCC_PCIE_PHY_3A_AUX_CLK>,
+				 <&gcc GCC_PCIE_3A_CFG_AHB_CLK>,
+				 <&tcsr TCSR_PCIE_3_CLKREF_EN>,
+				 <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3A_PIPE_CLK>,
+				 <&gcc GCC_PCIE_PHY_3B_AUX_CLK>,
+				 <&gcc GCC_PCIE_3B_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3B_PIPE_CLK>,
+				 <&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "phy_b_aux",
+				      "cfg_ahb_b",
+				      "rchng_b",
+				      "pipe_b",
+				      "pipediv2_b";
+
+			resets = <&gcc GCC_PCIE_3A_PHY_BCR>,
+				 <&gcc GCC_PCIE_3A_NOCSR_COM_PHY_BCR>,
+				 <&gcc GCC_PCIE_3B_PHY_BCR>,
+				 <&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>;
+			reset-names = "phy",
+				      "phy_nocsr",
+				      "phy_b",
+				      "phy_b_nocsr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>,
+					  <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>, <100000000>;
+
+			power-domains = <&gcc GCC_PCIE_3A_PHY_GDSC>,
+					<&gcc GCC_PCIE_3B_PHY_GDSC>;
+
+			qcom,link-mode = <&tcsr 0x5000 QMP_PCIE_GLYMUR_MODE_X4X4>;
+
+			#clock-cells = <1>;
+			clock-output-names = "pcie3a_pipe_clk",
+					     "pcie3b_pipe_clk";
+
+			#phy-cells = <1>;
+
+			status = "disabled";
+		};
+
 		usb_hs_phy: phy@fa0000 {
 			compatible = "qcom,glymur-m31-eusb2-phy",
 				     "qcom,sm8750-m31-eusb2-phy";
@@ -3647,6 +3700,282 @@ pcie3b_port0: pcie@0 {
 				reg = <0x0 0x0 0x0 0x0 0x0>;
 				bus-range = <0x01 0xff>;
 
+				phys = <&pcie3_phy 1>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+		};
+
+		pcie3a: pci@1c10000 {
+			device_type = "pci";
+			compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100";
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x70000000 0x0 0xf20>,
+			      <0x0 0x70000f40 0x0 0xa8>,
+			      <0x0 0x70001000 0x0 0x4000>,
+			      <0x0 0x70100000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x70000000 0x0 0x70300000 0x0 0x3d00000>,
+				 <0x03000000 0x7 0x00000000 0x7 0x00000000 0x0 0x40000000>,
+				 <0x43000000 0x70 0x00000000 0x70 0x00000000 0x10 0x00000000>;
+
+			bus-range = <0 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <3>;
+			num-lanes = <8>;
+
+			operating-points-v2 = <&pcie3a_opp_table>;
+
+			msi-map = <0x0 &gic_its 0xb0000 0x10000>;
+			iommu-map = <0x0 &pcie_smmu 0x30000 0x10000>;
+
+			interrupts = <GIC_SPI 948 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 949 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 845 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 847 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 942 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7",
+					  "global";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 0 0 848 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 849 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 850 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 851 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_3A_AUX_CLK>,
+				 <&gcc GCC_PCIE_3A_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3A_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_3A_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_3A_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_3A_WEST_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "noc_aggr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3A_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_west_anoc MASTER_PCIE_3A QCOM_ICC_TAG_ALWAYS
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					&pcie_west_slv_noc SLAVE_PCIE_3A QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			resets = <&gcc GCC_PCIE_3A_BCR>,
+				 <&gcc GCC_PCIE_3A_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_3A_GDSC>;
+
+			eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555
+						     0x5555 0x5555 0x5555 0x5555>;
+			eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+			eq-presets-32gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+
+			status = "disabled";
+
+			pcie3a_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* GEN 1 x1 */
+				opp-2500000-1 {
+					opp-hz = /bits/ 64 <2500000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <250000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 1 x2 */
+				opp-5000000-1 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 1 x4 */
+				opp-10000000-1 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 1 x8 */
+				opp-20000000-1 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 2 x1 */
+				opp-5000000-2 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 2 x2 */
+				opp-10000000-2 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 2 x4 */
+				opp-20000000-2 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 2 x8 */
+				opp-40000000-2 {
+					opp-hz = /bits/ 64 <40000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <4000000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000-3 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <984500 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 3 x2 */
+				opp-16000000-3 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1969000 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 3 x4 */
+				opp-32000000-3 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <3938000 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 3 x8 */
+				opp-64000000-3 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <7876000 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 4 x1 */
+				opp-16000000-4 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <1969000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 4 x2 */
+				opp-32000000-4 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <3938000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 4 x4 */
+				opp-64000000-4 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <7876000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 4 x8 */
+				opp-128000000-4 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <15753000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 5 x1 */
+				opp-32000000-5 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <3938000 1>;
+					opp-level = <5>;
+				};
+
+				/* GEN 5 x2 */
+				opp-64000000-5 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <7876000 1>;
+					opp-level = <5>;
+				};
+
+				/* GEN 5 x4 */
+				opp-128000000-5 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <15753000 1>;
+					opp-level = <5>;
+				};
+
+				/* GEN 5 x8 */
+				opp-256000000-5 {
+					opp-hz = /bits/ 64 <256000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <31506000 1>;
+					opp-level = <5>;
+				};
+			};
+
+			pcie3a_port0: pcie@0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				phys = <&pcie3_phy 0>;
+
 				#address-cells = <3>;
 				#size-cells = <2>;
 				ranges;

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-19  5:47 ` [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers Qiang Yu
@ 2026-05-20 16:25   ` Dmitry Baryshkov
  2026-05-22 10:57     ` Manivannan Sadhasivam
  0 siblings, 1 reply; 27+ messages in thread
From: Dmitry Baryshkov @ 2026-05-20 16:25 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
> 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@oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
>  1 file changed, 44 insertions(+), 32 deletions(-)

I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
end up having too many single-platform, single-device specifics which
don't apply to other platforms.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-20 16:25   ` Dmitry Baryshkov
@ 2026-05-22 10:57     ` Manivannan Sadhasivam
  2026-05-28 13:15       ` Qiang Yu
  2026-05-28 13:48       ` Dmitry Baryshkov
  0 siblings, 2 replies; 27+ messages in thread
From: Manivannan Sadhasivam @ 2026-05-22 10:57 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Qiang Yu, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio, linux-arm-msm, linux-phy, devicetree, linux-kernel

On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
> On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
> > 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@oss.qualcomm.com>
> > ---
> >  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
> >  1 file changed, 44 insertions(+), 32 deletions(-)
> 
> I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
> end up having too many single-platform, single-device specifics which
> don't apply to other platforms.
> 

I don't think that's really needed. This shared PHY concept is going to be
applicable to upcoming SoCs as well. And moreover, the split won't be clean
either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
driver and may only end up keeping very minimal code in
'phy-qcom-qmp-pcie-glymur'.

If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
move the SoC specific 'cfg' structs into a separate file as that's what
occupying majority of the space.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-22 10:57     ` Manivannan Sadhasivam
@ 2026-05-28 13:15       ` Qiang Yu
  2026-05-28 13:48       ` Dmitry Baryshkov
  1 sibling, 0 replies; 27+ messages in thread
From: Qiang Yu @ 2026-05-28 13:15 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Dmitry Baryshkov, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio, linux-arm-msm, linux-phy, devicetree, linux-kernel

On Fri, May 22, 2026 at 04:27:35PM +0530, Manivannan Sadhasivam wrote:
> On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
> > On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
> > > 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@oss.qualcomm.com>
> > > ---
> > >  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
> > >  1 file changed, 44 insertions(+), 32 deletions(-)
> > 
> > I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
> > end up having too many single-platform, single-device specifics which
> > don't apply to other platforms.
> > 
> 
> I don't think that's really needed. This shared PHY concept is going to be
> applicable to upcoming SoCs as well. And moreover, the split won't be clean
> either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
> driver and may only end up keeping very minimal code in
> 'phy-qcom-qmp-pcie-glymur'.
> 
> If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
> move the SoC specific 'cfg' structs into a separate file as that's what
> occupying majority of the space.
>
Can I move the SoC specific 'cfg' structs out of phy-qcom-qmp-pcie.c in
next version?

- Qiang Yu
> - Mani
> 
> -- 
> மணிவண்ணன் சதாசிவம்

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-22 10:57     ` Manivannan Sadhasivam
  2026-05-28 13:15       ` Qiang Yu
@ 2026-05-28 13:48       ` Dmitry Baryshkov
  2026-05-29  7:02         ` Qiang Yu
  1 sibling, 1 reply; 27+ messages in thread
From: Dmitry Baryshkov @ 2026-05-28 13:48 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Qiang Yu, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio, linux-arm-msm, linux-phy, devicetree, linux-kernel

On Fri, May 22, 2026 at 04:27:35PM +0530, Manivannan Sadhasivam wrote:
> On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
> > On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
> > > 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@oss.qualcomm.com>
> > > ---
> > >  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
> > >  1 file changed, 44 insertions(+), 32 deletions(-)
> > 
> > I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
> > end up having too many single-platform, single-device specifics which
> > don't apply to other platforms.
> > 
> 
> I don't think that's really needed. This shared PHY concept is going to be
> applicable to upcoming SoCs as well. And moreover, the split won't be clean
> either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
> driver and may only end up keeping very minimal code in
> 'phy-qcom-qmp-pcie-glymur'.

Then splitting makes even more sense. Let's not clutter the existing
driver with too many conditions and options.

> 
> If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
> move the SoC specific 'cfg' structs into a separate file as that's what
> occupying majority of the space.

No, it's really the 'shared' part.

> 
> - Mani
> 
> -- 
> மணிவண்ணன் சதாசிவம்
> 
> -- 
> linux-phy mailing list
> linux-phy@lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-28 13:48       ` Dmitry Baryshkov
@ 2026-05-29  7:02         ` Qiang Yu
  2026-06-16 14:05           ` Konrad Dybcio
  0 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-05-29  7:02 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Manivannan Sadhasivam, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio, linux-arm-msm, linux-phy, devicetree, linux-kernel

On Thu, May 28, 2026 at 04:48:24PM +0300, Dmitry Baryshkov wrote:
> On Fri, May 22, 2026 at 04:27:35PM +0530, Manivannan Sadhasivam wrote:
> > On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
> > > On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
> > > > 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@oss.qualcomm.com>
> > > > ---
> > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
> > > >  1 file changed, 44 insertions(+), 32 deletions(-)
> > > 
> > > I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
> > > end up having too many single-platform, single-device specifics which
> > > don't apply to other platforms.
> > > 
> > 
> > I don't think that's really needed. This shared PHY concept is going to be
> > applicable to upcoming SoCs as well. And moreover, the split won't be clean
> > either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
> > driver and may only end up keeping very minimal code in
> > 'phy-qcom-qmp-pcie-glymur'.
> 
> Then splitting makes even more sense. Let's not clutter the existing
> driver with too many conditions and options.
> 
> > 
> > If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
> > move the SoC specific 'cfg' structs into a separate file as that's what
> > occupying majority of the space.
> 
> No, it's really the 'shared' part.
>

To confirm, are you okay with some code duplication between the new
Glymur-specific driver and phy-qcom-qmp-pcie driver.

- Qiang Yu
> > 
> > - Mani
> > 
> > -- 
> > மணிவண்ணன் சதாசிவம்
> > 
> > -- 
> > linux-phy mailing list
> > linux-phy@lists.infradead.org
> > https://lists.infradead.org/mailman/listinfo/linux-phy
> 
> -- 
> With best wishes
> Dmitry

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible
  2026-05-19  5:47 ` [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible Qiang Yu
@ 2026-06-16 14:03   ` Konrad Dybcio
  2026-06-29  5:14     ` Qiang Yu
  0 siblings, 1 reply; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-16 14:03 UTC (permalink / raw)
  To: Qiang Yu, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel

On 5/19/26 7:47 AM, Qiang Yu wrote:
> The Glymur SoC uses a single PCIe Gen5 PHY hardware block for the
> PCIe3a/PCIe3b controllers. This block supports two link modes:
> 
> 1. x4+x4: two 4-lane PHY instances are exposed
> 2. x8: one 8-lane PHY instance is exposed
> 
> Add qcom,glymur-qmp-gen5x8-pcie-phy as a multi-mode PHY compatible and
> document the new link-mode property, which selects the active link mode
> via a TCSR syscon register.
> 
> Document the required clocks, resets, and power-domains for both PHY
> instances active in x8 mode. Use #phy-cells = <1> for this compatible,
> where the cell value is the PHY index within the active link mode.
> 
> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> ---

[...]

> @@ -68,20 +69,29 @@ properties:
>        - const: ref
>        - enum: [rchng, refgen]
>        - const: pipe
> -      - const: pipediv2
> +      - enum: [pipediv2, phy_b_aux]

I'm surprised to learn 3A doesnm'doesn't have a PIPE_DIV2 clk.. it does have
a non-div2 one though.

Seems like it's specifically not the case on Hamoa and Makena, so perhaps
it's better for maintainability if the Glymur list was separate

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-05-29  7:02         ` Qiang Yu
@ 2026-06-16 14:05           ` Konrad Dybcio
  2026-06-29  5:56             ` Qiang Yu
  0 siblings, 1 reply; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-16 14:05 UTC (permalink / raw)
  To: Qiang Yu, Dmitry Baryshkov
  Cc: Manivannan Sadhasivam, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio, linux-arm-msm, linux-phy, devicetree, linux-kernel

On 5/29/26 9:02 AM, Qiang Yu wrote:
> On Thu, May 28, 2026 at 04:48:24PM +0300, Dmitry Baryshkov wrote:
>> On Fri, May 22, 2026 at 04:27:35PM +0530, Manivannan Sadhasivam wrote:
>>> On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
>>>> On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
>>>>> 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@oss.qualcomm.com>
>>>>> ---
>>>>>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
>>>>>  1 file changed, 44 insertions(+), 32 deletions(-)
>>>>
>>>> I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
>>>> end up having too many single-platform, single-device specifics which
>>>> don't apply to other platforms.
>>>>
>>>
>>> I don't think that's really needed. This shared PHY concept is going to be
>>> applicable to upcoming SoCs as well. And moreover, the split won't be clean
>>> either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
>>> driver and may only end up keeping very minimal code in
>>> 'phy-qcom-qmp-pcie-glymur'.
>>
>> Then splitting makes even more sense. Let's not clutter the existing
>> driver with too many conditions and options.
>>
>>>
>>> If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
>>> move the SoC specific 'cfg' structs into a separate file as that's what
>>> occupying majority of the space.
>>
>> No, it's really the 'shared' part.
>>
> 
> To confirm, are you okay with some code duplication between the new
> Glymur-specific driver and phy-qcom-qmp-pcie driver.

That's a necessity, to some degree. See e.g. qmp-combo and qmp-usbc 

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros
  2026-05-19  5:47 ` [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros Qiang Yu
@ 2026-06-16 14:07   ` Konrad Dybcio
  2026-06-29  5:18     ` Qiang Yu
  0 siblings, 1 reply; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-16 14:07 UTC (permalink / raw)
  To: Qiang Yu, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel

On 5/19/26 7:47 AM, Qiang Yu wrote:
> Add two sets of constants to phy-qcom-qmp.h to support upcoming multiple
> link mode QMP PHY:
> 
> - QMP_PHY_SELECTOR_0 / QMP_PHY_SELECTOR_1: generic logical PHY index
>   values for QMP providers that expose multiple PHY instances under a
>   single DT node (i.e. #phy-cells = <1>).
> 
> - QMP_PCIE_GLYMUR_MODE_X8 / QMP_PCIE_GLYMUR_MODE_X4X4: link-mode
>   values for the Glymur Gen5x8 PCIe PHY "qcom,link-mode" syscon property,
>   selecting between the x8 single-PHY and x4+x4 dual-PHY topologies.
> 
> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> ---
>  include/dt-bindings/phy/phy-qcom-qmp.h | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/phy/phy-qcom-qmp.h
> index 6b43ea9e0051..befa76f8392f 100644
> --- a/include/dt-bindings/phy/phy-qcom-qmp.h
> +++ b/include/dt-bindings/phy/phy-qcom-qmp.h
> @@ -21,4 +21,12 @@
>  #define QMP_PCIE_PIPE_CLK		0
>  #define QMP_PCIE_PHY_AUX_CLK		1
>  
> +/* Generic QMP logical PHY selectors */
> +#define QMP_PHY_SELECTOR_0		0
> +#define QMP_PHY_SELECTOR_1		1

Is this for the second phy cell? FWIW I think it's fine to use raw
numbers as they're just indices (i.e. "nth bifurcated phy") anyway

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY
  2026-05-19  5:47 ` [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY Qiang Yu
@ 2026-06-17 11:19   ` Konrad Dybcio
  2026-06-29  5:05     ` Qiang Yu
  0 siblings, 1 reply; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-17 11:19 UTC (permalink / raw)
  To: Qiang Yu, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel

On 5/19/26 7:47 AM, Qiang Yu wrote:
> Glymur PCIe3 uses a single shared Gen5x8 QMP PHY block. Model PCIe3a and
> PCIe3b as consumers of that shared PHY provider instead of separate PHY
> nodes.
> 
> Update the DTS wiring to:
> - point GCC PCIe3A/3B pipe parents to the shared PHY clock outputs
> - add PCIe3a controller node and route PCIe3a/PCIe3b port phys to
>   &pcie3_phy using two-cell PHY arguments
> - configure the shared PHY node with link-mode and dual pipe outputs
> 
> Use QMP_PCIE_GLYMUR_MODE_* dt-binding macros for mode selection.
> 
> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> ---

[...]

> +		pcie3a: pci@1c10000 {
> +			device_type = "pci";
> +			compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100";
> +			reg = <0x0 0x01c10000 0x0 0x3000>,
> +			      <0x0 0x70000000 0x0 0xf20>,
> +			      <0x0 0x70000f40 0x0 0xa8>,
> +			      <0x0 0x70001000 0x0 0x4000>,
> +			      <0x0 0x70100000 0x0 0x100000>,
> +			      <0x0 0x01c13000 0x0 0x1000>;
> +			reg-names = "parf",
> +				    "dbi",
> +				    "elbi",
> +				    "atu",
> +				    "config",
> +				    "mhi";
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>,
> +				 <0x02000000 0x0 0x70000000 0x0 0x70300000 0x0 0x3d00000>,
> +				 <0x03000000 0x7 0x00000000 0x7 0x00000000 0x0 0x40000000>,
> +				 <0x43000000 0x70 0x00000000 0x70 0x00000000 0x10 0x00000000>;
> +
> +			bus-range = <0 0xff>;
> +
> +			dma-coherent;
> +
> +			linux,pci-domain = <3>;
> +			num-lanes = <8>;

Is it fine to keep num-lanes 8 here even for configurations with
bifurcated PHY?

I would assume so, given essentially this is a x8 host, whose 4
lanes may simply be effectively NC 

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY
  2026-06-17 11:19   ` Konrad Dybcio
@ 2026-06-29  5:05     ` Qiang Yu
  2026-06-29  9:20       ` Konrad Dybcio
  0 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-06-29  5:05 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On Wed, Jun 17, 2026 at 01:19:49PM +0200, Konrad Dybcio wrote:
> On 5/19/26 7:47 AM, Qiang Yu wrote:
> > Glymur PCIe3 uses a single shared Gen5x8 QMP PHY block. Model PCIe3a and
> > PCIe3b as consumers of that shared PHY provider instead of separate PHY
> > nodes.
> > 
> > Update the DTS wiring to:
> > - point GCC PCIe3A/3B pipe parents to the shared PHY clock outputs
> > - add PCIe3a controller node and route PCIe3a/PCIe3b port phys to
> >   &pcie3_phy using two-cell PHY arguments
> > - configure the shared PHY node with link-mode and dual pipe outputs
> > 
> > Use QMP_PCIE_GLYMUR_MODE_* dt-binding macros for mode selection.
> > 
> > Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> > ---
> 
> [...]
> 
> > +		pcie3a: pci@1c10000 {
> > +			device_type = "pci";
> > +			compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100";
> > +			reg = <0x0 0x01c10000 0x0 0x3000>,
> > +			      <0x0 0x70000000 0x0 0xf20>,
> > +			      <0x0 0x70000f40 0x0 0xa8>,
> > +			      <0x0 0x70001000 0x0 0x4000>,
> > +			      <0x0 0x70100000 0x0 0x100000>,
> > +			      <0x0 0x01c13000 0x0 0x1000>;
> > +			reg-names = "parf",
> > +				    "dbi",
> > +				    "elbi",
> > +				    "atu",
> > +				    "config",
> > +				    "mhi";
> > +			#address-cells = <3>;
> > +			#size-cells = <2>;
> > +			ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>,
> > +				 <0x02000000 0x0 0x70000000 0x0 0x70300000 0x0 0x3d00000>,
> > +				 <0x03000000 0x7 0x00000000 0x7 0x00000000 0x0 0x40000000>,
> > +				 <0x43000000 0x70 0x00000000 0x70 0x00000000 0x10 0x00000000>;
> > +
> > +			bus-range = <0 0xff>;
> > +
> > +			dma-coherent;
> > +
> > +			linux,pci-domain = <3>;
> > +			num-lanes = <8>;
> 
> Is it fine to keep num-lanes 8 here even for configurations with
> bifurcated PHY?
> 
> I would assume so, given essentially this is a x8 host, whose 4
> lanes may simply be effectively NC 
>
Actually, on existing platforms, the PCIe3a and PCIe3b controllers are
never enabled at the same time. When PCIe3a is exposed, it is always in an
x8 slot. But if we have a x4+x4 platform in future, we can simply override
num-lanes to 4 in the board.dts.

- Qiang Yu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible
  2026-06-16 14:03   ` Konrad Dybcio
@ 2026-06-29  5:14     ` Qiang Yu
  2026-06-29  9:20       ` Konrad Dybcio
  0 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-06-29  5:14 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On Tue, Jun 16, 2026 at 04:03:39PM +0200, Konrad Dybcio wrote:
> On 5/19/26 7:47 AM, Qiang Yu wrote:
> > The Glymur SoC uses a single PCIe Gen5 PHY hardware block for the
> > PCIe3a/PCIe3b controllers. This block supports two link modes:
> > 
> > 1. x4+x4: two 4-lane PHY instances are exposed
> > 2. x8: one 8-lane PHY instance is exposed
> > 
> > Add qcom,glymur-qmp-gen5x8-pcie-phy as a multi-mode PHY compatible and
> > document the new link-mode property, which selects the active link mode
> > via a TCSR syscon register.
> > 
> > Document the required clocks, resets, and power-domains for both PHY
> > instances active in x8 mode. Use #phy-cells = <1> for this compatible,
> > where the cell value is the PHY index within the active link mode.
> > 
> > Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> > ---
> 
> [...]
> 
> > @@ -68,20 +69,29 @@ properties:
> >        - const: ref
> >        - enum: [rchng, refgen]
> >        - const: pipe
> > -      - const: pipediv2
> > +      - enum: [pipediv2, phy_b_aux]
> 
> I'm surprised to learn 3A doesnm'doesn't have a PIPE_DIV2 clk.. it does have
> a non-div2 one though.
> 
> Seems like it's specifically not the case on Hamoa and Makena, so perhaps
> it's better for maintainability if the Glymur list was separate
>
Do you mean splitting Glymur out into a separate YAML file for the PCIe3
PHY? I'll add a new file if that's preferred and Krzysztof is on board.

- Qiang Yu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros
  2026-06-16 14:07   ` Konrad Dybcio
@ 2026-06-29  5:18     ` Qiang Yu
  2026-06-29  9:21       ` Konrad Dybcio
  0 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-06-29  5:18 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On Tue, Jun 16, 2026 at 04:07:27PM +0200, Konrad Dybcio wrote:
> On 5/19/26 7:47 AM, Qiang Yu wrote:
> > Add two sets of constants to phy-qcom-qmp.h to support upcoming multiple
> > link mode QMP PHY:
> > 
> > - QMP_PHY_SELECTOR_0 / QMP_PHY_SELECTOR_1: generic logical PHY index
> >   values for QMP providers that expose multiple PHY instances under a
> >   single DT node (i.e. #phy-cells = <1>).
> > 
> > - QMP_PCIE_GLYMUR_MODE_X8 / QMP_PCIE_GLYMUR_MODE_X4X4: link-mode
> >   values for the Glymur Gen5x8 PCIe PHY "qcom,link-mode" syscon property,
> >   selecting between the x8 single-PHY and x4+x4 dual-PHY topologies.
> > 
> > Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> > ---
> >  include/dt-bindings/phy/phy-qcom-qmp.h | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/phy/phy-qcom-qmp.h
> > index 6b43ea9e0051..befa76f8392f 100644
> > --- a/include/dt-bindings/phy/phy-qcom-qmp.h
> > +++ b/include/dt-bindings/phy/phy-qcom-qmp.h
> > @@ -21,4 +21,12 @@
> >  #define QMP_PCIE_PIPE_CLK		0
> >  #define QMP_PCIE_PHY_AUX_CLK		1
> >  
> > +/* Generic QMP logical PHY selectors */
> > +#define QMP_PHY_SELECTOR_0		0
> > +#define QMP_PHY_SELECTOR_1		1
> 
> Is this for the second phy cell? FWIW I think it's fine to use raw
> numbers as they're just indices (i.e. "nth bifurcated phy") anyway

I can't use lane numbers. In x4+x4 case, I need to tell phy the first 4
lanes or second 4 lanes are required.

- Qiang Yu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-06-16 14:05           ` Konrad Dybcio
@ 2026-06-29  5:56             ` Qiang Yu
  2026-06-29  9:21               ` Konrad Dybcio
  0 siblings, 1 reply; 27+ messages in thread
From: Qiang Yu @ 2026-06-29  5:56 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Dmitry Baryshkov, Manivannan Sadhasivam, Vinod Koul,
	Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Bjorn Andersson, Konrad Dybcio, linux-arm-msm,
	linux-phy, devicetree, linux-kernel

On Tue, Jun 16, 2026 at 04:05:43PM +0200, Konrad Dybcio wrote:
> On 5/29/26 9:02 AM, Qiang Yu wrote:
> > On Thu, May 28, 2026 at 04:48:24PM +0300, Dmitry Baryshkov wrote:
> >> On Fri, May 22, 2026 at 04:27:35PM +0530, Manivannan Sadhasivam wrote:
> >>> On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
> >>>> On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
> >>>>> 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@oss.qualcomm.com>
> >>>>> ---
> >>>>>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
> >>>>>  1 file changed, 44 insertions(+), 32 deletions(-)
> >>>>
> >>>> I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
> >>>> end up having too many single-platform, single-device specifics which
> >>>> don't apply to other platforms.
> >>>>
> >>>
> >>> I don't think that's really needed. This shared PHY concept is going to be
> >>> applicable to upcoming SoCs as well. And moreover, the split won't be clean
> >>> either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
> >>> driver and may only end up keeping very minimal code in
> >>> 'phy-qcom-qmp-pcie-glymur'.
> >>
> >> Then splitting makes even more sense. Let's not clutter the existing
> >> driver with too many conditions and options.
> >>
> >>>
> >>> If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
> >>> move the SoC specific 'cfg' structs into a separate file as that's what
> >>> occupying majority of the space.
> >>
> >> No, it's really the 'shared' part.
> >>
> > 
> > To confirm, are you okay with some code duplication between the new
> > Glymur-specific driver and phy-qcom-qmp-pcie driver.
> 
> That's a necessity, to some degree. See e.g. qmp-combo and qmp-usbc 
>
I've already prototyped a separate Glymur driver, and it turned out better
than expected — there's actually not much duplication. The parts that do
overlap aren't fully identical either; they tend to diverge once the
Glymur-specific handling is factored in.

Currently, I meet an issue when tesing the patch, and will post it after
fixing the issue.

- Qiang Yu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY
  2026-06-29  5:05     ` Qiang Yu
@ 2026-06-29  9:20       ` Konrad Dybcio
  0 siblings, 0 replies; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-29  9:20 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On 6/29/26 7:05 AM, Qiang Yu wrote:
> On Wed, Jun 17, 2026 at 01:19:49PM +0200, Konrad Dybcio wrote:
>> On 5/19/26 7:47 AM, Qiang Yu wrote:
>>> Glymur PCIe3 uses a single shared Gen5x8 QMP PHY block. Model PCIe3a and
>>> PCIe3b as consumers of that shared PHY provider instead of separate PHY
>>> nodes.
>>>
>>> Update the DTS wiring to:
>>> - point GCC PCIe3A/3B pipe parents to the shared PHY clock outputs
>>> - add PCIe3a controller node and route PCIe3a/PCIe3b port phys to
>>>   &pcie3_phy using two-cell PHY arguments
>>> - configure the shared PHY node with link-mode and dual pipe outputs
>>>
>>> Use QMP_PCIE_GLYMUR_MODE_* dt-binding macros for mode selection.
>>>
>>> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
>>> ---
>>
>> [...]
>>
>>> +		pcie3a: pci@1c10000 {
>>> +			device_type = "pci";
>>> +			compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100";
>>> +			reg = <0x0 0x01c10000 0x0 0x3000>,
>>> +			      <0x0 0x70000000 0x0 0xf20>,
>>> +			      <0x0 0x70000f40 0x0 0xa8>,
>>> +			      <0x0 0x70001000 0x0 0x4000>,
>>> +			      <0x0 0x70100000 0x0 0x100000>,
>>> +			      <0x0 0x01c13000 0x0 0x1000>;
>>> +			reg-names = "parf",
>>> +				    "dbi",
>>> +				    "elbi",
>>> +				    "atu",
>>> +				    "config",
>>> +				    "mhi";
>>> +			#address-cells = <3>;
>>> +			#size-cells = <2>;
>>> +			ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>,
>>> +				 <0x02000000 0x0 0x70000000 0x0 0x70300000 0x0 0x3d00000>,
>>> +				 <0x03000000 0x7 0x00000000 0x7 0x00000000 0x0 0x40000000>,
>>> +				 <0x43000000 0x70 0x00000000 0x70 0x00000000 0x10 0x00000000>;
>>> +
>>> +			bus-range = <0 0xff>;
>>> +
>>> +			dma-coherent;
>>> +
>>> +			linux,pci-domain = <3>;
>>> +			num-lanes = <8>;
>>
>> Is it fine to keep num-lanes 8 here even for configurations with
>> bifurcated PHY?
>>
>> I would assume so, given essentially this is a x8 host, whose 4
>> lanes may simply be effectively NC 
>>
> Actually, on existing platforms, the PCIe3a and PCIe3b controllers are
> never enabled at the same time. When PCIe3a is exposed, it is always in an
> x8 slot. But if we have a x4+x4 platform in future, we can simply override
> num-lanes to 4 in the board.dts.

My question is whether that will be necessary - if yes, sure, we
can do it, but if not, we can conclude on this early and not have
to fight over it in a couple months

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible
  2026-06-29  5:14     ` Qiang Yu
@ 2026-06-29  9:20       ` Konrad Dybcio
  0 siblings, 0 replies; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-29  9:20 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On 6/29/26 7:14 AM, Qiang Yu wrote:
> On Tue, Jun 16, 2026 at 04:03:39PM +0200, Konrad Dybcio wrote:
>> On 5/19/26 7:47 AM, Qiang Yu wrote:
>>> The Glymur SoC uses a single PCIe Gen5 PHY hardware block for the
>>> PCIe3a/PCIe3b controllers. This block supports two link modes:
>>>
>>> 1. x4+x4: two 4-lane PHY instances are exposed
>>> 2. x8: one 8-lane PHY instance is exposed
>>>
>>> Add qcom,glymur-qmp-gen5x8-pcie-phy as a multi-mode PHY compatible and
>>> document the new link-mode property, which selects the active link mode
>>> via a TCSR syscon register.
>>>
>>> Document the required clocks, resets, and power-domains for both PHY
>>> instances active in x8 mode. Use #phy-cells = <1> for this compatible,
>>> where the cell value is the PHY index within the active link mode.
>>>
>>> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
>>> ---
>>
>> [...]
>>
>>> @@ -68,20 +69,29 @@ properties:
>>>        - const: ref
>>>        - enum: [rchng, refgen]
>>>        - const: pipe
>>> -      - const: pipediv2
>>> +      - enum: [pipediv2, phy_b_aux]
>>
>> I'm surprised to learn 3A doesnm'doesn't have a PIPE_DIV2 clk.. it does have
>> a non-div2 one though.
>>
>> Seems like it's specifically not the case on Hamoa and Makena, so perhaps
>> it's better for maintainability if the Glymur list was separate
>>
> Do you mean splitting Glymur out into a separate YAML file for the PCIe3
> PHY? I'll add a new file if that's preferred and Krzysztof is on board.

I believe that may be the better approach since Glymur seems to be an
outlier with the clocks I mentioned above.  Krzysztof?

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros
  2026-06-29  5:18     ` Qiang Yu
@ 2026-06-29  9:21       ` Konrad Dybcio
  0 siblings, 0 replies; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-29  9:21 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-phy, devicetree, linux-kernel

On 6/29/26 7:18 AM, Qiang Yu wrote:
> On Tue, Jun 16, 2026 at 04:07:27PM +0200, Konrad Dybcio wrote:
>> On 5/19/26 7:47 AM, Qiang Yu wrote:
>>> Add two sets of constants to phy-qcom-qmp.h to support upcoming multiple
>>> link mode QMP PHY:
>>>
>>> - QMP_PHY_SELECTOR_0 / QMP_PHY_SELECTOR_1: generic logical PHY index
>>>   values for QMP providers that expose multiple PHY instances under a
>>>   single DT node (i.e. #phy-cells = <1>).
>>>
>>> - QMP_PCIE_GLYMUR_MODE_X8 / QMP_PCIE_GLYMUR_MODE_X4X4: link-mode
>>>   values for the Glymur Gen5x8 PCIe PHY "qcom,link-mode" syscon property,
>>>   selecting between the x8 single-PHY and x4+x4 dual-PHY topologies.
>>>
>>> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
>>> ---
>>>  include/dt-bindings/phy/phy-qcom-qmp.h | 8 ++++++++
>>>  1 file changed, 8 insertions(+)
>>>
>>> diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/phy/phy-qcom-qmp.h
>>> index 6b43ea9e0051..befa76f8392f 100644
>>> --- a/include/dt-bindings/phy/phy-qcom-qmp.h
>>> +++ b/include/dt-bindings/phy/phy-qcom-qmp.h
>>> @@ -21,4 +21,12 @@
>>>  #define QMP_PCIE_PIPE_CLK		0
>>>  #define QMP_PCIE_PHY_AUX_CLK		1
>>>  
>>> +/* Generic QMP logical PHY selectors */
>>> +#define QMP_PHY_SELECTOR_0		0
>>> +#define QMP_PHY_SELECTOR_1		1
>>
>> Is this for the second phy cell? FWIW I think it's fine to use raw
>> numbers as they're just indices (i.e. "nth bifurcated phy") anyway
> 
> I can't use lane numbers. In x4+x4 case, I need to tell phy the first 4
> lanes or second 4 lanes are required.

I didn't mean lane indices, but instead the same numbers you defined,
without the name. It's a minor difference though, and ultimately both
work for me.

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers
  2026-06-29  5:56             ` Qiang Yu
@ 2026-06-29  9:21               ` Konrad Dybcio
  0 siblings, 0 replies; 27+ messages in thread
From: Konrad Dybcio @ 2026-06-29  9:21 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Dmitry Baryshkov, Manivannan Sadhasivam, Vinod Koul,
	Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Bjorn Andersson, Konrad Dybcio, linux-arm-msm,
	linux-phy, devicetree, linux-kernel

On 6/29/26 7:56 AM, Qiang Yu wrote:
> On Tue, Jun 16, 2026 at 04:05:43PM +0200, Konrad Dybcio wrote:
>> On 5/29/26 9:02 AM, Qiang Yu wrote:
>>> On Thu, May 28, 2026 at 04:48:24PM +0300, Dmitry Baryshkov wrote:
>>>> On Fri, May 22, 2026 at 04:27:35PM +0530, Manivannan Sadhasivam wrote:
>>>>> On Wed, May 20, 2026 at 07:25:01PM +0300, Dmitry Baryshkov wrote:
>>>>>> On Mon, May 18, 2026 at 10:47:16PM -0700, Qiang Yu wrote:
>>>>>>> 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@oss.qualcomm.com>
>>>>>>> ---
>>>>>>>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 76 ++++++++++++++++++--------------
>>>>>>>  1 file changed, 44 insertions(+), 32 deletions(-)
>>>>>>
>>>>>> I'd suggest splitting the Glymur PHY to a separate driver. Otherwise we
>>>>>> end up having too many single-platform, single-device specifics which
>>>>>> don't apply to other platforms.
>>>>>>
>>>>>
>>>>> I don't think that's really needed. This shared PHY concept is going to be
>>>>> applicable to upcoming SoCs as well. And moreover, the split won't be clean
>>>>> either. We still need to reuse a lot of common logic in the 'phy-qcom-qmp-pcie'
>>>>> driver and may only end up keeping very minimal code in
>>>>> 'phy-qcom-qmp-pcie-glymur'.
>>>>
>>>> Then splitting makes even more sense. Let's not clutter the existing
>>>> driver with too many conditions and options.
>>>>
>>>>>
>>>>> If you are concerned about the file size of 'phy-qcom-qmp-pcie', then we should
>>>>> move the SoC specific 'cfg' structs into a separate file as that's what
>>>>> occupying majority of the space.
>>>>
>>>> No, it's really the 'shared' part.
>>>>
>>>
>>> To confirm, are you okay with some code duplication between the new
>>> Glymur-specific driver and phy-qcom-qmp-pcie driver.
>>
>> That's a necessity, to some degree. See e.g. qmp-combo and qmp-usbc 
>>
> I've already prototyped a separate Glymur driver, and it turned out better
> than expected — there's actually not much duplication. The parts that do
> overlap aren't fully identical either; they tend to diverge once the
> Glymur-specific handling is factored in.
> 
> Currently, I meet an issue when tesing the patch, and will post it after
> fixing the issue.

Good, thank you!

Konrad

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2026-06-29  9:21 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-19  5:47 [PATCH RFC v4 0/9] phy: qcom: qmp-pcie: Add link-mode based support for Glymur Gen5x8 PHY Qiang Yu
2026-05-19  5:47 ` [PATCH RFC v4 1/9] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add glymur-qmp-gen5x8-pcie-phy compatible Qiang Yu
2026-06-16 14:03   ` Konrad Dybcio
2026-06-29  5:14     ` Qiang Yu
2026-06-29  9:20       ` Konrad Dybcio
2026-05-19  5:47 ` [PATCH RFC v4 2/9] dt-bindings: phy: qcom-qmp: Add PHY selector and Glymur link-mode macros Qiang Yu
2026-06-16 14:07   ` Konrad Dybcio
2026-06-29  5:18     ` Qiang Yu
2026-06-29  9:21       ` Konrad Dybcio
2026-05-19  5:47 ` [PATCH RFC v4 3/9] phy: qcom: qmp-pcie: Add multiple power-domains support Qiang Yu
2026-05-19  5:47 ` [PATCH RFC v4 4/9] phy: qcom: qmp-pcie: Support multiple nocsr resets Qiang Yu
2026-05-19  5:47 ` [PATCH RFC v4 5/9] phy: qcom: qmp-pcie: Refactor pipe clk register and parse_dt helpers Qiang Yu
2026-05-20 16:25   ` Dmitry Baryshkov
2026-05-22 10:57     ` Manivannan Sadhasivam
2026-05-28 13:15       ` Qiang Yu
2026-05-28 13:48       ` Dmitry Baryshkov
2026-05-29  7:02         ` Qiang Yu
2026-06-16 14:05           ` Konrad Dybcio
2026-06-29  5:56             ` Qiang Yu
2026-06-29  9:21               ` Konrad Dybcio
2026-05-19  5:47 ` [PATCH RFC v4 6/9] phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector Qiang Yu
2026-05-19  5:47 ` [PATCH RFC v4 7/9] phy: qcom: qmp-pcie: Add link-mode multi-PHY probe infrastructure Qiang Yu
2026-05-19  5:47 ` [PATCH RFC v4 8/9] phy: qcom: qmp-pcie: Add Glymur Gen5x8 PHY config and match data Qiang Yu
2026-05-19  5:47 ` [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY Qiang Yu
2026-06-17 11:19   ` Konrad Dybcio
2026-06-29  5:05     ` Qiang Yu
2026-06-29  9:20       ` Konrad Dybcio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox