devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC
@ 2024-01-13  5:42 Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 01/13] dt-bindings: regulator: qcom,usb-vbus-regulator: add support for PMI632 Dmitry Baryshkov
                   ` (12 more replies)
  0 siblings, 13 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy,
	Vladimir Zapolskiy

The Qualcomm PMI632 PMIC (found on Qualcomm Robotics RB2 platform)
doesn't support USB Power Delivery. However this PMIC still supports
handling of the Type-C port (orientation detection, etc). Reuse exiting
qcom-pmic-typec driver to support Type-C related functionality of this
PMIC. Use this to enable USB-C connector support on the RB2 platform.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
Dmitry Baryshkov (12):
      dt-bindings: regulator: qcom,usb-vbus-regulator: add support for PMI632
      dt-bindings: usb: qcom,pmic-typec: add support for the PMI632 block
      dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: split from sc8280xp PHY schema
      dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data
      usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY
      usb: typec: qcom-pmic-typec: add support for PMI632 PMIC
      phy: qcom: qmp-usb: split USB-C PHY driver
      phy: qcom: qmp-usb: drop dual-lane handling
      phy: qcom: qmp-usbc: drop single lane handling
      phy: qcom: qmp-usbc: add support for the Type-C handling
      arm64: dts: qcom: pmi632: define USB-C related blocks
      arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling

Vladimir Zapolskiy (1):
      arm64: dts: qcom: sm6115: drop pipe clock selection

 .../bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml    |  171 +++
 .../phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml        |   22 -
 .../regulator/qcom,usb-vbus-regulator.yaml         |    9 +-
 .../devicetree/bindings/usb/qcom,pmic-typec.yaml   |   28 +-
 arch/arm64/boot/dts/qcom/pmi632.dtsi               |   29 +
 arch/arm64/boot/dts/qcom/qrb4210-rb2.dts           |   60 +-
 arch/arm64/boot/dts/qcom/sm6115.dtsi               |   39 +-
 drivers/phy/qualcomm/Makefile                      |    2 +-
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c            |  323 +-----
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c           | 1202 ++++++++++++++++++++
 drivers/usb/typec/tcpm/qcom/Makefile               |    3 +-
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c      |  126 +-
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h      |   25 +
 .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c    |  155 ++-
 .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h    |   92 +-
 .../typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c   |   67 ++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h |    4 +-
 17 files changed, 1805 insertions(+), 552 deletions(-)
---
base-commit: 9e21984d62c56a0f6d1fc6f76b646212cfd7fe88
change-id: 20240112-pmi632-typec-4c7533092387

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>


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

* [PATCH 01/13] dt-bindings: regulator: qcom,usb-vbus-regulator: add support for PMI632
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 02/13] dt-bindings: usb: qcom,pmic-typec: add support for the PMI632 block Dmitry Baryshkov
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

The VBUS register block on the PMI632 PMIC shares the design with the
PM8150B one. Define corresponding compatible string, having the
qcom,pm8150b-vbus-reg as a fallback.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 .../devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml   | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
index 534f87e98716..66dcd5ce03e6 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
@@ -19,8 +19,13 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - qcom,pm8150b-vbus-reg
+    oneOf:
+      - enum:
+          - qcom,pm8150b-vbus-reg
+      - items:
+          - enum:
+              - qcom,pmi632-vbus-reg
+          - const: qcom,pm8150b-vbus-reg
 
   reg:
     maxItems: 1

-- 
2.39.2


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

* [PATCH 02/13] dt-bindings: usb: qcom,pmic-typec: add support for the PMI632 block
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 01/13] dt-bindings: regulator: qcom,usb-vbus-regulator: add support for PMI632 Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 03/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: split from sc8280xp PHY schema Dmitry Baryshkov
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

The PMI632 PMIC has the same Type-C register block as the PM8150B.
However this PMIC doesn't support USB Power Delivery. As such it doesn't
have the second region used by the existing pm8150b bindings. Add if
clauses to handle the PMI632 usecase.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 .../devicetree/bindings/usb/qcom,pmic-typec.yaml   | 28 +++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
index 55df3129a0bc..e9f44750d580 100644
--- a/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
@@ -15,6 +15,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,pmi632-typec
       - qcom,pm8150b-typec
 
   connector:
@@ -24,9 +25,11 @@ properties:
 
   reg:
     description: Type-C port and pdphy SPMI register base offsets
+    minItems: 1
     maxItems: 2
 
   interrupts:
+    minItems: 8
     items:
       - description: Type-C CC attach notification, VBUS error, tCCDebounce done
       - description: Type-C VCONN powered
@@ -46,6 +49,7 @@ properties:
       - description: Power Domain Fast Role Swap event
 
   interrupt-names:
+    minItems: 8
     items:
       - const: or-rid-detect-change
       - const: vpd-detect
@@ -81,7 +85,29 @@ required:
   - interrupts
   - interrupt-names
   - vdd-vbus-supply
-  - vdd-pdphy-supply
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,pmi632-typec
+    then:
+      properties:
+        interrupts:
+          maxItems: 8
+        interrupt-names:
+          maxItems: 8
+        vdd-pdphy-supply: false
+    else:
+      properties:
+        interrupts:
+          minItems: 16
+        interrupt-names:
+          maxItems: 16
+      required:
+        - vdd-pdphy-supply
 
 additionalProperties: false
 

-- 
2.39.2


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

* [PATCH 03/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: split from sc8280xp PHY schema
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 01/13] dt-bindings: regulator: qcom,usb-vbus-regulator: add support for PMI632 Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 02/13] dt-bindings: usb: qcom,pmic-typec: add support for the PMI632 block Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 04/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data Dmitry Baryshkov
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

In preparation to defining the USB-C handling on MSM8998, QCM2290 and
SM6115 split existing QMP USB3 PHY schema into pure USB3 and USB-C
schema definitions.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 .../bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml    | 132 +++++++++++++++++++++
 .../phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml        |  22 ----
 2 files changed, 132 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
new file mode 100644
index 000000000000..868fabd44d72
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
@@ -0,0 +1,132 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,msm8998-qmp-usb3-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm QMP PHY controller (USB, MSM8998)
+
+maintainers:
+  - Vinod Koul <vkoul@kernel.org>
+
+description:
+  The QMP PHY controller supports physical layer functionality for USB-C on
+  several Qualcomm chipsets.
+
+properties:
+  compatible:
+    enum:
+      - qcom,msm8998-qmp-usb3-phy
+      - qcom,qcm2290-qmp-usb3-phy
+      - qcom,sm6115-qmp-usb3-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 4
+
+  clock-names:
+    maxItems: 4
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: phy
+      - const: phy_phy
+
+  vdda-phy-supply: true
+
+  vdda-pll-supply: true
+
+  "#clock-cells":
+    const: 0
+
+  clock-output-names:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+  - "#clock-cells"
+  - clock-output-names
+  - "#phy-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,msm8998-qmp-usb3-phy
+    then:
+      properties:
+        clocks:
+          maxItems: 4
+        clock-names:
+          items:
+            - const: aux
+            - const: ref
+            - const: cfg_ahb
+            - const: pipe
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcm2290-qmp-usb3-phy
+              - qcom,sm6115-qmp-usb3-phy
+    then:
+      properties:
+        clocks:
+          maxItems: 4
+        clock-names:
+          items:
+            - const: cfg_ahb
+            - const: ref
+            - const: com_aux
+            - const: pipe
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-msm8998.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+
+    phy@c010000 {
+      compatible = "qcom,msm8998-qmp-usb3-phy";
+      reg = <0x0c010000 0x1000>;
+
+      clocks = <&gcc GCC_USB3_PHY_AUX_CLK>,
+               <&gcc GCC_USB3_CLKREF_CLK>,
+               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+               <&gcc GCC_USB3_PHY_PIPE_CLK>;
+      clock-names = "aux",
+                    "ref",
+                    "cfg_ahb",
+                    "pipe";
+      clock-output-names = "usb3_phy_pipe_clk_src";
+      #clock-cells = <0>;
+      #phy-cells = <0>;
+
+      resets = <&gcc GCC_USB3_PHY_BCR>,
+               <&gcc GCC_USB3PHY_PHY_BCR>;
+      reset-names = "phy",
+                    "phy_phy";
+
+      vdda-phy-supply = <&vreg_l1a_0p875>;
+      vdda-pll-supply = <&vreg_l2a_1p2>;
+    };
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
index 15d82c67f157..1e2d4ddc5391 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
@@ -20,15 +20,12 @@ properties:
       - qcom,ipq8074-qmp-usb3-phy
       - qcom,ipq9574-qmp-usb3-phy
       - qcom,msm8996-qmp-usb3-phy
-      - qcom,msm8998-qmp-usb3-phy
-      - qcom,qcm2290-qmp-usb3-phy
       - qcom,sa8775p-qmp-usb3-uni-phy
       - qcom,sc8280xp-qmp-usb3-uni-phy
       - qcom,sdm845-qmp-usb3-uni-phy
       - qcom,sdx55-qmp-usb3-uni-phy
       - qcom,sdx65-qmp-usb3-uni-phy
       - qcom,sdx75-qmp-usb3-uni-phy
-      - qcom,sm6115-qmp-usb3-phy
       - qcom,sm8150-qmp-usb3-uni-phy
       - qcom,sm8250-qmp-usb3-uni-phy
       - qcom,sm8350-qmp-usb3-uni-phy
@@ -93,7 +90,6 @@ allOf:
               - qcom,ipq8074-qmp-usb3-phy
               - qcom,ipq9574-qmp-usb3-phy
               - qcom,msm8996-qmp-usb3-phy
-              - qcom,msm8998-qmp-usb3-phy
               - qcom,sdx55-qmp-usb3-uni-phy
               - qcom,sdx65-qmp-usb3-uni-phy
               - qcom,sdx75-qmp-usb3-uni-phy
@@ -108,24 +104,6 @@ allOf:
             - const: cfg_ahb
             - const: pipe
 
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - qcom,qcm2290-qmp-usb3-phy
-              - qcom,sm6115-qmp-usb3-phy
-    then:
-      properties:
-        clocks:
-          maxItems: 4
-        clock-names:
-          items:
-            - const: cfg_ahb
-            - const: ref
-            - const: com_aux
-            - const: pipe
-
   - if:
       properties:
         compatible:

-- 
2.39.2


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

* [PATCH 04/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (2 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 03/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: split from sc8280xp PHY schema Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 12:09   ` Bryan O'Donoghue
  2024-01-13  5:42 ` [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY Dmitry Baryshkov
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

Extend the Qualcomm USB-C QMP PHY schema with the USB-C related entry
points: orientation-switch property and USB-C connection graph.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 .../bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml    | 39 ++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
index 868fabd44d72..da5d4cbca24c 100644
--- a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
@@ -50,6 +50,22 @@ properties:
   "#phy-cells":
     const: 0
 
+  orientation-switch:
+    description:
+      Flag the PHY as possible handler of USB Type-C orientation switching
+    type: boolean
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output endpoint of the PHY
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Incoming endpoint from the USB controller
+
 required:
   - compatible
   - reg
@@ -129,4 +145,27 @@ examples:
 
       vdda-phy-supply = <&vreg_l1a_0p875>;
       vdda-pll-supply = <&vreg_l2a_1p2>;
+
+      orientation-switch;
+
+      ports {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port@0 {
+          reg = <0>;
+
+          endpoint {
+            remote-endpoint = <&pmic_typec_mux_in>;
+          };
+        };
+
+        port@1 {
+          reg = <1>;
+
+          endpoint {
+            remote-endpoint = <&usb_dwc3_ss>;
+          };
+        };
+      };
     };

-- 
2.39.2


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

* [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (3 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 04/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:32   ` Konrad Dybcio
  2024-01-13 13:43   ` Bryan O'Donoghue
  2024-01-13  5:42 ` [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC Dmitry Baryshkov
                   ` (7 subsequent siblings)
  12 siblings, 2 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

Rework Qualcomm PMIC TCPM driver to allow different platform-specific
implementations of the PD PHY interface. While majority of platforms
has the same of register for the PD PHY, some obscure ones (PMI632) do
not have real PD PHY support. Add proper interface between the main
module and the PD PHY backend to allow switching the PD PHY
implementation.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c      | 100 ++-----------
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h      |  25 ++++
 .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c    | 155 ++++++++++++++++++---
 .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h    |  90 +-----------
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h |   4 +-
 5 files changed, 178 insertions(+), 196 deletions(-)

diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
index 1a2b4bddaa97..4f2dbf20da12 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
@@ -20,26 +20,15 @@
 
 #include <drm/bridge/aux-bridge.h>
 
+#include "qcom_pmic_typec.h"
 #include "qcom_pmic_typec_pdphy.h"
 #include "qcom_pmic_typec_port.h"
 
 struct pmic_typec_resources {
-	struct pmic_typec_pdphy_resources	*pdphy_res;
+	const struct pmic_typec_pdphy_resources	*pdphy_res;
 	struct pmic_typec_port_resources	*port_res;
 };
 
-struct pmic_typec {
-	struct device		*dev;
-	struct tcpm_port	*tcpm_port;
-	struct tcpc_dev		tcpc;
-	struct pmic_typec_pdphy	*pmic_typec_pdphy;
-	struct pmic_typec_port	*pmic_typec_port;
-	bool			vbus_enabled;
-	struct mutex		lock;		/* VBUS state serialization */
-};
-
-#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
-
 static int qcom_pmic_typec_get_vbus(struct tcpc_dev *tcpc)
 {
 	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
@@ -116,34 +105,6 @@ static int qcom_pmic_typec_start_toggling(struct tcpc_dev *tcpc,
 						   port_type, cc);
 }
 
-static int qcom_pmic_typec_set_roles(struct tcpc_dev *tcpc, bool attached,
-				     enum typec_role power_role,
-				     enum typec_data_role data_role)
-{
-	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
-
-	return qcom_pmic_typec_pdphy_set_roles(tcpm->pmic_typec_pdphy,
-					       data_role, power_role);
-}
-
-static int qcom_pmic_typec_set_pd_rx(struct tcpc_dev *tcpc, bool on)
-{
-	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
-
-	return qcom_pmic_typec_pdphy_set_pd_rx(tcpm->pmic_typec_pdphy, on);
-}
-
-static int qcom_pmic_typec_pd_transmit(struct tcpc_dev *tcpc,
-				       enum tcpm_transmit_type type,
-				       const struct pd_message *msg,
-				       unsigned int negotiated_rev)
-{
-	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
-
-	return qcom_pmic_typec_pdphy_pd_transmit(tcpm->pmic_typec_pdphy, type,
-						 msg, negotiated_rev);
-}
-
 static int qcom_pmic_typec_init(struct tcpc_dev *tcpc)
 {
 	return 0;
@@ -177,9 +138,6 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 	tcpm->tcpc.set_polarity = qcom_pmic_typec_set_polarity;
 	tcpm->tcpc.set_vconn = qcom_pmic_typec_set_vconn;
 	tcpm->tcpc.start_toggling = qcom_pmic_typec_start_toggling;
-	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_set_pd_rx;
-	tcpm->tcpc.set_roles = qcom_pmic_typec_set_roles;
-	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pd_transmit;
 
 	regmap = dev_get_regmap(dev->parent, NULL);
 	if (!regmap) {
@@ -195,17 +153,13 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 	if (IS_ERR(tcpm->pmic_typec_port))
 		return PTR_ERR(tcpm->pmic_typec_port);
 
-	tcpm->pmic_typec_pdphy = qcom_pmic_typec_pdphy_alloc(dev);
-	if (IS_ERR(tcpm->pmic_typec_pdphy))
-		return PTR_ERR(tcpm->pmic_typec_pdphy);
-
 	ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
 					 res->port_res, regmap, base[0]);
 	if (ret)
 		return ret;
 
-	ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm->pmic_typec_pdphy,
-					  res->pdphy_res, regmap, base[1]);
+	ret = res->pdphy_probe(pdev, tcpm,
+			       res->pdphy_res, regmap, base[1]);
 	if (ret)
 		return ret;
 
@@ -231,10 +185,11 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 	if (ret)
 		goto fwnode_remove;
 
-	ret = qcom_pmic_typec_pdphy_start(tcpm->pmic_typec_pdphy,
-					  tcpm->tcpm_port);
-	if (ret)
-		goto fwnode_remove;
+	if (tcpm->pdphy_start) {
+		ret = tcpm->pdphy_start(tcpm, tcpm->tcpm_port);
+		if (ret)
+			goto fwnode_remove;
+	}
 
 	return 0;
 
@@ -248,46 +203,13 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
 {
 	struct pmic_typec *tcpm = platform_get_drvdata(pdev);
 
-	qcom_pmic_typec_pdphy_stop(tcpm->pmic_typec_pdphy);
+	if (tcpm->pdphy_stop)
+		tcpm->pdphy_stop(tcpm);
 	qcom_pmic_typec_port_stop(tcpm->pmic_typec_port);
 	tcpm_unregister_port(tcpm->tcpm_port);
 	fwnode_remove_software_node(tcpm->tcpc.fwnode);
 }
 
-static struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
-	.irq_params = {
-		{
-			.virq = PMIC_PDPHY_SIG_TX_IRQ,
-			.irq_name = "sig-tx",
-		},
-		{
-			.virq = PMIC_PDPHY_SIG_RX_IRQ,
-			.irq_name = "sig-rx",
-		},
-		{
-			.virq = PMIC_PDPHY_MSG_TX_IRQ,
-			.irq_name = "msg-tx",
-		},
-		{
-			.virq = PMIC_PDPHY_MSG_RX_IRQ,
-			.irq_name = "msg-rx",
-		},
-		{
-			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
-			.irq_name = "msg-tx-failed",
-		},
-		{
-			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
-			.irq_name = "msg-tx-discarded",
-		},
-		{
-			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
-			.irq_name = "msg-rx-discarded",
-		},
-	},
-	.nr_irqs = 7,
-};
-
 static struct pmic_typec_port_resources pm8150b_port_res = {
 	.irq_params = {
 		{
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
new file mode 100644
index 000000000000..da035916c12a
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+
+#ifndef __QCOM_PMIC_TYPEC_H__
+#define __QCOM_PMIC_TYPEC_H__
+
+struct pmic_typec {
+	struct device		*dev;
+	struct tcpm_port	*tcpm_port;
+	struct tcpc_dev		tcpc;
+	struct pmic_typec_pdphy	*pmic_typec_pdphy;
+	struct pmic_typec_port	*pmic_typec_port;
+	bool			vbus_enabled;
+	struct mutex		lock;		/* VBUS state serialization */
+
+	int (*pdphy_start)(struct pmic_typec *tcpm,
+			   struct tcpm_port *tcpm_port);
+	void (*pdphy_stop)(struct pmic_typec *tcpm);
+};
+
+#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
+
+#endif
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
index 52c81378e36e..40511ce86a34 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
@@ -14,8 +14,74 @@
 #include <linux/slab.h>
 #include <linux/usb/pd.h>
 #include <linux/usb/tcpm.h>
+#include "qcom_pmic_typec.h"
 #include "qcom_pmic_typec_pdphy.h"
 
+/* PD PHY register offsets and bit fields */
+#define USB_PDPHY_MSG_CONFIG_REG	0x40
+#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
+#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
+#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
+
+#define USB_PDPHY_EN_CONTROL_REG	0x46
+#define CONTROL_ENABLE			BIT(0)
+
+#define USB_PDPHY_RX_STATUS_REG		0x4A
+#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
+
+#define USB_PDPHY_FRAME_FILTER_REG	0x4C
+#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
+#define FRAME_FILTER_EN_SOP		BIT(0)
+
+#define USB_PDPHY_TX_SIZE_REG		0x42
+#define TX_SIZE_MASK			0xF
+
+#define USB_PDPHY_TX_CONTROL_REG	0x44
+#define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
+#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
+#define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
+#define TX_CONTROL_SEND_SIGNAL		BIT(1)
+#define TX_CONTROL_SEND_MSG		BIT(0)
+
+#define USB_PDPHY_RX_SIZE_REG		0x48
+
+#define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
+#define RX_BUFFER_TOKEN			BIT(0)
+
+#define USB_PDPHY_BIST_MODE_REG		0x4E
+#define BIST_MODE_MASK			0xF
+#define BIST_ENABLE			BIT(7)
+#define PD_MSG_BIST			0x3
+#define PD_BIST_TEST_DATA_MODE		0x8
+
+#define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
+#define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
+
+#define USB_PDPHY_RX_BUFFER_REG		0x80
+
+/* VDD regulator */
+#define VDD_PDPHY_VOL_MIN		2800000	/* uV */
+#define VDD_PDPHY_VOL_MAX		3300000	/* uV */
+#define VDD_PDPHY_HPM_LOAD		3000	/* uA */
+
+/* Message Spec Rev field */
+#define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
+
+/* timers */
+#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
+#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
+
+/* Interrupt numbers */
+#define PMIC_PDPHY_SIG_TX_IRQ		0x0
+#define PMIC_PDPHY_SIG_RX_IRQ		0x1
+#define PMIC_PDPHY_MSG_TX_IRQ		0x2
+#define PMIC_PDPHY_MSG_RX_IRQ		0x3
+#define PMIC_PDPHY_MSG_TX_FAIL_IRQ	0x4
+#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ	0x5
+#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ	0x6
+#define PMIC_PDPHY_FR_SWAP_IRQ		0x7
+
+
 struct pmic_typec_pdphy_irq_data {
 	int				virq;
 	int				irq;
@@ -231,11 +297,13 @@ qcom_pmic_typec_pdphy_pd_transmit_payload(struct pmic_typec_pdphy *pmic_typec_pd
 	return ret;
 }
 
-int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
-				      enum tcpm_transmit_type type,
-				      const struct pd_message *msg,
-				      unsigned int negotiated_rev)
+static int qcom_pmic_typec_pdphy_pd_transmit(struct tcpc_dev *tcpc,
+					     enum tcpm_transmit_type type,
+					     const struct pd_message *msg,
+					     unsigned int negotiated_rev)
 {
+	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
 	struct device *dev = pmic_typec_pdphy->dev;
 	int ret;
 
@@ -336,8 +404,10 @@ static irqreturn_t qcom_pmic_typec_pdphy_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on)
+static int qcom_pmic_typec_pdphy_set_pd_rx(struct tcpc_dev *tcpc, bool on)
 {
+	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
 	unsigned long flags;
 	int ret;
 
@@ -353,9 +423,12 @@ int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, b
 	return ret;
 }
 
-int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
-				    bool data_role_host, bool power_role_src)
+static int qcom_pmic_typec_pdphy_set_roles(struct tcpc_dev *tcpc, bool attached,
+					   enum typec_role power_role,
+					   enum typec_data_role data_role)
 {
+	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
 	struct device *dev = pmic_typec_pdphy->dev;
 	unsigned long flags;
 	int ret;
@@ -366,12 +439,13 @@ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
 				 pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
 				 MSG_CONFIG_PORT_DATA_ROLE |
 				 MSG_CONFIG_PORT_POWER_ROLE,
-				 data_role_host << 3 | power_role_src << 2);
+				 (data_role == TYPEC_HOST ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
+				 (power_role == TYPEC_SOURCE ? MSG_CONFIG_PORT_POWER_ROLE : 0));
 
 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
 
 	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
-		data_role_host, power_role_src);
+		data_role, power_role);
 
 	return ret;
 }
@@ -435,9 +509,10 @@ static int pmic_typec_pdphy_reset(struct pmic_typec_pdphy *pmic_typec_pdphy)
 	return ret;
 }
 
-int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
-				struct tcpm_port *tcpm_port)
+static int qcom_pmic_typec_pdphy_start(struct pmic_typec *tcpm,
+				       struct tcpm_port *tcpm_port)
 {
+	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
 	int i;
 	int ret;
 
@@ -457,8 +532,9 @@ int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
 	return 0;
 }
 
-void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
+static void qcom_pmic_typec_pdphy_stop(struct pmic_typec *tcpm)
 {
+	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
 	int i;
 
 	for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
@@ -469,21 +545,55 @@ void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
 	regulator_disable(pmic_typec_pdphy->vdd_pdphy);
 }
 
-struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev)
-{
-	return devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
-}
+const struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
+	.irq_params = {
+		{
+			.virq = PMIC_PDPHY_SIG_TX_IRQ,
+			.irq_name = "sig-tx",
+		},
+		{
+			.virq = PMIC_PDPHY_SIG_RX_IRQ,
+			.irq_name = "sig-rx",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_TX_IRQ,
+			.irq_name = "msg-tx",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_RX_IRQ,
+			.irq_name = "msg-rx",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
+			.irq_name = "msg-tx-failed",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
+			.irq_name = "msg-tx-discarded",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
+			.irq_name = "msg-rx-discarded",
+		},
+	},
+	.nr_irqs = 7,
+};
 
 int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
-				struct pmic_typec_pdphy *pmic_typec_pdphy,
-				struct pmic_typec_pdphy_resources *res,
+				struct pmic_typec *tcpm,
+				const struct pmic_typec_pdphy_resources *res,
 				struct regmap *regmap,
 				u32 base)
 {
+	struct pmic_typec_pdphy *pmic_typec_pdphy;
 	struct device *dev = &pdev->dev;
 	struct pmic_typec_pdphy_irq_data *irq_data;
 	int i, ret, irq;
 
+	pmic_typec_pdphy = devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
+	if (!pmic_typec_pdphy)
+		return -ENOMEM;
+
 	if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
 		return -EINVAL;
 
@@ -522,5 +632,14 @@ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
 			return ret;
 	}
 
+	tcpm->pmic_typec_pdphy = pmic_typec_pdphy;
+
+	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_set_pd_rx;
+	tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_set_roles;
+	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_pd_transmit;
+
+	tcpm->pdphy_start = qcom_pmic_typec_pdphy_start;
+	tcpm->pdphy_stop = qcom_pmic_typec_pdphy_stop;
+
 	return 0;
 }
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
index e67954e31b14..b94eccadb042 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
@@ -8,74 +8,6 @@
 
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
-#include <linux/usb/tcpm.h>
-
-#define USB_PDPHY_MAX_DATA_OBJ_LEN	28
-#define USB_PDPHY_MSG_HDR_LEN		2
-
-/* PD PHY register offsets and bit fields */
-#define USB_PDPHY_MSG_CONFIG_REG	0x40
-#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
-#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
-#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
-
-#define USB_PDPHY_EN_CONTROL_REG	0x46
-#define CONTROL_ENABLE			BIT(0)
-
-#define USB_PDPHY_RX_STATUS_REG		0x4A
-#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
-
-#define USB_PDPHY_FRAME_FILTER_REG	0x4C
-#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
-#define FRAME_FILTER_EN_SOP		BIT(0)
-
-#define USB_PDPHY_TX_SIZE_REG		0x42
-#define TX_SIZE_MASK			0xF
-
-#define USB_PDPHY_TX_CONTROL_REG	0x44
-#define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
-#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
-#define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
-#define TX_CONTROL_SEND_SIGNAL		BIT(1)
-#define TX_CONTROL_SEND_MSG		BIT(0)
-
-#define USB_PDPHY_RX_SIZE_REG		0x48
-
-#define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
-#define RX_BUFFER_TOKEN			BIT(0)
-
-#define USB_PDPHY_BIST_MODE_REG		0x4E
-#define BIST_MODE_MASK			0xF
-#define BIST_ENABLE			BIT(7)
-#define PD_MSG_BIST			0x3
-#define PD_BIST_TEST_DATA_MODE		0x8
-
-#define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
-#define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
-
-#define USB_PDPHY_RX_BUFFER_REG		0x80
-
-/* VDD regulator */
-#define VDD_PDPHY_VOL_MIN		2800000	/* uV */
-#define VDD_PDPHY_VOL_MAX		3300000	/* uV */
-#define VDD_PDPHY_HPM_LOAD		3000	/* uA */
-
-/* Message Spec Rev field */
-#define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
-
-/* timers */
-#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
-#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
-
-/* Interrupt numbers */
-#define PMIC_PDPHY_SIG_TX_IRQ		0x0
-#define PMIC_PDPHY_SIG_RX_IRQ		0x1
-#define PMIC_PDPHY_MSG_TX_IRQ		0x2
-#define PMIC_PDPHY_MSG_RX_IRQ		0x3
-#define PMIC_PDPHY_MSG_TX_FAIL_IRQ	0x4
-#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ	0x5
-#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ	0x6
-#define PMIC_PDPHY_FR_SWAP_IRQ		0x7
 
 /* Resources */
 #define PMIC_PDPHY_MAX_IRQS		0x08
@@ -93,27 +25,11 @@ struct pmic_typec_pdphy_resources {
 /* API */
 struct pmic_typec_pdphy;
 
-struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev);
-
+extern const struct pmic_typec_pdphy_resources pm8150b_pdphy_res;
 int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
-				struct pmic_typec_pdphy *pmic_typec_pdphy,
-				struct pmic_typec_pdphy_resources *res,
+				struct pmic_typec *tcpm,
+				const struct pmic_typec_pdphy_resources *res,
 				struct regmap *regmap,
 				u32 base);
 
-int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
-				struct tcpm_port *tcpm_port);
-
-void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy);
-
-int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
-				    bool power_role_src, bool data_role_host);
-
-int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on);
-
-int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
-				      enum tcpm_transmit_type type,
-				      const struct pd_message *msg,
-				      unsigned int negotiated_rev);
-
 #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
index d4d358c680b6..4a892048908e 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
  * Copyright (c) 2023, Linaro Ltd. All rights reserved.
  */
-#ifndef __QCOM_PMIC_TYPEC_H__
-#define __QCOM_PMIC_TYPEC_H__
+#ifndef __QCOM_PMIC_TYPEC_PORT_H__
+#define __QCOM_PMIC_TYPEC_PORT_H__
 
 #include <linux/platform_device.h>
 #include <linux/usb/tcpm.h>

-- 
2.39.2


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

* [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (4 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:33   ` Konrad Dybcio
  2024-01-13 13:40   ` Bryan O'Donoghue
  2024-01-13  5:42 ` [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver Dmitry Baryshkov
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

The PMI632 PMIC support Type-C port handling, but lacks USB
PowerDelivery support. The TCPM requires all callbacks to be provided
by the implementation. Implement a special, 'stub' Qcom PD PHY
implementation to enable the PMI632 support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/usb/typec/tcpm/qcom/Makefile               |  3 +-
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c      | 30 +++++++---
 .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h    |  2 +
 .../typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c   | 67 ++++++++++++++++++++++
 4 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/typec/tcpm/qcom/Makefile b/drivers/usb/typec/tcpm/qcom/Makefile
index dc1e8832e197..cc23042b9487 100644
--- a/drivers/usb/typec/tcpm/qcom/Makefile
+++ b/drivers/usb/typec/tcpm/qcom/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_TYPEC_QCOM_PMIC)		+= qcom_pmic_tcpm.o
 qcom_pmic_tcpm-y			+= qcom_pmic_typec.o \
 					   qcom_pmic_typec_port.o \
-					   qcom_pmic_typec_pdphy.o
+					   qcom_pmic_typec_pdphy.o \
+					   qcom_pmic_typec_pdphy_stub.o \
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
index 4f2dbf20da12..e2513549c58a 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
@@ -118,7 +118,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 	const struct pmic_typec_resources *res;
 	struct regmap *regmap;
 	struct device *bridge_dev;
-	u32 base[2];
+	u32 base;
 	int ret;
 
 	res = of_device_get_match_data(dev);
@@ -145,7 +145,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	ret = of_property_read_u32_array(np, "reg", base, 2);
+	ret = of_property_read_u32_index(np, "reg", 0, &base);
 	if (ret)
 		return ret;
 
@@ -154,14 +154,24 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 		return PTR_ERR(tcpm->pmic_typec_port);
 
 	ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
-					 res->port_res, regmap, base[0]);
+					 res->port_res, regmap, base);
 	if (ret)
 		return ret;
 
-	ret = res->pdphy_probe(pdev, tcpm,
-			       res->pdphy_res, regmap, base[1]);
-	if (ret)
-		return ret;
+	if (res->pdphy_res) {
+		ret = of_property_read_u32_index(np, "reg", 1, &base);
+		if (ret)
+			return ret;
+
+		ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm,
+						  res->pdphy_res, regmap, base);
+		if (ret)
+			return ret;
+	} else {
+		ret = qcom_pmic_typec_pdphy_stub_probe(pdev, tcpm);
+		if (ret)
+			return ret;
+	}
 
 	mutex_init(&tcpm->lock);
 	platform_set_drvdata(pdev, tcpm);
@@ -253,8 +263,14 @@ static struct pmic_typec_resources pm8150b_typec_res = {
 	.port_res = &pm8150b_port_res,
 };
 
+static struct pmic_typec_resources pmi632_typec_res = {
+	/* PD PHY not present */
+	.port_res = &pm8150b_port_res,
+};
+
 static const struct of_device_id qcom_pmic_typec_table[] = {
 	{ .compatible = "qcom,pm8150b-typec", .data = &pm8150b_typec_res },
+	{ .compatible = "qcom,pmi632-typec", .data = &pmi632_typec_res },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, qcom_pmic_typec_table);
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
index b94eccadb042..2a7dedeb3009 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
@@ -31,5 +31,7 @@ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
 				const struct pmic_typec_pdphy_resources *res,
 				struct regmap *regmap,
 				u32 base);
+int qcom_pmic_typec_pdphy_stub_probe(struct platform_device *pdev,
+				     struct pmic_typec *tcpm);
 
 #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
new file mode 100644
index 000000000000..5d3b0e78d4d8
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024, Linaro Ltd. All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/tcpm.h>
+#include "qcom_pmic_typec.h"
+#include "qcom_pmic_typec_pdphy.h"
+
+static int qcom_pmic_typec_pdphy_stub_pd_transmit(struct tcpc_dev *tcpc,
+						  enum tcpm_transmit_type type,
+						  const struct pd_message *msg,
+						  unsigned int negotiated_rev)
+{
+	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+	struct device *dev = tcpm->dev;
+
+	dev_dbg(dev, "pdphy_transmit: type=%d\n", type);
+
+	tcpm_pd_transmit_complete(tcpm->tcpm_port,
+				  TCPC_TX_SUCCESS);
+
+	return 0;
+}
+
+static int qcom_pmic_typec_pdphy_stub_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+{
+	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+	struct device *dev = tcpm->dev;
+
+	dev_dbg(dev, "set_pd_rx: %s\n", on ? "on" : "off");
+
+	return 0;
+}
+
+static int qcom_pmic_typec_pdphy_stub_set_roles(struct tcpc_dev *tcpc, bool attached,
+						enum typec_role power_role,
+						enum typec_data_role data_role)
+{
+	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+	struct device *dev = tcpm->dev;
+
+	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
+		data_role, power_role);
+
+	return 0;
+}
+
+int qcom_pmic_typec_pdphy_stub_probe(struct platform_device *pdev,
+				     struct pmic_typec *tcpm)
+{
+	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_stub_set_pd_rx;
+	tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_stub_set_roles;
+	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_stub_pd_transmit;
+
+	return 0;
+}

-- 
2.39.2


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

* [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (5 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:42   ` Konrad Dybcio
  2024-01-13  5:42 ` [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling Dmitry Baryshkov
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

In preparation to adding Type-C handling for MSM8998, QCM2290 and SM6115
platforms, create new QMP USB-C PHY driver by splitting mentioned
platforms to a separate file. In future it will also be extended with
support for the DisplayPort handling. It will also be reused later for
such platforms as SDM660, SM6125, SM6150.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/phy/qualcomm/Makefile            |    2 +-
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c  |  266 -------
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 1125 ++++++++++++++++++++++++++++++
 3 files changed, 1126 insertions(+), 267 deletions(-)

diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile
index ffd609ac6233..eb60e950ad53 100644
--- a/drivers/phy/qualcomm/Makefile
+++ b/drivers/phy/qualcomm/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)	+= phy-qcom-ipq806x-sata.o
 obj-$(CONFIG_PHY_QCOM_M31_USB)		+= phy-qcom-m31.o
 obj-$(CONFIG_PHY_QCOM_PCIE2)		+= phy-qcom-pcie2.o
 
-obj-$(CONFIG_PHY_QCOM_QMP_COMBO)	+= phy-qcom-qmp-combo.o
+obj-$(CONFIG_PHY_QCOM_QMP_COMBO)	+= phy-qcom-qmp-combo.o phy-qcom-qmp-usbc.o
 obj-$(CONFIG_PHY_QCOM_QMP_PCIE)		+= phy-qcom-qmp-pcie.o
 obj-$(CONFIG_PHY_QCOM_QMP_PCIE_8996)	+= phy-qcom-qmp-pcie-msm8996.o
 obj-$(CONFIG_PHY_QCOM_QMP_UFS)		+= phy-qcom-qmp-ufs.o
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index 243cc2b9a0fb..c7698369d3dc 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -121,15 +121,6 @@ static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_MISC_CLAMP_ENABLE]	= QPHY_V3_PCS_MISC_CLAMP_ENABLE,
 };
 
-static const unsigned int qmp_v3_usb3phy_regs_layout_qcm2290[QPHY_LAYOUT_SIZE] = {
-	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET,
-	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL,
-	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS,
-	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
-	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
-	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL,
-};
-
 static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_SW_RESET]			= QPHY_V4_PCS_SW_RESET,
 	[QPHY_START_CTRL]		= QPHY_V4_PCS_START_CONTROL,
@@ -514,115 +505,6 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
 };
 
-static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
-	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
-};
-
-static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
-};
-
-static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
-};
-
-static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
-};
-
 static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
@@ -1089,99 +971,6 @@ static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_usb_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
 };
 
-static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
-	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
-	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
-	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
-	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
-	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
-	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
-	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
-	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
-	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
-	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
-	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
-	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
-	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
-	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
-	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
-	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
-};
-
-static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
-};
-
-static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
-	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
-};
-
-static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
-	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
-};
-
 static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x1a),
 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
@@ -1571,16 +1360,6 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v3 = {
 	.rx		= 0x400,
 };
 
-static const struct qmp_usb_offsets qmp_usb_offsets_v3_qcm2290 = {
-	.serdes		= 0x0,
-	.pcs		= 0xc00,
-	.pcs_misc	= 0xa00,
-	.tx		= 0x200,
-	.rx		= 0x400,
-	.tx2		= 0x600,
-	.rx2		= 0x800,
-};
-
 static const struct qmp_usb_offsets qmp_usb_offsets_v4 = {
 	.serdes		= 0,
 	.pcs		= 0x0800,
@@ -1727,24 +1506,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
 	.has_pwrdn_delay	= true,
 };
 
-static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
-	.lanes			= 2,
-
-	.offsets		= &qmp_usb_offsets_v3_qcm2290,
-
-	.serdes_tbl             = msm8998_usb3_serdes_tbl,
-	.serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
-	.tx_tbl                 = msm8998_usb3_tx_tbl,
-	.tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
-	.rx_tbl                 = msm8998_usb3_rx_tbl,
-	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
-	.pcs_tbl                = msm8998_usb3_pcs_tbl,
-	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
-	.vreg_list              = qmp_phy_vreg_l,
-	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
-	.regs                   = qmp_v3_usb3phy_regs_layout,
-};
-
 static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
 	.lanes			= 1,
 
@@ -1882,24 +1643,6 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
 	.has_pwrdn_delay	= true,
 };
 
-static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
-	.lanes			= 2,
-
-	.offsets		= &qmp_usb_offsets_v3_qcm2290,
-
-	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
-	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
-	.tx_tbl			= qcm2290_usb3_tx_tbl,
-	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl),
-	.rx_tbl			= qcm2290_usb3_rx_tbl,
-	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
-	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
-	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
-	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
-};
-
 static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = {
 	.lanes			= 1,
 
@@ -2573,12 +2316,6 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
 	}, {
 		.compatible = "qcom,msm8996-qmp-usb3-phy",
 		.data = &msm8996_usb3phy_cfg,
-	}, {
-		.compatible = "qcom,msm8998-qmp-usb3-phy",
-		.data = &msm8998_usb3phy_cfg,
-	}, {
-		.compatible = "qcom,qcm2290-qmp-usb3-phy",
-		.data = &qcm2290_usb3phy_cfg,
 	}, {
 		.compatible = "qcom,sa8775p-qmp-usb3-uni-phy",
 		.data = &sa8775p_usb3_uniphy_cfg,
@@ -2597,9 +2334,6 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
 	}, {
 		.compatible = "qcom,sdx75-qmp-usb3-uni-phy",
 		.data = &sdx75_usb3_uniphy_cfg,
-	}, {
-		.compatible = "qcom,sm6115-qmp-usb3-phy",
-		.data = &qcm2290_usb3phy_cfg,
 	}, {
 		.compatible = "qcom,sm8150-qmp-usb3-uni-phy",
 		.data = &sm8150_usb3_uniphy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
new file mode 100644
index 000000000000..fd2439175cdf
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -0,0 +1,1125 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-misc-v3.h"
+
+/* QPHY_SW_RESET bit */
+#define SW_RESET				BIT(0)
+/* QPHY_POWER_DOWN_CONTROL */
+#define SW_PWRDN				BIT(0)
+/* QPHY_START_CONTROL bits */
+#define SERDES_START				BIT(0)
+#define PCS_START				BIT(1)
+/* QPHY_PCS_STATUS bit */
+#define PHYSTATUS				BIT(6)
+
+/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
+/* DP PHY soft reset */
+#define SW_DPPHY_RESET				BIT(0)
+/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
+#define SW_DPPHY_RESET_MUX			BIT(1)
+/* USB3 PHY soft reset */
+#define SW_USB3PHY_RESET			BIT(2)
+/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
+#define SW_USB3PHY_RESET_MUX			BIT(3)
+
+/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
+#define USB3_MODE				BIT(0) /* enables USB3 mode */
+#define DP_MODE					BIT(1) /* enables DP mode */
+
+/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
+#define ARCVR_DTCT_EN				BIT(0)
+#define ALFPS_DTCT_EN				BIT(1)
+#define ARCVR_DTCT_EVENT_SEL			BIT(4)
+
+/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
+#define IRQ_CLEAR				BIT(0)
+
+/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
+#define CLAMP_EN				BIT(0) /* enables i/o clamp_n */
+
+#define PHY_INIT_COMPLETE_TIMEOUT		10000
+
+struct qmp_phy_init_tbl {
+	unsigned int offset;
+	unsigned int val;
+	/*
+	 * mask of lanes for which this register is written
+	 * for cases when second lane needs different values
+	 */
+	u8 lane_mask;
+};
+
+#define QMP_PHY_INIT_CFG(o, v)		\
+	{				\
+		.offset = o,		\
+		.val = v,		\
+		.lane_mask = 0xff,	\
+	}
+
+#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\
+	{				\
+		.offset = o,		\
+		.val = v,		\
+		.lane_mask = l,		\
+	}
+
+/* set of registers with offsets different per-PHY */
+enum qphy_reg_layout {
+	/* PCS registers */
+	QPHY_SW_RESET,
+	QPHY_START_CTRL,
+	QPHY_PCS_STATUS,
+	QPHY_PCS_AUTONOMOUS_MODE_CTRL,
+	QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
+	QPHY_PCS_POWER_DOWN_CONTROL,
+	QPHY_PCS_MISC_CLAMP_ENABLE,
+	/* Keep last to ensure regs_layout arrays are properly initialized */
+	QPHY_LAYOUT_SIZE
+};
+
+static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET,
+	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL,
+	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS,
+	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
+	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
+	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL,
+	[QPHY_PCS_MISC_CLAMP_ENABLE]	= QPHY_V3_PCS_MISC_CLAMP_ENABLE,
+};
+
+static const unsigned int qmp_v3_usb3phy_regs_layout_qcm2290[QPHY_LAYOUT_SIZE] = {
+	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET,
+	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL,
+	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS,
+	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
+	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
+	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL,
+};
+
+static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
+};
+
+static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
+};
+
+static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
+};
+
+static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
+};
+
+static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
+};
+
+static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
+};
+
+static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
+};
+
+struct qmp_usbc_offsets {
+	u16 serdes;
+	u16 pcs;
+	u16 pcs_misc;
+	u16 pcs_usb;
+	u16 tx;
+	u16 rx;
+	/* for PHYs with >= 2 lanes */
+	u16 tx2;
+	u16 rx2;
+};
+
+/* struct qmp_phy_cfg - per-PHY initialization config */
+struct qmp_phy_cfg {
+	int lanes;
+
+	const struct qmp_usbc_offsets *offsets;
+
+	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
+	const struct qmp_phy_init_tbl *serdes_tbl;
+	int serdes_tbl_num;
+	const struct qmp_phy_init_tbl *tx_tbl;
+	int tx_tbl_num;
+	const struct qmp_phy_init_tbl *rx_tbl;
+	int rx_tbl_num;
+	const struct qmp_phy_init_tbl *pcs_tbl;
+	int pcs_tbl_num;
+	const struct qmp_phy_init_tbl *pcs_usb_tbl;
+	int pcs_usb_tbl_num;
+
+	/* regulators to be requested */
+	const char * const *vreg_list;
+	int num_vregs;
+
+	/* array of registers with different offsets */
+	const unsigned int *regs;
+
+	/* true, if PHY needs delay after POWER_DOWN */
+	bool has_pwrdn_delay;
+
+	/* Offset from PCS to PCS_USB region */
+	unsigned int pcs_usb_offset;
+};
+
+struct qmp_usbc {
+	struct device *dev;
+
+	const struct qmp_phy_cfg *cfg;
+
+	void __iomem *serdes;
+	void __iomem *pcs;
+	void __iomem *pcs_misc;
+	void __iomem *pcs_usb;
+	void __iomem *tx;
+	void __iomem *rx;
+	void __iomem *tx2;
+	void __iomem *rx2;
+
+	struct clk *pipe_clk;
+	struct clk_bulk_data *clks;
+	int num_clks;
+	int num_resets;
+	struct reset_control_bulk_data *resets;
+	struct regulator_bulk_data *vregs;
+
+	enum phy_mode mode;
+
+	struct phy *phy;
+
+	struct clk_fixed_rate pipe_clk_fixed;
+};
+
+static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	reg |= val;
+	writel(reg, base + offset);
+
+	/* ensure that above write is through */
+	readl(base + offset);
+}
+
+static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	reg &= ~val;
+	writel(reg, base + offset);
+
+	/* ensure that above write is through */
+	readl(base + offset);
+}
+
+/* list of clocks required by phy */
+static const char * const qmp_usbc_phy_clk_l[] = {
+	"aux", "cfg_ahb", "ref", "com_aux",
+};
+
+/* list of resets */
+static const char * const usb3phy_legacy_reset_l[] = {
+	"phy", "common",
+};
+
+static const char * const usb3phy_reset_l[] = {
+	"phy_phy", "phy",
+};
+
+/* list of regulators */
+static const char * const qmp_phy_vreg_l[] = {
+	"vdda-phy", "vdda-pll",
+};
+
+static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
+	.serdes		= 0x0,
+	.pcs		= 0xc00,
+	.pcs_misc	= 0xa00,
+	.tx		= 0x200,
+	.rx		= 0x400,
+	.tx2		= 0x600,
+	.rx2		= 0x800,
+};
+
+static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
+	.lanes			= 2,
+
+	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
+
+	.serdes_tbl             = msm8998_usb3_serdes_tbl,
+	.serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
+	.tx_tbl                 = msm8998_usb3_tx_tbl,
+	.tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
+	.rx_tbl                 = msm8998_usb3_rx_tbl,
+	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
+	.pcs_tbl                = msm8998_usb3_pcs_tbl,
+	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
+	.vreg_list              = qmp_phy_vreg_l,
+	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs                   = qmp_v3_usb3phy_regs_layout,
+};
+
+static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
+	.lanes			= 2,
+
+	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
+
+	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
+	.tx_tbl			= qcm2290_usb3_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl),
+	.rx_tbl			= qcm2290_usb3_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
+	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
+};
+
+static void qmp_usbc_configure_lane(void __iomem *base,
+					const struct qmp_phy_init_tbl tbl[],
+					int num,
+					u8 lane_mask)
+{
+	int i;
+	const struct qmp_phy_init_tbl *t = tbl;
+
+	if (!t)
+		return;
+
+	for (i = 0; i < num; i++, t++) {
+		if (!(t->lane_mask & lane_mask))
+			continue;
+
+		writel(t->val, base + t->offset);
+	}
+}
+
+static void qmp_usbc_configure(void __iomem *base,
+				   const struct qmp_phy_init_tbl tbl[],
+				   int num)
+{
+	qmp_usbc_configure_lane(base, tbl, num, 0xff);
+}
+
+static int qmp_usbc_serdes_init(struct qmp_usbc *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *serdes = qmp->serdes;
+	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
+	int serdes_tbl_num = cfg->serdes_tbl_num;
+
+	qmp_usbc_configure(serdes, serdes_tbl, serdes_tbl_num);
+
+	return 0;
+}
+
+static int qmp_usbc_init(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *pcs = qmp->pcs;
+	int ret;
+
+	ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
+	if (ret) {
+		dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
+		return ret;
+	}
+
+	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
+	if (ret) {
+		dev_err(qmp->dev, "reset assert failed\n");
+		goto err_disable_regulators;
+	}
+
+	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
+	if (ret) {
+		dev_err(qmp->dev, "reset deassert failed\n");
+		goto err_disable_regulators;
+	}
+
+	ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
+	if (ret)
+		goto err_assert_reset;
+
+	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
+
+	return 0;
+
+err_assert_reset:
+	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
+err_disable_regulators:
+	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
+
+	return ret;
+}
+
+static int qmp_usbc_exit(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
+
+	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
+
+	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
+
+	return 0;
+}
+
+static int qmp_usbc_power_on(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *tx = qmp->tx;
+	void __iomem *rx = qmp->rx;
+	void __iomem *pcs = qmp->pcs;
+	void __iomem *pcs_usb = qmp->pcs_usb;
+	void __iomem *status;
+	unsigned int val;
+	int ret;
+
+	qmp_usbc_serdes_init(qmp);
+
+	ret = clk_prepare_enable(qmp->pipe_clk);
+	if (ret) {
+		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
+		return ret;
+	}
+
+	/* Tx, Rx, and PCS configurations */
+	qmp_usbc_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
+	qmp_usbc_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
+
+	if (cfg->lanes >= 2) {
+		qmp_usbc_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
+		qmp_usbc_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
+	}
+
+	qmp_usbc_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+
+	if (pcs_usb)
+		qmp_usbc_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
+
+	if (cfg->has_pwrdn_delay)
+		usleep_range(10, 20);
+
+	/* Pull PHY out of reset state */
+	qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+
+	/* start SerDes and Phy-Coding-Sublayer */
+	qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START);
+
+	status = pcs + cfg->regs[QPHY_PCS_STATUS];
+	ret = readl_poll_timeout(status, val, !(val & PHYSTATUS), 200,
+				 PHY_INIT_COMPLETE_TIMEOUT);
+	if (ret) {
+		dev_err(qmp->dev, "phy initialization timed-out\n");
+		goto err_disable_pipe_clk;
+	}
+
+	return 0;
+
+err_disable_pipe_clk:
+	clk_disable_unprepare(qmp->pipe_clk);
+
+	return ret;
+}
+
+static int qmp_usbc_power_off(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+	clk_disable_unprepare(qmp->pipe_clk);
+
+	/* PHY reset */
+	qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+
+	/* stop SerDes and Phy-Coding-Sublayer */
+	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
+			SERDES_START | PCS_START);
+
+	/* Put PHY into POWER DOWN state: active low */
+	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+			SW_PWRDN);
+
+	return 0;
+}
+
+static int qmp_usbc_enable(struct phy *phy)
+{
+	int ret;
+
+	ret = qmp_usbc_init(phy);
+	if (ret)
+		return ret;
+
+	ret = qmp_usbc_power_on(phy);
+	if (ret)
+		qmp_usbc_exit(phy);
+
+	return ret;
+}
+
+static int qmp_usbc_disable(struct phy *phy)
+{
+	int ret;
+
+	ret = qmp_usbc_power_off(phy);
+	if (ret)
+		return ret;
+	return qmp_usbc_exit(phy);
+}
+
+static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+
+	qmp->mode = mode;
+
+	return 0;
+}
+
+static const struct phy_ops qmp_usbc_phy_ops = {
+	.init		= qmp_usbc_enable,
+	.exit		= qmp_usbc_disable,
+	.set_mode	= qmp_usbc_set_mode,
+	.owner		= THIS_MODULE,
+};
+
+static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
+	void __iomem *pcs_misc = qmp->pcs_misc;
+	u32 intr_mask;
+
+	if (qmp->mode == PHY_MODE_USB_HOST_SS ||
+	    qmp->mode == PHY_MODE_USB_DEVICE_SS)
+		intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
+	else
+		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
+
+	/* Clear any pending interrupts status */
+	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+	/* Writing 1 followed by 0 clears the interrupt */
+	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+
+	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
+		     ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
+
+	/* Enable required PHY autonomous mode interrupts */
+	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
+
+	/* Enable i/o clamp_n for autonomous mode */
+	if (pcs_misc && cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE])
+		qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE], CLAMP_EN);
+}
+
+static void qmp_usbc_disable_autonomous_mode(struct qmp_usbc *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
+	void __iomem *pcs_misc = qmp->pcs_misc;
+
+	/* Disable i/o clamp_n on resume for normal mode */
+	if (pcs_misc && cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE])
+		qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE], CLAMP_EN);
+
+	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
+		     ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
+
+	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+	/* Writing 1 followed by 0 clears the interrupt */
+	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+}
+
+static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev)
+{
+	struct qmp_usbc *qmp = dev_get_drvdata(dev);
+
+	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
+
+	if (!qmp->phy->init_count) {
+		dev_vdbg(dev, "PHY not initialized, bailing out\n");
+		return 0;
+	}
+
+	qmp_usbc_enable_autonomous_mode(qmp);
+
+	clk_disable_unprepare(qmp->pipe_clk);
+	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
+
+	return 0;
+}
+
+static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
+{
+	struct qmp_usbc *qmp = dev_get_drvdata(dev);
+	int ret = 0;
+
+	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
+
+	if (!qmp->phy->init_count) {
+		dev_vdbg(dev, "PHY not initialized, bailing out\n");
+		return 0;
+	}
+
+	ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(qmp->pipe_clk);
+	if (ret) {
+		dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
+		clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
+		return ret;
+	}
+
+	qmp_usbc_disable_autonomous_mode(qmp);
+
+	return 0;
+}
+
+static const struct dev_pm_ops qmp_usbc_pm_ops = {
+	SET_RUNTIME_PM_OPS(qmp_usbc_runtime_suspend,
+			   qmp_usbc_runtime_resume, NULL)
+};
+
+static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	struct device *dev = qmp->dev;
+	int num = cfg->num_vregs;
+	int i;
+
+	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
+	if (!qmp->vregs)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++)
+		qmp->vregs[i].supply = cfg->vreg_list[i];
+
+	return devm_regulator_bulk_get(dev, num, qmp->vregs);
+}
+
+static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
+			      const char *const *reset_list,
+			      int num_resets)
+{
+	struct device *dev = qmp->dev;
+	int i;
+	int ret;
+
+	qmp->resets = devm_kcalloc(dev, num_resets,
+				   sizeof(*qmp->resets), GFP_KERNEL);
+	if (!qmp->resets)
+		return -ENOMEM;
+
+	for (i = 0; i < num_resets; i++)
+		qmp->resets[i].id = reset_list[i];
+
+	qmp->num_resets = num_resets;
+
+	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get resets\n");
+
+	return 0;
+}
+
+static int qmp_usbc_clk_init(struct qmp_usbc *qmp)
+{
+	struct device *dev = qmp->dev;
+	int num = ARRAY_SIZE(qmp_usbc_phy_clk_l);
+	int i;
+
+	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_usbc_phy_clk_l[i];
+
+	qmp->num_clks = num;
+
+	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
+}
+
+static void phy_clk_release_provider(void *res)
+{
+	of_clk_del_provider(res);
+}
+
+/*
+ * Register a fixed rate pipe clock.
+ *
+ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
+ * controls it. The <s>_pipe_clk coming out of the GCC is requested
+ * by the PHY driver for its operations.
+ * We register the <s>_pipe_clksrc here. The gcc driver takes care
+ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
+ * Below picture shows this relationship.
+ *
+ *         +---------------+
+ *         |   PHY block   |<<---------------------------------------+
+ *         |               |                                         |
+ *         |   +-------+   |                   +-----+               |
+ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
+ *    clk  |   +-------+   |                   +-----+
+ *         +---------------+
+ */
+static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
+{
+	struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
+	struct clk_init_data init = { };
+	int ret;
+
+	ret = of_property_read_string(np, "clock-output-names", &init.name);
+	if (ret) {
+		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
+		return ret;
+	}
+
+	init.ops = &clk_fixed_rate_ops;
+
+	/* controllers using QMP phys use 125MHz pipe clock interface */
+	fixed->fixed_rate = 125000000;
+	fixed->hw.init = &init;
+
+	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
+	if (ret)
+		return ret;
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
+	if (ret)
+		return ret;
+
+	/*
+	 * Roll a devm action because the clock provider is the child node, but
+	 * the child node is not actually a device.
+	 */
+	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
+}
+
+static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np)
+{
+	struct platform_device *pdev = to_platform_device(qmp->dev);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	struct device *dev = qmp->dev;
+	int ret;
+
+	qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(qmp->serdes))
+		return PTR_ERR(qmp->serdes);
+
+	/*
+	 * Get memory resources for the PHY:
+	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
+	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
+	 * For single lane PHYs: pcs_misc (optional) -> 3.
+	 */
+	qmp->tx = devm_of_iomap(dev, np, 0, NULL);
+	if (IS_ERR(qmp->tx))
+		return PTR_ERR(qmp->tx);
+
+	qmp->rx = devm_of_iomap(dev, np, 1, NULL);
+	if (IS_ERR(qmp->rx))
+		return PTR_ERR(qmp->rx);
+
+	qmp->pcs = devm_of_iomap(dev, np, 2, NULL);
+	if (IS_ERR(qmp->pcs))
+		return PTR_ERR(qmp->pcs);
+
+	if (cfg->pcs_usb_offset)
+		qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset;
+
+	if (cfg->lanes >= 2) {
+		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
+		if (IS_ERR(qmp->tx2))
+			return PTR_ERR(qmp->tx2);
+
+		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
+		if (IS_ERR(qmp->rx2))
+			return PTR_ERR(qmp->rx2);
+
+		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
+	} else {
+		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
+	}
+
+	if (IS_ERR(qmp->pcs_misc)) {
+		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
+		qmp->pcs_misc = NULL;
+	}
+
+	qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
+	if (IS_ERR(qmp->pipe_clk)) {
+		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
+				     "failed to get pipe clock\n");
+	}
+
+	ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks);
+	if (ret < 0)
+		return ret;
+
+	qmp->num_clks = ret;
+
+	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
+				 ARRAY_SIZE(usb3phy_legacy_reset_l));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int qmp_usbc_parse_dt(struct qmp_usbc *qmp)
+{
+	struct platform_device *pdev = to_platform_device(qmp->dev);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	const struct qmp_usbc_offsets *offs = cfg->offsets;
+	struct device *dev = qmp->dev;
+	void __iomem *base;
+	int ret;
+
+	if (!offs)
+		return -EINVAL;
+
+	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;
+	if (offs->pcs_usb)
+		qmp->pcs_usb = base + offs->pcs_usb;
+	if (offs->pcs_misc)
+		qmp->pcs_misc = base + offs->pcs_misc;
+	qmp->tx = base + offs->tx;
+	qmp->rx = base + offs->rx;
+
+	if (cfg->lanes >= 2) {
+		qmp->tx2 = base + offs->tx2;
+		qmp->rx2 = base + offs->rx2;
+	}
+
+	ret = qmp_usbc_clk_init(qmp);
+	if (ret)
+		return ret;
+
+	qmp->pipe_clk = devm_clk_get(dev, "pipe");
+	if (IS_ERR(qmp->pipe_clk)) {
+		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
+				     "failed to get pipe clock\n");
+	}
+
+	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
+				 ARRAY_SIZE(usb3phy_reset_l));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int qmp_usbc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	struct device_node *np;
+	struct qmp_usbc *qmp;
+	int ret;
+
+	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
+	if (!qmp)
+		return -ENOMEM;
+
+	qmp->dev = dev;
+
+	qmp->cfg = of_device_get_match_data(dev);
+	if (!qmp->cfg)
+		return -EINVAL;
+
+	ret = qmp_usbc_vreg_init(qmp);
+	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_usbc_parse_dt_legacy(qmp, np);
+	} else {
+		np = of_node_get(dev->of_node);
+		ret = qmp_usbc_parse_dt(qmp);
+	}
+	if (ret)
+		goto err_node_put;
+
+	pm_runtime_set_active(dev);
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		goto err_node_put;
+	/*
+	 * Prevent runtime pm from being ON by default. Users can enable
+	 * it using power/control in sysfs.
+	 */
+	pm_runtime_forbid(dev);
+
+	ret = phy_pipe_clk_register(qmp, np);
+	if (ret)
+		goto err_node_put;
+
+	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops);
+	if (IS_ERR(qmp->phy)) {
+		ret = PTR_ERR(qmp->phy);
+		dev_err(dev, "failed to create PHY: %d\n", ret);
+		goto err_node_put;
+	}
+
+	phy_set_drvdata(qmp->phy, qmp);
+
+	of_node_put(np);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+
+err_node_put:
+	of_node_put(np);
+	return ret;
+}
+
+static const struct of_device_id qmp_usbc_of_match_table[] = {
+	{
+		.compatible = "qcom,msm8998-qmp-usb3-phy",
+		.data = &msm8998_usb3phy_cfg,
+	}, {
+		.compatible = "qcom,qcm2290-qmp-usb3-phy",
+		.data = &qcm2290_usb3phy_cfg,
+	}, {
+		.compatible = "qcom,sm6115-qmp-usb3-phy",
+		.data = &qcm2290_usb3phy_cfg,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qmp_usbc_of_match_table);
+
+static struct platform_driver qmp_usbc_driver = {
+	.probe		= qmp_usbc_probe,
+	.driver = {
+		.name	= "qcom-qmp-usbc-phy",
+		.pm	= &qmp_usbc_pm_ops,
+		.of_match_table = qmp_usbc_of_match_table,
+	},
+};
+
+module_platform_driver(qmp_usbc_driver);
+
+MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
+MODULE_DESCRIPTION("Qualcomm QMP USB-C PHY driver");
+MODULE_LICENSE("GPL");

-- 
2.39.2


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

* [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (6 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:46   ` Konrad Dybcio
  2024-01-17  0:04   ` Jeff Johnson
  2024-01-13  5:42 ` [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling Dmitry Baryshkov
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

Now as all dual-lane PHYs have been migrated to a new driver, drop
support for dual lanes configuration. If the PHY uses two lanes for USB,
it is symthom that it should use either a combo USB+DP or a USB-C PHY
driver.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 57 +--------------------------------
 1 file changed, 1 insertion(+), 56 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index c7698369d3dc..e62539ce99a6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -1237,15 +1237,10 @@ struct qmp_usb_offsets {
 	u16 pcs_usb;
 	u16 tx;
 	u16 rx;
-	/* for PHYs with >= 2 lanes */
-	u16 tx2;
-	u16 rx2;
 };
 
 /* struct qmp_phy_cfg - per-PHY initialization config */
 struct qmp_phy_cfg {
-	int lanes;
-
 	const struct qmp_usb_offsets *offsets;
 
 	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
@@ -1285,8 +1280,6 @@ struct qmp_usb {
 	void __iomem *pcs_usb;
 	void __iomem *tx;
 	void __iomem *rx;
-	void __iomem *tx2;
-	void __iomem *rx2;
 
 	struct clk *pipe_clk;
 	struct clk_bulk_data *clks;
@@ -1393,8 +1386,6 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v7 = {
 };
 
 static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v3,
 
 	.serdes_tbl		= ipq8074_usb3_serdes_tbl,
@@ -1411,8 +1402,6 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_ipq9574,
 
 	.serdes_tbl		= ipq9574_usb3_serdes_tbl,
@@ -1429,8 +1418,6 @@ static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v3,
 
 	.serdes_tbl		= msm8996_usb3_serdes_tbl,
@@ -1447,8 +1434,6 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v5,
 
 	.serdes_tbl		= sc8280xp_usb3_uniphy_serdes_tbl,
@@ -1467,8 +1452,6 @@ static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v5,
 
 	.serdes_tbl		= sc8280xp_usb3_uniphy_serdes_tbl,
@@ -1487,8 +1470,6 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v3,
 
 	.serdes_tbl		= qmp_v3_usb3_uniphy_serdes_tbl,
@@ -1507,8 +1488,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v4,
 
 	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl,
@@ -1530,8 +1509,6 @@ static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v4,
 
 	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl,
@@ -1553,8 +1530,6 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v4,
 
 	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl,
@@ -1576,8 +1551,6 @@ static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v5,
 
 	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl,
@@ -1599,7 +1572,6 @@ static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sdx75_usb3_uniphy_cfg = {
-	.lanes			= 1,
 	.offsets		= &qmp_usb_offsets_v6,
 
 	.serdes_tbl		= sdx75_usb3_uniphy_serdes_tbl,
@@ -1621,8 +1593,6 @@ static const struct qmp_phy_cfg sdx75_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v5,
 
 	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl,
@@ -1644,8 +1614,6 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
 };
 
 static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = {
-	.lanes			= 1,
-
 	.offsets		= &qmp_usb_offsets_v7,
 
 	.serdes_tbl		= x1e80100_usb3_uniphy_serdes_tbl,
@@ -1780,11 +1748,6 @@ static int qmp_usb_power_on(struct phy *phy)
 	qmp_usb_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
 	qmp_usb_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
 
-	if (cfg->lanes >= 2) {
-		qmp_usb_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
-		qmp_usb_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
-	}
-
 	qmp_usb_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 
 	if (pcs_usb)
@@ -2131,7 +2094,6 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)
 	/*
 	 * Get memory resources for the PHY:
 	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
-	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
 	 * For single lane PHYs: pcs_misc (optional) -> 3.
 	 */
 	qmp->tx = devm_of_iomap(dev, np, 0, NULL);
@@ -2149,19 +2111,7 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)
 	if (cfg->pcs_usb_offset)
 		qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset;
 
-	if (cfg->lanes >= 2) {
-		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
-		if (IS_ERR(qmp->tx2))
-			return PTR_ERR(qmp->tx2);
-
-		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
-		if (IS_ERR(qmp->rx2))
-			return PTR_ERR(qmp->rx2);
-
-		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
-	} else {
-		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
-	}
+	qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
 
 	if (IS_ERR(qmp->pcs_misc)) {
 		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
@@ -2213,11 +2163,6 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp)
 	qmp->tx = base + offs->tx;
 	qmp->rx = base + offs->rx;
 
-	if (cfg->lanes >= 2) {
-		qmp->tx2 = base + offs->tx2;
-		qmp->rx2 = base + offs->rx2;
-	}
-
 	ret = qmp_usb_clk_init(qmp);
 	if (ret)
 		return ret;

-- 
2.39.2


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

* [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (7 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:46   ` Konrad Dybcio
  2024-01-13  5:42 ` [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling Dmitry Baryshkov
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

All USB-C PHYs use 2 lanes for the USB. Drop single lane handling in
this driver.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 36 ++++++++++----------------------
 1 file changed, 11 insertions(+), 25 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index fd2439175cdf..21faed7f648a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -332,8 +332,6 @@ struct qmp_usbc_offsets {
 
 /* struct qmp_phy_cfg - per-PHY initialization config */
 struct qmp_phy_cfg {
-	int lanes;
-
 	const struct qmp_usbc_offsets *offsets;
 
 	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
@@ -444,8 +442,6 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
 };
 
 static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
-	.lanes			= 2,
-
 	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
 
 	.serdes_tbl             = msm8998_usb3_serdes_tbl,
@@ -462,8 +458,6 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
-	.lanes			= 2,
-
 	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
 
 	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
@@ -596,10 +590,8 @@ static int qmp_usbc_power_on(struct phy *phy)
 	qmp_usbc_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
 	qmp_usbc_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
 
-	if (cfg->lanes >= 2) {
-		qmp_usbc_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
-		qmp_usbc_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
-	}
+	qmp_usbc_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
+	qmp_usbc_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
 
 	qmp_usbc_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 
@@ -940,19 +932,15 @@ static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np
 	if (cfg->pcs_usb_offset)
 		qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset;
 
-	if (cfg->lanes >= 2) {
-		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
-		if (IS_ERR(qmp->tx2))
-			return PTR_ERR(qmp->tx2);
+	qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
+	if (IS_ERR(qmp->tx2))
+		return PTR_ERR(qmp->tx2);
 
-		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
-		if (IS_ERR(qmp->rx2))
-			return PTR_ERR(qmp->rx2);
+	qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
+	if (IS_ERR(qmp->rx2))
+		return PTR_ERR(qmp->rx2);
 
-		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
-	} else {
-		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
-	}
+	qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
 
 	if (IS_ERR(qmp->pcs_misc)) {
 		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
@@ -1004,10 +992,8 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp)
 	qmp->tx = base + offs->tx;
 	qmp->rx = base + offs->rx;
 
-	if (cfg->lanes >= 2) {
-		qmp->tx2 = base + offs->tx2;
-		qmp->rx2 = base + offs->rx2;
-	}
+	qmp->tx2 = base + offs->tx2;
+	qmp->rx2 = base + offs->rx2;
 
 	ret = qmp_usbc_clk_init(qmp);
 	if (ret)

-- 
2.39.2


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

* [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (8 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:48   ` Konrad Dybcio
  2024-01-13  5:42 ` [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks Dmitry Baryshkov
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

The USB-C PHYs on the msm8998, QCM2290 and SM6115 platforms use special
register to control which lanes of the Type-C port are used for the
SuperSpeed USB connection. Mimic the qmp-combo driver and handle this
register.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 97 +++++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 21faed7f648a..9cddba30b52e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -18,6 +18,8 @@
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/usb/typec.h>
+#include <linux/usb/typec_mux.h>
 
 #include "phy-qcom-qmp.h"
 #include "phy-qcom-qmp-pcs-misc-v3.h"
@@ -381,11 +383,17 @@ struct qmp_usbc {
 	struct reset_control_bulk_data *resets;
 	struct regulator_bulk_data *vregs;
 
+	struct mutex phy_mutex;
+
 	enum phy_mode mode;
+	unsigned int usb_init_count;
 
 	struct phy *phy;
 
 	struct clk_fixed_rate pipe_clk_fixed;
+
+	struct typec_switch_dev *sw;
+	enum typec_orientation orientation;
 };
 
 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -516,6 +524,7 @@ static int qmp_usbc_init(struct phy *phy)
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	void __iomem *pcs = qmp->pcs;
+	u32 val = 0;
 	int ret;
 
 	ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
@@ -542,6 +551,14 @@ static int qmp_usbc_init(struct phy *phy)
 
 	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
 
+#define SW_PORTSELECT_VAL			BIT(0)
+#define SW_PORTSELECT_MUX			BIT(1)
+	/* Use software based port select and switch on typec orientation */
+	val = SW_PORTSELECT_MUX;
+	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
+		val |= SW_PORTSELECT_VAL;
+	writel(val, qmp->pcs_misc);
+
 	return 0;
 
 err_assert_reset:
@@ -646,23 +663,34 @@ static int qmp_usbc_power_off(struct phy *phy)
 
 static int qmp_usbc_enable(struct phy *phy)
 {
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	int ret;
 
+	mutex_lock(&qmp->phy_mutex);
+
 	ret = qmp_usbc_init(phy);
 	if (ret)
-		return ret;
+		goto out_unlock;
 
 	ret = qmp_usbc_power_on(phy);
-	if (ret)
+	if (ret) {
 		qmp_usbc_exit(phy);
+		goto out_unlock;
+	}
+
+	qmp->usb_init_count++;
+out_unlock:
+	mutex_unlock(&qmp->phy_mutex);
 
 	return ret;
 }
 
 static int qmp_usbc_disable(struct phy *phy)
 {
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	int ret;
 
+	qmp->usb_init_count--;
 	ret = qmp_usbc_power_off(phy);
 	if (ret)
 		return ret;
@@ -900,6 +928,61 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
 	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
 }
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
+				      enum typec_orientation orientation)
+{
+	struct qmp_usbc *qmp = typec_switch_get_drvdata(sw);
+
+	if (orientation == qmp->orientation || orientation == TYPEC_ORIENTATION_NONE)
+		return 0;
+
+	mutex_lock(&qmp->phy_mutex);
+	qmp->orientation = orientation;
+
+	if (qmp->usb_init_count) {
+		qmp_usbc_power_off(qmp->phy);
+		qmp_usbc_exit(qmp->phy);
+
+		qmp_usbc_init(qmp->phy);
+		qmp_usbc_power_on(qmp->phy);
+	}
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+}
+
+static void qmp_usbc_typec_unregister(void *data)
+{
+	struct qmp_usbc *qmp = data;
+
+	typec_switch_unregister(qmp->sw);
+}
+
+static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp)
+{
+	struct typec_switch_desc sw_desc = {};
+	struct device *dev = qmp->dev;
+
+	sw_desc.drvdata = qmp;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = qmp_usbc_typec_switch_set;
+	qmp->sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(qmp->sw)) {
+		dev_err(dev, "Unable to register typec switch: %pe\n", qmp->sw);
+		return PTR_ERR(qmp->sw);
+	}
+
+	return devm_add_action_or_reset(dev, qmp_usbc_typec_unregister, qmp);
+}
+#else
+static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp)
+{
+	return 0;
+}
+#endif
+
 static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np)
 {
 	struct platform_device *pdev = to_platform_device(qmp->dev);
@@ -1027,16 +1110,24 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 
 	qmp->dev = dev;
 
+	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
+
 	qmp->cfg = of_device_get_match_data(dev);
 	if (!qmp->cfg)
 		return -EINVAL;
 
+	mutex_init(&qmp->phy_mutex);
+
 	ret = qmp_usbc_vreg_init(qmp);
 	if (ret)
 		return ret;
 
+	ret = qmp_usbc_typec_switch_register(qmp);
+	if (ret)
+		return ret;
+
 	/* Check for legacy binding with child node. */
-	np = of_get_next_available_child(dev->of_node, NULL);
+	np = of_get_child_by_name(dev->of_node, "phy");
 	if (np) {
 		ret = qmp_usbc_parse_dt_legacy(qmp, np);
 	} else {

-- 
2.39.2


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

* [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (9 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:48   ` Konrad Dybcio
  2024-01-13 12:18   ` Bryan O'Donoghue
  2024-01-13  5:42 ` [PATCH 12/13] arm64: dts: qcom: sm6115: drop pipe clock selection Dmitry Baryshkov
  2024-01-13  5:42 ` [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling Dmitry Baryshkov
  12 siblings, 2 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

Define VBUS regulator and the Type-C handling block as present on the
Quacomm PMI632 PMIC.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 arch/arm64/boot/dts/qcom/pmi632.dtsi | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index 4eb79e0ce40a..ccf288ddc987 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -45,6 +45,35 @@ pmic@2 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		pmi632_vbus: usb-vbus-regulator@1100 {
+			compatible = "qcom,pmi632-vbus-reg", "qcom,pm8150b-vbus-reg";
+			status = "disabled";
+			reg = <0x1100>;
+		};
+
+		pmi632_typec: typec@1500 {
+			compatible = "qcom,pmi632-typec";
+			status = "disabled";
+			reg = <0x1500>;
+			interrupts = <0x2 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
+				     <0x2 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
+				     <0x2 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
+				     <0x2 0x15 0x07 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "or-rid-detect-change",
+					  "vpd-detect",
+					  "cc-state-change",
+					  "vconn-oc",
+					  "vbus-change",
+					  "attach-detach",
+					  "legacy-cable-detect",
+					  "try-snk-src-detect";
+			vdd-vbus-supply = <&pmi632_vbus>;
+		};
+
 		pmi632_temp: temp-alarm@2400 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0x2400>;

-- 
2.39.2


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

* [PATCH 12/13] arm64: dts: qcom: sm6115: drop pipe clock selection
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (10 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:49   ` Konrad Dybcio
  2024-01-13  5:42 ` [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling Dmitry Baryshkov
  12 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy,
	Vladimir Zapolskiy

From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>

Stop selecting UTMI clock as the USB3 PIPE clock. This setting is
incompatible with the USB host working in USB3 (SuperSpeed) mode.

Fixes: 9dd5f6dba729 ("arm64: dts: qcom: sm6115: Add USB SS qmp phy node")
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
[DB: fixed commit message, dropped dr_mode setting]
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 4 ----
 arch/arm64/boot/dts/qcom/sm6115.dtsi     | 1 -
 2 files changed, 5 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
index 7c19f874fa71..52f31f3166c2 100644
--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
+++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
@@ -607,10 +607,6 @@ &usb {
 	status = "okay";
 };
 
-&usb_dwc3 {
-	maximum-speed = "super-speed";
-};
-
 &usb_hsphy {
 	vdd-supply = <&vreg_l4a_0p9>;
 	vdda-pll-supply = <&vreg_l12a_1p8>;
diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi
index 160e098f1075..76c429e8ebab 100644
--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -1600,7 +1600,6 @@ &bimc SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
 			interconnect-names = "usb-ddr",
 					     "apps-usb";
 
-			qcom,select-utmi-as-pipe-clk;
 			status = "disabled";
 
 			usb_dwc3: usb@4e00000 {

-- 
2.39.2


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

* [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling
  2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
                   ` (11 preceding siblings ...)
  2024-01-13  5:42 ` [PATCH 12/13] arm64: dts: qcom: sm6115: drop pipe clock selection Dmitry Baryshkov
@ 2024-01-13  5:42 ` Dmitry Baryshkov
  2024-01-13 10:52   ` Konrad Dybcio
  12 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13  5:42 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

Plug in USB-C related bits and pieces to enable USB role switching and
USB-C orientation handling for the Qualcomm RB2 board.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 62 ++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/qcom/sm6115.dtsi     | 38 ++++++++++++++++++++
 2 files changed, 100 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
index 52f31f3166c2..a96e3afb65bc 100644
--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
+++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
@@ -6,8 +6,10 @@
 /dts-v1/;
 
 #include <dt-bindings/leds/common.h>
+#include <dt-bindings/usb/pd.h>
 #include "sm4250.dtsi"
 #include "pm6125.dtsi"
+#include "pmi632.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. QRB4210 RB2";
@@ -256,6 +258,53 @@ kypd_vol_up_n: kypd-vol-up-n-state {
 	};
 };
 
+&pmi632_typec {
+	status = "okay";
+
+	connector {
+		compatible = "usb-c-connector";
+
+		power-role = "dual";
+		data-role = "dual";
+		self-powered;
+
+		source-pdos = <PDO_FIXED(5000, 3000,
+					 PDO_FIXED_DUAL_ROLE |
+					 PDO_FIXED_USB_COMM |
+					 PDO_FIXED_DATA_SWAP)>;
+		sink-pdos = <PDO_FIXED(5000, 500,
+					 PDO_FIXED_DUAL_ROLE |
+					 PDO_FIXED_USB_COMM |
+					 PDO_FIXED_DATA_SWAP)>;
+		op-sink-microwatt = <10000000>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				pmi632_hs_in: endpoint {
+					remote-endpoint = <&usb_dwc3_hs>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				pmi632_ss_in: endpoint {
+					remote-endpoint = <&usb_qmpphy_out>;
+				};
+			};
+		};
+	};
+};
+
+&pmi632_vbus {
+	regulator-min-microamp = <500000>;
+	regulator-max-microamp = <3000000>;
+	status = "okay";
+};
+
 &pon_pwrkey {
 	status = "okay";
 };
@@ -607,6 +656,14 @@ &usb {
 	status = "okay";
 };
 
+&usb_dwc3 {
+	usb-role-switch;
+};
+
+&usb_dwc3_hs {
+	remote-endpoint = <&pmi632_hs_in>;
+};
+
 &usb_hsphy {
 	vdd-supply = <&vreg_l4a_0p9>;
 	vdda-pll-supply = <&vreg_l12a_1p8>;
@@ -618,10 +675,15 @@ &usb_hsphy {
 &usb_qmpphy {
 	vdda-phy-supply = <&vreg_l4a_0p9>;
 	vdda-pll-supply = <&vreg_l12a_1p8>;
+	orientation-switch;
 
 	status = "okay";
 };
 
+&usb_qmpphy_out {
+	remote-endpoint = <&pmi632_ss_in>;
+};
+
 &wifi {
 	vdd-0.8-cx-mx-supply = <&vreg_l8a_0p664>;
 	vdd-1.8-xo-supply = <&vreg_l16a_1p3>;
diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi
index 76c429e8ebab..252074219bed 100644
--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -880,6 +880,25 @@ usb_qmpphy: phy@1615000 {
 			#phy-cells = <0>;
 
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					usb_qmpphy_out: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					usb_qmpphy_usb_ss_in: endpoint {
+					};
+				};
+			};
 		};
 
 		system_noc: interconnect@1880000 {
@@ -1614,6 +1633,25 @@ usb_dwc3: usb@4e00000 {
 				snps,has-lpm-erratum;
 				snps,hird-threshold = /bits/ 8 <0x10>;
 				snps,usb3_lpm_capable;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+
+						usb_dwc3_hs: endpoint {
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+
+						usb_dwc3_ss: endpoint {
+						};
+					};
+				};
 			};
 		};
 

-- 
2.39.2


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

* Re: [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY
  2024-01-13  5:42 ` [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY Dmitry Baryshkov
@ 2024-01-13 10:32   ` Konrad Dybcio
  2024-01-13 13:43   ` Bryan O'Donoghue
  1 sibling, 0 replies; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:32 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> Rework Qualcomm PMIC TCPM driver to allow different platform-specific
> implementations of the PD PHY interface. While majority of platforms
> has the same of register for the PD PHY, some obscure ones (PMI632) do
> not have real PD PHY support. Add proper interface between the main
> module and the PD PHY backend to allow switching the PD PHY
> implementation.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

[...]

> @@ -366,12 +439,13 @@ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
>  				 pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
>  				 MSG_CONFIG_PORT_DATA_ROLE |
>  				 MSG_CONFIG_PORT_POWER_ROLE,
> -				 data_role_host << 3 | power_role_src << 2);
> +				 (data_role == TYPEC_HOST ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
> +				 (power_role == TYPEC_SOURCE ? MSG_CONFIG_PORT_POWER_ROLE : 0));

Was this hunk supposed to be part of this patch?

[...]

>  int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
> -				struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				struct pmic_typec_pdphy_resources *res,
> +				struct pmic_typec *tcpm,
> +				const struct pmic_typec_pdphy_resources *res,
>  				struct regmap *regmap,
>  				u32 base)
>  {
> +	struct pmic_typec_pdphy *pmic_typec_pdphy;
>  	struct device *dev = &pdev->dev;
>  	struct pmic_typec_pdphy_irq_data *irq_data;
>  	int i, ret, irq;
>  
> +	pmic_typec_pdphy = devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
> +	if (!pmic_typec_pdphy)
> +		return -ENOMEM;

or simply sizeof(*pdphy) 

Konrad

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

* Re: [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC
  2024-01-13  5:42 ` [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC Dmitry Baryshkov
@ 2024-01-13 10:33   ` Konrad Dybcio
  2024-01-13 13:58     ` Bryan O'Donoghue
  2024-01-13 13:40   ` Bryan O'Donoghue
  1 sibling, 1 reply; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:33 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> The PMI632 PMIC support Type-C port handling, but lacks USB
> PowerDelivery support. The TCPM requires all callbacks to be provided
> by the implementation. Implement a special, 'stub' Qcom PD PHY
> implementation to enable the PMI632 support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

[...]

>  #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
> new file mode 100644
> index 000000000000..5d3b0e78d4d8
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c

Not a fan.

Maybe add some TCPM_FLAG_NO_PD and solve it in a generic manner?

Konrad

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

* Re: [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver
  2024-01-13  5:42 ` [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver Dmitry Baryshkov
@ 2024-01-13 10:42   ` Konrad Dybcio
  2024-01-13 14:15     ` Dmitry Baryshkov
  0 siblings, 1 reply; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> In preparation to adding Type-C handling for MSM8998, QCM2290 and SM6115
> platforms, create new QMP USB-C PHY driver by splitting mentioned
> platforms to a separate file. In future it will also be extended with
> support for the DisplayPort handling. It will also be reused later for
> such platforms as SDM660, SM6125, SM6150.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

[...]


> +#include "phy-qcom-qmp.h"
> +#include "phy-qcom-qmp-pcs-misc-v3.h"
> +
> +/* QPHY_SW_RESET bit */
> +#define SW_RESET				BIT(0)
> +/* QPHY_POWER_DOWN_CONTROL */
> +#define SW_PWRDN				BIT(0)

Most / all of these defines could probably live in a header file.

[...]

> +struct qmp_usbc_offsets {
> +	u16 serdes;
> +	u16 pcs;
> +	u16 pcs_misc;
> +	u16 pcs_usb;
> +	u16 tx;
> +	u16 rx;
> +	/* for PHYs with >= 2 lanes */

So, all PHYs within this driver if I'm following correctly

> +	u16 tx2;
> +	u16 rx2;
> +};
> +

> +static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
> +{
> +	u32 reg;
> +
> +	reg = readl(base + offset);
> +	reg |= val;
> +	writel(reg, base + offset);
> +
> +	/* ensure that above write is through */
> +	readl(base + offset);
> +}
> +
> +static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
> +{
> +	u32 reg;
> +
> +	reg = readl(base + offset);
> +	reg &= ~val;
> +	writel(reg, base + offset);
> +
> +	/* ensure that above write is through */
> +	readl(base + offset);
> +}

Maybe you could use regmap to avoid NIH-ing such accessors

> +
> +/* list of clocks required by phy */
> +static const char * const qmp_usbc_phy_clk_l[] = {
> +	"aux", "cfg_ahb", "ref", "com_aux",
> +};
> +
> +/* list of resets */
> +static const char * const usb3phy_legacy_reset_l[] = {
> +	"phy", "common",
> +};
> +
> +static const char * const usb3phy_reset_l[] = {
> +	"phy_phy", "phy",
> +};
> +
> +/* list of regulators */
> +static const char * const qmp_phy_vreg_l[] = {
> +	"vdda-phy", "vdda-pll",
> +};
> +
> +static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
> +	.serdes		= 0x0,
> +	.pcs		= 0xc00,
> +	.pcs_misc	= 0xa00,
> +	.tx		= 0x200,
> +	.rx		= 0x400,
> +	.tx2		= 0x600,
> +	.rx2		= 0x800,
> +};
> +
> +static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
> +	.lanes			= 2,
> +
> +	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
> +
> +	.serdes_tbl             = msm8998_usb3_serdes_tbl,
> +	.serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
> +	.tx_tbl                 = msm8998_usb3_tx_tbl,
> +	.tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
> +	.rx_tbl                 = msm8998_usb3_rx_tbl,
> +	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
> +	.pcs_tbl                = msm8998_usb3_pcs_tbl,
> +	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
> +	.vreg_list              = qmp_phy_vreg_l,
> +	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
> +	.regs                   = qmp_v3_usb3phy_regs_layout,
> +};
> +
> +static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
> +	.lanes			= 2,
> +
> +	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
> +
> +	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
> +	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
> +	.tx_tbl			= qcm2290_usb3_tx_tbl,
> +	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl),
> +	.rx_tbl			= qcm2290_usb3_rx_tbl,
> +	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
> +	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
> +	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> +	.vreg_list		= qmp_phy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
> +};
> +
> +static void qmp_usbc_configure_lane(void __iomem *base,
> +					const struct qmp_phy_init_tbl tbl[],
> +					int num,
> +					u8 lane_mask)
> +{
> +	int i;
> +	const struct qmp_phy_init_tbl *t = tbl;
> +
> +	if (!t)
> +		return;
> +
> +	for (i = 0; i < num; i++, t++) {
> +		if (!(t->lane_mask & lane_mask))
> +			continue;
> +
> +		writel(t->val, base + t->offset);
> +	}
> +}
> +
> +static void qmp_usbc_configure(void __iomem *base,
> +				   const struct qmp_phy_init_tbl tbl[],
> +				   int num)
> +{
> +	qmp_usbc_configure_lane(base, tbl, num, 0xff);
> +}
> +

Can this be inlined?

> +static int qmp_usbc_serdes_init(struct qmp_usbc *qmp)
> +{
> +	const struct qmp_phy_cfg *cfg = qmp->cfg;
> +	void __iomem *serdes = qmp->serdes;
> +	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
> +	int serdes_tbl_num = cfg->serdes_tbl_num;
> +
> +	qmp_usbc_configure(serdes, serdes_tbl, serdes_tbl_num);
> +
> +	return 0;
> +}

Can this be inlined?

[...]

> +	/* Tx, Rx, and PCS configurations */
> +	qmp_usbc_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
> +	qmp_usbc_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
> +
> +	if (cfg->lanes >= 2) {

Again, if (true) IIUC


> +		qmp_usbc_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
> +		qmp_usbc_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
> +	}
> +
> +	qmp_usbc_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
> +
> +	if (pcs_usb)

if (false)?

[...]

The rest looks to be boilerplate that's already present in at least
one more driver..

Konrad

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

* Re: [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling
  2024-01-13  5:42 ` [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling Dmitry Baryshkov
@ 2024-01-13 10:46   ` Konrad Dybcio
  2024-01-17  0:04   ` Jeff Johnson
  1 sibling, 0 replies; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:46 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> Now as all dual-lane PHYs have been migrated to a new driver, drop
> support for dual lanes configuration. If the PHY uses two lanes for USB,
> it is symthom that it should use either a combo USB+DP or a USB-C PHY
> driver.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

[...]

> -	if (cfg->lanes >= 2) {
> -		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
> -		if (IS_ERR(qmp->tx2))
> -			return PTR_ERR(qmp->tx2);
> -
> -		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
> -		if (IS_ERR(qmp->rx2))
> -			return PTR_ERR(qmp->rx2);
> -
> -		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
> -	} else {
> -		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
> -	}
> +	qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
>  
>  	if (IS_ERR(qmp->pcs_misc)) {
Since you may need a new revision, you can remove the neline
above to get a nice

ret = ...
if (ret)
	...

equivalent while at it

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

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

* Re: [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling
  2024-01-13  5:42 ` [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling Dmitry Baryshkov
@ 2024-01-13 10:46   ` Konrad Dybcio
  2024-01-13 14:16     ` Dmitry Baryshkov
  0 siblings, 1 reply; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:46 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> All USB-C PHYs use 2 lanes for the USB. Drop single lane handling in
> this driver.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Why is this not part of the introduction of that driver then?

Konrad

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

* Re: [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling
  2024-01-13  5:42 ` [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling Dmitry Baryshkov
@ 2024-01-13 10:48   ` Konrad Dybcio
  2024-01-13 14:17     ` Dmitry Baryshkov
  0 siblings, 1 reply; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:48 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> The USB-C PHYs on the msm8998, QCM2290 and SM6115 platforms use special
> register to control which lanes of the Type-C port are used for the
> SuperSpeed USB connection. Mimic the qmp-combo driver and handle this
> register.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

[...]

> +#if IS_ENABLED(CONFIG_TYPEC)

I understand some people may want their USB to work without TC compiled
in, but it looks funky to have a "USB-C PHY" with optional USB-C support..

Should we just depend on it in kconfig?

Konrad

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

* Re: [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks
  2024-01-13  5:42 ` [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks Dmitry Baryshkov
@ 2024-01-13 10:48   ` Konrad Dybcio
  2024-01-13 12:18   ` Bryan O'Donoghue
  1 sibling, 0 replies; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:48 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> Define VBUS regulator and the Type-C handling block as present on the
> Quacomm PMI632 PMIC.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/pmi632.dtsi | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
> index 4eb79e0ce40a..ccf288ddc987 100644
> --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
> @@ -45,6 +45,35 @@ pmic@2 {
>  		#address-cells = <1>;
>  		#size-cells = <0>;
>  
> +		pmi632_vbus: usb-vbus-regulator@1100 {
> +			compatible = "qcom,pmi632-vbus-reg", "qcom,pm8150b-vbus-reg";
> +			status = "disabled";
> +			reg = <0x1100>;

reg
status

> +		};
> +
> +		pmi632_typec: typec@1500 {
> +			compatible = "qcom,pmi632-typec";
> +			status = "disabled";

status last

> +			reg = <0x1500>;
> +			interrupts = <0x2 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 0x07 IRQ_TYPE_EDGE_RISING>;
> +			interrupt-names = "or-rid-detect-change",
> +					  "vpd-detect",
> +					  "cc-state-change",
> +					  "vconn-oc",
> +					  "vbus-change",
> +					  "attach-detach",
> +					  "legacy-cable-detect",
> +					  "try-snk-src-detect";
> +			vdd-vbus-supply = <&pmi632_vbus>;
> +		};

Konrad

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

* Re: [PATCH 12/13] arm64: dts: qcom: sm6115: drop pipe clock selection
  2024-01-13  5:42 ` [PATCH 12/13] arm64: dts: qcom: sm6115: drop pipe clock selection Dmitry Baryshkov
@ 2024-01-13 10:49   ` Konrad Dybcio
  0 siblings, 0 replies; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:49 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy,
	Vladimir Zapolskiy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
> 
> Stop selecting UTMI clock as the USB3 PIPE clock. This setting is
> incompatible with the USB host working in USB3 (SuperSpeed) mode.
> 
> Fixes: 9dd5f6dba729 ("arm64: dts: qcom: sm6115: Add USB SS qmp phy node")
> Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
> [DB: fixed commit message, dropped dr_mode setting]
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

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

* Re: [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling
  2024-01-13  5:42 ` [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling Dmitry Baryshkov
@ 2024-01-13 10:52   ` Konrad Dybcio
  2024-01-13 14:20     ` Dmitry Baryshkov
  0 siblings, 1 reply; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 10:52 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> Plug in USB-C related bits and pieces to enable USB role switching and
> USB-C orientation handling for the Qualcomm RB2 board.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 62 ++++++++++++++++++++++++++++++++
>  arch/arm64/boot/dts/qcom/sm6115.dtsi     | 38 ++++++++++++++++++++
>  2 files changed, 100 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
> index 52f31f3166c2..a96e3afb65bc 100644
> --- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
> +++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
> @@ -6,8 +6,10 @@
>  /dts-v1/;
>  
>  #include <dt-bindings/leds/common.h>
> +#include <dt-bindings/usb/pd.h>
>  #include "sm4250.dtsi"
>  #include "pm6125.dtsi"
> +#include "pmi632.dtsi"
>  
>  / {
>  	model = "Qualcomm Technologies, Inc. QRB4210 RB2";
> @@ -256,6 +258,53 @@ kypd_vol_up_n: kypd-vol-up-n-state {
>  	};
>  };
>  
> +&pmi632_typec {
> +	status = "okay";
> +
> +	connector {
> +		compatible = "usb-c-connector";
> +
> +		power-role = "dual";
> +		data-role = "dual";
> +		self-powered;
> +
> +		source-pdos = <PDO_FIXED(5000, 3000,
> +					 PDO_FIXED_DUAL_ROLE |
> +					 PDO_FIXED_USB_COMM |
> +					 PDO_FIXED_DATA_SWAP)>;
> +		sink-pdos = <PDO_FIXED(5000, 500,
> +					 PDO_FIXED_DUAL_ROLE |
> +					 PDO_FIXED_USB_COMM |
> +					 PDO_FIXED_DATA_SWAP)>;
> +		op-sink-microwatt = <10000000>;
So RB2 can provide 15 watts over the USB-C port, consume 2.5 but
requires 10? That doesn't make a whole lot of sense..

Unless I'm reading this wrong..

> +&usb_dwc3 {
> +	usb-role-switch;

Since this is a dual-role controller, I think this could live in the SoC
DT

> +};
> +
> +&usb_dwc3_hs {
> +	remote-endpoint = <&pmi632_hs_in>;
> +};
> +
>  &usb_hsphy {
>  	vdd-supply = <&vreg_l4a_0p9>;
>  	vdda-pll-supply = <&vreg_l12a_1p8>;
> @@ -618,10 +675,15 @@ &usb_hsphy {
>  &usb_qmpphy {
>  	vdda-phy-supply = <&vreg_l4a_0p9>;
>  	vdda-pll-supply = <&vreg_l12a_1p8>;
> +	orientation-switch;

Similarly, if this doesn't kaboom w/ our implementation too much, the
PHY itself has orientation detection capabilities

Konrad

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

* Re: [PATCH 04/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data
  2024-01-13  5:42 ` [PATCH 04/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data Dmitry Baryshkov
@ 2024-01-13 12:09   ` Bryan O'Donoghue
  0 siblings, 0 replies; 35+ messages in thread
From: Bryan O'Donoghue @ 2024-01-13 12:09 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Wesley Cheng, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13/01/2024 05:42, Dmitry Baryshkov wrote:
> Extend the Qualcomm USB-C QMP PHY schema with the USB-C related entry
> points: orientation-switch property and USB-C connection graph.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   .../bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml    | 39 ++++++++++++++++++++++
>   1 file changed, 39 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
> index 868fabd44d72..da5d4cbca24c 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
> @@ -50,6 +50,22 @@ properties:
>     "#phy-cells":
>       const: 0
>   
> +  orientation-switch:
> +    description:
> +      Flag the PHY as possible handler of USB Type-C orientation switching
> +    type: boolean
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    properties:
> +      port@0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Output endpoint of the PHY
> +
> +      port@1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Incoming endpoint from the USB controller
> +
>   required:
>     - compatible
>     - reg
> @@ -129,4 +145,27 @@ examples:
>   
>         vdda-phy-supply = <&vreg_l1a_0p875>;
>         vdda-pll-supply = <&vreg_l2a_1p2>;
> +
> +      orientation-switch;
> +
> +      ports {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        port@0 {
> +          reg = <0>;
> +
> +          endpoint {
> +            remote-endpoint = <&pmic_typec_mux_in>;
> +          };
> +        };
> +
> +        port@1 {
> +          reg = <1>;
> +
> +          endpoint {
> +            remote-endpoint = <&usb_dwc3_ss>;
> +          };
> +        };
> +      };
>       };
> 
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

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

* Re: [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks
  2024-01-13  5:42 ` [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks Dmitry Baryshkov
  2024-01-13 10:48   ` Konrad Dybcio
@ 2024-01-13 12:18   ` Bryan O'Donoghue
  1 sibling, 0 replies; 35+ messages in thread
From: Bryan O'Donoghue @ 2024-01-13 12:18 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Wesley Cheng, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13/01/2024 05:42, Dmitry Baryshkov wrote:
> Define VBUS regulator and the Type-C handling block as present on the
> Quacomm PMI632 PMIC.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   arch/arm64/boot/dts/qcom/pmi632.dtsi | 29 +++++++++++++++++++++++++++++
>   1 file changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
> index 4eb79e0ce40a..ccf288ddc987 100644
> --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
> @@ -45,6 +45,35 @@ pmic@2 {
>   		#address-cells = <1>;
>   		#size-cells = <0>;
>   
> +		pmi632_vbus: usb-vbus-regulator@1100 {
> +			compatible = "qcom,pmi632-vbus-reg", "qcom,pm8150b-vbus-reg";
> +			status = "disabled";
> +			reg = <0x1100>;
> +		};
> +
> +		pmi632_typec: typec@1500 {
> +			compatible = "qcom,pmi632-typec";
> +			status = "disabled";
> +			reg = <0x1500>;
> +			interrupts = <0x2 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 0x07 IRQ_TYPE_EDGE_RISING>;
> +			interrupt-names = "or-rid-detect-change",
> +					  "vpd-detect",
> +					  "cc-state-change",
> +					  "vconn-oc",
> +					  "vbus-change",
> +					  "attach-detach",
> +					  "legacy-cable-detect",
> +					  "try-snk-src-detect";
> +			vdd-vbus-supply = <&pmi632_vbus>;
> +		};
> +
>   		pmi632_temp: temp-alarm@2400 {
>   			compatible = "qcom,spmi-temp-alarm";
>   			reg = <0x2400>;
> 

LTGM

Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

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

* Re: [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC
  2024-01-13  5:42 ` [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC Dmitry Baryshkov
  2024-01-13 10:33   ` Konrad Dybcio
@ 2024-01-13 13:40   ` Bryan O'Donoghue
  1 sibling, 0 replies; 35+ messages in thread
From: Bryan O'Donoghue @ 2024-01-13 13:40 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Wesley Cheng, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13/01/2024 05:42, Dmitry Baryshkov wrote:
> The PMI632 PMIC support Type-C port handling, but lacks USB
> PowerDelivery support. The TCPM requires all callbacks to be provided
> by the implementation. Implement a special, 'stub' Qcom PD PHY
> implementation to enable the PMI632 support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/usb/typec/tcpm/qcom/Makefile               |  3 +-
>   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c      | 30 +++++++---
>   .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h    |  2 +
>   .../typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c   | 67 ++++++++++++++++++++++
>   4 files changed, 94 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm/qcom/Makefile b/drivers/usb/typec/tcpm/qcom/Makefile
> index dc1e8832e197..cc23042b9487 100644
> --- a/drivers/usb/typec/tcpm/qcom/Makefile
> +++ b/drivers/usb/typec/tcpm/qcom/Makefile
> @@ -3,4 +3,5 @@
>   obj-$(CONFIG_TYPEC_QCOM_PMIC)		+= qcom_pmic_tcpm.o
>   qcom_pmic_tcpm-y			+= qcom_pmic_typec.o \
>   					   qcom_pmic_typec_port.o \
> -					   qcom_pmic_typec_pdphy.o
> +					   qcom_pmic_typec_pdphy.o \
> +					   qcom_pmic_typec_pdphy_stub.o \
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> index 4f2dbf20da12..e2513549c58a 100644
> --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> @@ -118,7 +118,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
>   	const struct pmic_typec_resources *res;
>   	struct regmap *regmap;
>   	struct device *bridge_dev;
> -	u32 base[2];
> +	u32 base;
>   	int ret;
>   
>   	res = of_device_get_match_data(dev);
> @@ -145,7 +145,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
>   		return -ENODEV;
>   	}
>   
> -	ret = of_property_read_u32_array(np, "reg", base, 2);
> +	ret = of_property_read_u32_index(np, "reg", 0, &base);

So I had to do a double-take here but, this seems fine to me.

>   	if (ret)
>   		return ret;
>   
> @@ -154,14 +154,24 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
>   		return PTR_ERR(tcpm->pmic_typec_port);
>   
>   	ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
> -					 res->port_res, regmap, base[0]);
> +					 res->port_res, regmap, base);
>   	if (ret)
>   		return ret;
>   
> -	ret = res->pdphy_probe(pdev, tcpm,
> -			       res->pdphy_res, regmap, base[1]);
> -	if (ret)
> -		return ret;
> +	if (res->pdphy_res) {
> +		ret = of_property_read_u32_index(np, "reg", 1, &base);
> +		if (ret)
> +			return ret;
> +
> +		ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm,
> +						  res->pdphy_res, regmap, base);
> +		if (ret)
> +			return ret;
> +	} else {
> +		ret = qcom_pmic_typec_pdphy_stub_probe(pdev, tcpm);
> +		if (ret)
> +			return ret;
> +	}

Looks fine.

>   
>   	mutex_init(&tcpm->lock);
>   	platform_set_drvdata(pdev, tcpm);
> @@ -253,8 +263,14 @@ static struct pmic_typec_resources pm8150b_typec_res = {
>   	.port_res = &pm8150b_port_res,
>   };
>   
> +static struct pmic_typec_resources pmi632_typec_res = {
> +	/* PD PHY not present */
> +	.port_res = &pm8150b_port_res,
> +};
> +
>   static const struct of_device_id qcom_pmic_typec_table[] = {
>   	{ .compatible = "qcom,pm8150b-typec", .data = &pm8150b_typec_res },
> +	{ .compatible = "qcom,pmi632-typec", .data = &pmi632_typec_res },
>   	{ }
>   };
>   MODULE_DEVICE_TABLE(of, qcom_pmic_typec_table);
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> index b94eccadb042..2a7dedeb3009 100644
> --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> @@ -31,5 +31,7 @@ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
>   				const struct pmic_typec_pdphy_resources *res,
>   				struct regmap *regmap,
>   				u32 base);
> +int qcom_pmic_typec_pdphy_stub_probe(struct platform_device *pdev,
> +				     struct pmic_typec *tcpm);
>   
>   #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
> new file mode 100644
> index 000000000000..5d3b0e78d4d8
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
> @@ -0,0 +1,67 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024, Linaro Ltd. All rights reserved.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/usb/pd.h>
> +#include <linux/usb/tcpm.h>
> +#include "qcom_pmic_typec.h"
> +#include "qcom_pmic_typec_pdphy.h"
> +
> +static int qcom_pmic_typec_pdphy_stub_pd_transmit(struct tcpc_dev *tcpc,
> +						  enum tcpm_transmit_type type,
> +						  const struct pd_message *msg,
> +						  unsigned int negotiated_rev)
> +{
> +	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> +	struct device *dev = tcpm->dev;
> +
> +	dev_dbg(dev, "pdphy_transmit: type=%d\n", type);
> +
> +	tcpm_pd_transmit_complete(tcpm->tcpm_port,
> +				  TCPC_TX_SUCCESS);
> +
> +	return 0;
> +}
> +
> +static int qcom_pmic_typec_pdphy_stub_set_pd_rx(struct tcpc_dev *tcpc, bool on)
> +{
> +	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> +	struct device *dev = tcpm->dev;
> +
> +	dev_dbg(dev, "set_pd_rx: %s\n", on ? "on" : "off");
> +
> +	return 0;
> +}
> +
> +static int qcom_pmic_typec_pdphy_stub_set_roles(struct tcpc_dev *tcpc, bool attached,
> +						enum typec_role power_role,
> +						enum typec_data_role data_role)
> +{
> +	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> +	struct device *dev = tcpm->dev;
> +
> +	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
> +		data_role, power_role);
> +
> +	return 0;
> +}
> +
> +int qcom_pmic_typec_pdphy_stub_probe(struct platform_device *pdev,
> +				     struct pmic_typec *tcpm)
> +{
> +	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_stub_set_pd_rx;
> +	tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_stub_set_roles;
> +	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_stub_pd_transmit;
> +
> +	return 0;
> +}
> 

So this answers the question I had on IRC whether or not the Linux TCPM 
layer could tolerate a stubbed PD layers.

I think this _should_ be fine, I certainly have no problem with the 
approach overall and the intevention in the code seems small.

Good work.

Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

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

* Re: [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY
  2024-01-13  5:42 ` [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY Dmitry Baryshkov
  2024-01-13 10:32   ` Konrad Dybcio
@ 2024-01-13 13:43   ` Bryan O'Donoghue
  2024-01-13 14:24     ` Dmitry Baryshkov
  1 sibling, 1 reply; 35+ messages in thread
From: Bryan O'Donoghue @ 2024-01-13 13:43 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Wesley Cheng, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13/01/2024 05:42, Dmitry Baryshkov wrote:
> Rework Qualcomm PMIC TCPM driver to allow different platform-specific
> implementations of the PD PHY interface. While majority of platforms
> has the same of register for the PD PHY, some obscure ones (PMI632) do
> not have real PD PHY support. Add proper interface between the main
> module and the PD PHY backend to allow switching the PD PHY
> implementation.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c      | 100 ++-----------
>   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h      |  25 ++++
>   .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c    | 155 ++++++++++++++++++---
>   .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h    |  90 +-----------
>   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h |   4 +-
>   5 files changed, 178 insertions(+), 196 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> index 1a2b4bddaa97..4f2dbf20da12 100644
> --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> @@ -20,26 +20,15 @@
>   
>   #include <drm/bridge/aux-bridge.h>
>   
> +#include "qcom_pmic_typec.h"
>   #include "qcom_pmic_typec_pdphy.h"
>   #include "qcom_pmic_typec_port.h"
>   
>   struct pmic_typec_resources {
> -	struct pmic_typec_pdphy_resources	*pdphy_res;
> +	const struct pmic_typec_pdphy_resources	*pdphy_res;

If you are making one resource struct const then make both const.

>   	struct pmic_typec_port_resources	*port_res;
>   };
>   
> -struct pmic_typec {
> -	struct device		*dev;
> -	struct tcpm_port	*tcpm_port;
> -	struct tcpc_dev		tcpc;
> -	struct pmic_typec_pdphy	*pmic_typec_pdphy;
> -	struct pmic_typec_port	*pmic_typec_port;
> -	bool			vbus_enabled;
> -	struct mutex		lock;		/* VBUS state serialization */
> -};
> -
> -#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
> -
>   static int qcom_pmic_typec_get_vbus(struct tcpc_dev *tcpc)
>   {
>   	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> @@ -116,34 +105,6 @@ static int qcom_pmic_typec_start_toggling(struct tcpc_dev *tcpc,
>   						   port_type, cc);
>   }
>   
> -static int qcom_pmic_typec_set_roles(struct tcpc_dev *tcpc, bool attached,
> -				     enum typec_role power_role,
> -				     enum typec_data_role data_role)
> -{
> -	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> -
> -	return qcom_pmic_typec_pdphy_set_roles(tcpm->pmic_typec_pdphy,
> -					       data_role, power_role);
> -}
> -
> -static int qcom_pmic_typec_set_pd_rx(struct tcpc_dev *tcpc, bool on)
> -{
> -	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> -
> -	return qcom_pmic_typec_pdphy_set_pd_rx(tcpm->pmic_typec_pdphy, on);
> -}
> -
> -static int qcom_pmic_typec_pd_transmit(struct tcpc_dev *tcpc,
> -				       enum tcpm_transmit_type type,
> -				       const struct pd_message *msg,
> -				       unsigned int negotiated_rev)
> -{
> -	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> -
> -	return qcom_pmic_typec_pdphy_pd_transmit(tcpm->pmic_typec_pdphy, type,
> -						 msg, negotiated_rev);
> -}
> -
>   static int qcom_pmic_typec_init(struct tcpc_dev *tcpc)
>   {
>   	return 0;
> @@ -177,9 +138,6 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
>   	tcpm->tcpc.set_polarity = qcom_pmic_typec_set_polarity;
>   	tcpm->tcpc.set_vconn = qcom_pmic_typec_set_vconn;
>   	tcpm->tcpc.start_toggling = qcom_pmic_typec_start_toggling;
> -	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_set_pd_rx;
> -	tcpm->tcpc.set_roles = qcom_pmic_typec_set_roles;
> -	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pd_transmit;
>   
>   	regmap = dev_get_regmap(dev->parent, NULL);
>   	if (!regmap) {
> @@ -195,17 +153,13 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
>   	if (IS_ERR(tcpm->pmic_typec_port))
>   		return PTR_ERR(tcpm->pmic_typec_port);
>   
> -	tcpm->pmic_typec_pdphy = qcom_pmic_typec_pdphy_alloc(dev);
> -	if (IS_ERR(tcpm->pmic_typec_pdphy))
> -		return PTR_ERR(tcpm->pmic_typec_pdphy);
> -
>   	ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
>   					 res->port_res, regmap, base[0]);
>   	if (ret)
>   		return ret;
>   
> -	ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm->pmic_typec_pdphy,
> -					  res->pdphy_res, regmap, base[1]);
> +	ret = res->pdphy_probe(pdev, tcpm,
> +			       res->pdphy_res, regmap, base[1]);
>   	if (ret)
>   		return ret;
>   
> @@ -231,10 +185,11 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
>   	if (ret)
>   		goto fwnode_remove;
>   
> -	ret = qcom_pmic_typec_pdphy_start(tcpm->pmic_typec_pdphy,
> -					  tcpm->tcpm_port);
> -	if (ret)
> -		goto fwnode_remove;
> +	if (tcpm->pdphy_start) {
> +		ret = tcpm->pdphy_start(tcpm, tcpm->tcpm_port);
> +		if (ret)
> +			goto fwnode_remove;
> +	}

Its a bit of a minor nit but, instead of checking for tcpm->pdphy_start 
and tcpm->ppdphy_stop you could also populate the callbacks to return 
zero from stubs you add and make this code look just a bit neater.

I'd say that optional though but, for preference unless there's a good 
technical argument against it.

>   
>   	return 0;
>   
> @@ -248,46 +203,13 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
>   {
>   	struct pmic_typec *tcpm = platform_get_drvdata(pdev);
>   
> -	qcom_pmic_typec_pdphy_stop(tcpm->pmic_typec_pdphy);
> +	if (tcpm->pdphy_stop)
> +		tcpm->pdphy_stop(tcpm);
>   	qcom_pmic_typec_port_stop(tcpm->pmic_typec_port);
>   	tcpm_unregister_port(tcpm->tcpm_port);
>   	fwnode_remove_software_node(tcpm->tcpc.fwnode);
>   }
>   
> -static struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
> -	.irq_params = {
> -		{
> -			.virq = PMIC_PDPHY_SIG_TX_IRQ,
> -			.irq_name = "sig-tx",
> -		},
> -		{
> -			.virq = PMIC_PDPHY_SIG_RX_IRQ,
> -			.irq_name = "sig-rx",
> -		},
> -		{
> -			.virq = PMIC_PDPHY_MSG_TX_IRQ,
> -			.irq_name = "msg-tx",
> -		},
> -		{
> -			.virq = PMIC_PDPHY_MSG_RX_IRQ,
> -			.irq_name = "msg-rx",
> -		},
> -		{
> -			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
> -			.irq_name = "msg-tx-failed",
> -		},
> -		{
> -			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
> -			.irq_name = "msg-tx-discarded",
> -		},
> -		{
> -			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
> -			.irq_name = "msg-rx-discarded",
> -		},
> -	},
> -	.nr_irqs = 7,
> -};
> -
>   static struct pmic_typec_port_resources pm8150b_port_res = {
>   	.irq_params = {
>   		{
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
> new file mode 100644
> index 000000000000..da035916c12a
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +
> +#ifndef __QCOM_PMIC_TYPEC_H__
> +#define __QCOM_PMIC_TYPEC_H__
> +
> +struct pmic_typec {
> +	struct device		*dev;
> +	struct tcpm_port	*tcpm_port;
> +	struct tcpc_dev		tcpc;
> +	struct pmic_typec_pdphy	*pmic_typec_pdphy;
> +	struct pmic_typec_port	*pmic_typec_port;
> +	bool			vbus_enabled;
> +	struct mutex		lock;		/* VBUS state serialization */
> +
> +	int (*pdphy_start)(struct pmic_typec *tcpm,
> +			   struct tcpm_port *tcpm_port);
> +	void (*pdphy_stop)(struct pmic_typec *tcpm);
> +};
> +
> +#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
> +
> +#endif
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
> index 52c81378e36e..40511ce86a34 100644
> --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
> @@ -14,8 +14,74 @@
>   #include <linux/slab.h>
>   #include <linux/usb/pd.h>
>   #include <linux/usb/tcpm.h>
> +#include "qcom_pmic_typec.h"
>   #include "qcom_pmic_typec_pdphy.h"
>   
> +/* PD PHY register offsets and bit fields */
> +#define USB_PDPHY_MSG_CONFIG_REG	0x40
> +#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
> +#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
> +#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
> +
> +#define USB_PDPHY_EN_CONTROL_REG	0x46
> +#define CONTROL_ENABLE			BIT(0)
> +
> +#define USB_PDPHY_RX_STATUS_REG		0x4A
> +#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
> +
> +#define USB_PDPHY_FRAME_FILTER_REG	0x4C
> +#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
> +#define FRAME_FILTER_EN_SOP		BIT(0)
> +
> +#define USB_PDPHY_TX_SIZE_REG		0x42
> +#define TX_SIZE_MASK			0xF
> +
> +#define USB_PDPHY_TX_CONTROL_REG	0x44
> +#define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
> +#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
> +#define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
> +#define TX_CONTROL_SEND_SIGNAL		BIT(1)
> +#define TX_CONTROL_SEND_MSG		BIT(0)
> +
> +#define USB_PDPHY_RX_SIZE_REG		0x48
> +
> +#define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
> +#define RX_BUFFER_TOKEN			BIT(0)
> +
> +#define USB_PDPHY_BIST_MODE_REG		0x4E
> +#define BIST_MODE_MASK			0xF
> +#define BIST_ENABLE			BIT(7)
> +#define PD_MSG_BIST			0x3
> +#define PD_BIST_TEST_DATA_MODE		0x8
> +
> +#define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
> +#define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
> +
> +#define USB_PDPHY_RX_BUFFER_REG		0x80
> +
> +/* VDD regulator */
> +#define VDD_PDPHY_VOL_MIN		2800000	/* uV */
> +#define VDD_PDPHY_VOL_MAX		3300000	/* uV */
> +#define VDD_PDPHY_HPM_LOAD		3000	/* uA */
> +
> +/* Message Spec Rev field */
> +#define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
> +
> +/* timers */
> +#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
> +#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
> +
> +/* Interrupt numbers */
> +#define PMIC_PDPHY_SIG_TX_IRQ		0x0
> +#define PMIC_PDPHY_SIG_RX_IRQ		0x1
> +#define PMIC_PDPHY_MSG_TX_IRQ		0x2
> +#define PMIC_PDPHY_MSG_RX_IRQ		0x3
> +#define PMIC_PDPHY_MSG_TX_FAIL_IRQ	0x4
> +#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ	0x5
> +#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ	0x6
> +#define PMIC_PDPHY_FR_SWAP_IRQ		0x7
> +
> +
>   struct pmic_typec_pdphy_irq_data {
>   	int				virq;
>   	int				irq;
> @@ -231,11 +297,13 @@ qcom_pmic_typec_pdphy_pd_transmit_payload(struct pmic_typec_pdphy *pmic_typec_pd
>   	return ret;
>   }
>   
> -int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				      enum tcpm_transmit_type type,
> -				      const struct pd_message *msg,
> -				      unsigned int negotiated_rev)
> +static int qcom_pmic_typec_pdphy_pd_transmit(struct tcpc_dev *tcpc,
> +					     enum tcpm_transmit_type type,
> +					     const struct pd_message *msg,
> +					     unsigned int negotiated_rev)
>   {
> +	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> +	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
>   	struct device *dev = pmic_typec_pdphy->dev;
>   	int ret;
>   
> @@ -336,8 +404,10 @@ static irqreturn_t qcom_pmic_typec_pdphy_isr(int irq, void *dev_id)
>   	return IRQ_HANDLED;
>   }
>   
> -int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on)
> +static int qcom_pmic_typec_pdphy_set_pd_rx(struct tcpc_dev *tcpc, bool on)
>   {
> +	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> +	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
>   	unsigned long flags;
>   	int ret;
>   
> @@ -353,9 +423,12 @@ int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, b
>   	return ret;
>   }
>   
> -int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				    bool data_role_host, bool power_role_src)
> +static int qcom_pmic_typec_pdphy_set_roles(struct tcpc_dev *tcpc, bool attached,
> +					   enum typec_role power_role,
> +					   enum typec_data_role data_role)
>   {
> +	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> +	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
>   	struct device *dev = pmic_typec_pdphy->dev;
>   	unsigned long flags;
>   	int ret;
> @@ -366,12 +439,13 @@ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
>   				 pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
>   				 MSG_CONFIG_PORT_DATA_ROLE |
>   				 MSG_CONFIG_PORT_POWER_ROLE,
> -				 data_role_host << 3 | power_role_src << 2);
> +				 (data_role == TYPEC_HOST ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
> +				 (power_role == TYPEC_SOURCE ? MSG_CONFIG_PORT_POWER_ROLE : 0));
>   
>   	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
>   
>   	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
> -		data_role_host, power_role_src);
> +		data_role, power_role);
>   
>   	return ret;
>   }
> @@ -435,9 +509,10 @@ static int pmic_typec_pdphy_reset(struct pmic_typec_pdphy *pmic_typec_pdphy)
>   	return ret;
>   }
>   
> -int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				struct tcpm_port *tcpm_port)
> +static int qcom_pmic_typec_pdphy_start(struct pmic_typec *tcpm,
> +				       struct tcpm_port *tcpm_port)
>   {
> +	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
>   	int i;
>   	int ret;
>   
> @@ -457,8 +532,9 @@ int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
>   	return 0;
>   }
>   
> -void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
> +static void qcom_pmic_typec_pdphy_stop(struct pmic_typec *tcpm)
>   {
> +	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
>   	int i;
>   
>   	for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
> @@ -469,21 +545,55 @@ void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
>   	regulator_disable(pmic_typec_pdphy->vdd_pdphy);
>   }
>   
> -struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev)
> -{
> -	return devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
> -}
> +const struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
> +	.irq_params = {
> +		{
> +			.virq = PMIC_PDPHY_SIG_TX_IRQ,
> +			.irq_name = "sig-tx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_SIG_RX_IRQ,
> +			.irq_name = "sig-rx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_TX_IRQ,
> +			.irq_name = "msg-tx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_RX_IRQ,
> +			.irq_name = "msg-rx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
> +			.irq_name = "msg-tx-failed",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
> +			.irq_name = "msg-tx-discarded",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
> +			.irq_name = "msg-rx-discarded",
> +		},
> +	},
> +	.nr_irqs = 7,
> +};
>   
>   int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
> -				struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				struct pmic_typec_pdphy_resources *res,
> +				struct pmic_typec *tcpm,
> +				const struct pmic_typec_pdphy_resources *res,
>   				struct regmap *regmap,
>   				u32 base)
>   {
> +	struct pmic_typec_pdphy *pmic_typec_pdphy;
>   	struct device *dev = &pdev->dev;
>   	struct pmic_typec_pdphy_irq_data *irq_data;
>   	int i, ret, irq;
>   
> +	pmic_typec_pdphy = devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
> +	if (!pmic_typec_pdphy)
> +		return -ENOMEM;
> +
>   	if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
>   		return -EINVAL;
>   
> @@ -522,5 +632,14 @@ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
>   			return ret;
>   	}
>   
> +	tcpm->pmic_typec_pdphy = pmic_typec_pdphy;
> +
> +	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_set_pd_rx;
> +	tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_set_roles;
> +	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_pd_transmit;
> +
> +	tcpm->pdphy_start = qcom_pmic_typec_pdphy_start;
> +	tcpm->pdphy_stop = qcom_pmic_typec_pdphy_stop;
> +
>   	return 0;
>   }
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> index e67954e31b14..b94eccadb042 100644
> --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> @@ -8,74 +8,6 @@
>   
>   #include <linux/platform_device.h>
>   #include <linux/regmap.h>
> -#include <linux/usb/tcpm.h>
> -
> -#define USB_PDPHY_MAX_DATA_OBJ_LEN	28
> -#define USB_PDPHY_MSG_HDR_LEN		2
> -
> -/* PD PHY register offsets and bit fields */
> -#define USB_PDPHY_MSG_CONFIG_REG	0x40
> -#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
> -#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
> -#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
> -
> -#define USB_PDPHY_EN_CONTROL_REG	0x46
> -#define CONTROL_ENABLE			BIT(0)
> -
> -#define USB_PDPHY_RX_STATUS_REG		0x4A
> -#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
> -
> -#define USB_PDPHY_FRAME_FILTER_REG	0x4C
> -#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
> -#define FRAME_FILTER_EN_SOP		BIT(0)
> -
> -#define USB_PDPHY_TX_SIZE_REG		0x42
> -#define TX_SIZE_MASK			0xF
> -
> -#define USB_PDPHY_TX_CONTROL_REG	0x44
> -#define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
> -#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
> -#define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
> -#define TX_CONTROL_SEND_SIGNAL		BIT(1)
> -#define TX_CONTROL_SEND_MSG		BIT(0)
> -
> -#define USB_PDPHY_RX_SIZE_REG		0x48
> -
> -#define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
> -#define RX_BUFFER_TOKEN			BIT(0)
> -
> -#define USB_PDPHY_BIST_MODE_REG		0x4E
> -#define BIST_MODE_MASK			0xF
> -#define BIST_ENABLE			BIT(7)
> -#define PD_MSG_BIST			0x3
> -#define PD_BIST_TEST_DATA_MODE		0x8
> -
> -#define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
> -#define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
> -
> -#define USB_PDPHY_RX_BUFFER_REG		0x80
> -
> -/* VDD regulator */
> -#define VDD_PDPHY_VOL_MIN		2800000	/* uV */
> -#define VDD_PDPHY_VOL_MAX		3300000	/* uV */
> -#define VDD_PDPHY_HPM_LOAD		3000	/* uA */
> -
> -/* Message Spec Rev field */
> -#define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
> -
> -/* timers */
> -#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
> -#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
> -
> -/* Interrupt numbers */
> -#define PMIC_PDPHY_SIG_TX_IRQ		0x0
> -#define PMIC_PDPHY_SIG_RX_IRQ		0x1
> -#define PMIC_PDPHY_MSG_TX_IRQ		0x2
> -#define PMIC_PDPHY_MSG_RX_IRQ		0x3
> -#define PMIC_PDPHY_MSG_TX_FAIL_IRQ	0x4
> -#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ	0x5
> -#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ	0x6
> -#define PMIC_PDPHY_FR_SWAP_IRQ		0x7
>   
>   /* Resources */
>   #define PMIC_PDPHY_MAX_IRQS		0x08
> @@ -93,27 +25,11 @@ struct pmic_typec_pdphy_resources {
>   /* API */
>   struct pmic_typec_pdphy;
>   
> -struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev);
> -
> +extern const struct pmic_typec_pdphy_resources pm8150b_pdphy_res;
>   int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
> -				struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				struct pmic_typec_pdphy_resources *res,
> +				struct pmic_typec *tcpm,
> +				const struct pmic_typec_pdphy_resources *res,
>   				struct regmap *regmap,
>   				u32 base);
>   
> -int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				struct tcpm_port *tcpm_port);
> -
> -void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy);
> -
> -int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				    bool power_role_src, bool data_role_host);
> -
> -int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on);
> -
> -int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
> -				      enum tcpm_transmit_type type,
> -				      const struct pd_message *msg,
> -				      unsigned int negotiated_rev);
> -
>   #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
> index d4d358c680b6..4a892048908e 100644
> --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
> @@ -3,8 +3,8 @@
>    * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
>    * Copyright (c) 2023, Linaro Ltd. All rights reserved.
>    */
> -#ifndef __QCOM_PMIC_TYPEC_H__
> -#define __QCOM_PMIC_TYPEC_H__
> +#ifndef __QCOM_PMIC_TYPEC_PORT_H__
> +#define __QCOM_PMIC_TYPEC_PORT_H__
>   
>   #include <linux/platform_device.h>
>   #include <linux/usb/tcpm.h>
> 

Other than my nit above looks good.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>


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

* Re: [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC
  2024-01-13 10:33   ` Konrad Dybcio
@ 2024-01-13 13:58     ` Bryan O'Donoghue
  0 siblings, 0 replies; 35+ messages in thread
From: Bryan O'Donoghue @ 2024-01-13 13:58 UTC (permalink / raw)
  To: Konrad Dybcio, Dmitry Baryshkov, Bjorn Andersson, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Wesley Cheng, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 13/01/2024 10:33, Konrad Dybcio wrote:
> On 13.01.2024 06:42, Dmitry Baryshkov wrote:
>> The PMI632 PMIC support Type-C port handling, but lacks USB
>> PowerDelivery support. The TCPM requires all callbacks to be provided
>> by the implementation. Implement a special, 'stub' Qcom PD PHY
>> implementation to enable the PMI632 support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
> 
> [...]
> 
>>   #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
>> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
>> new file mode 100644
>> index 000000000000..5d3b0e78d4d8
>> --- /dev/null
>> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy_stub.c
> 
> Not a fan.
> 
> Maybe add some TCPM_FLAG_NO_PD and solve it in a generic manner?
> 
> Konrad

This is a good suggestion, provided its the direction Heikki and Guenter 
want to go.

Otherwise @Dmitry you can retain my Acked-by for the stubification.

---
bod

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

* Re: [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver
  2024-01-13 10:42   ` Konrad Dybcio
@ 2024-01-13 14:15     ` Dmitry Baryshkov
  2024-01-13 14:48       ` Konrad Dybcio
  0 siblings, 1 reply; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13 14:15 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Bjorn Andersson, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma, linux-arm-msm, devicetree,
	linux-usb, linux-phy

On Sat, 13 Jan 2024 at 12:42, Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>
> On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> > In preparation to adding Type-C handling for MSM8998, QCM2290 and SM6115
> > platforms, create new QMP USB-C PHY driver by splitting mentioned
> > platforms to a separate file. In future it will also be extended with
> > support for the DisplayPort handling. It will also be reused later for
> > such platforms as SDM660, SM6125, SM6150.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
>
> [...]
>
>
> > +#include "phy-qcom-qmp.h"
> > +#include "phy-qcom-qmp-pcs-misc-v3.h"
> > +
> > +/* QPHY_SW_RESET bit */
> > +#define SW_RESET                             BIT(0)
> > +/* QPHY_POWER_DOWN_CONTROL */
> > +#define SW_PWRDN                             BIT(0)
>
> Most / all of these defines could probably live in a header file.

For this (and several other comments), see
https://lore.kernel.org/linux-arm-msm/20240109-phy-qmp-merge-common-v1-0-572899a14318@linaro.org/

>
> [...]
>
> > +struct qmp_usbc_offsets {
> > +     u16 serdes;
> > +     u16 pcs;
> > +     u16 pcs_misc;
> > +     u16 pcs_usb;
> > +     u16 tx;
> > +     u16 rx;
> > +     /* for PHYs with >= 2 lanes */
>
> So, all PHYs within this driver if I'm following correctly

Yes. I just felt that it is easier to follow for copy & modify rather
than just rushing all the changes in. I can squash one of the next
patches that clear single-lane support out of this driver..

>
> > +     u16 tx2;
> > +     u16 rx2;
> > +};
> > +
>
> > +static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
> > +{
> > +     u32 reg;
> > +
> > +     reg = readl(base + offset);
> > +     reg |= val;
> > +     writel(reg, base + offset);
> > +
> > +     /* ensure that above write is through */
> > +     readl(base + offset);
> > +}
> > +
> > +static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
> > +{
> > +     u32 reg;
> > +
> > +     reg = readl(base + offset);
> > +     reg &= ~val;
> > +     writel(reg, base + offset);
> > +
> > +     /* ensure that above write is through */
> > +     readl(base + offset);
> > +}
>
> Maybe you could use regmap to avoid NIH-ing such accessors

regmap will still require posting through read, will it not?

>
> > +
> > +/* list of clocks required by phy */
> > +static const char * const qmp_usbc_phy_clk_l[] = {
> > +     "aux", "cfg_ahb", "ref", "com_aux",
> > +};
> > +
> > +/* list of resets */
> > +static const char * const usb3phy_legacy_reset_l[] = {
> > +     "phy", "common",
> > +};
> > +
> > +static const char * const usb3phy_reset_l[] = {
> > +     "phy_phy", "phy",
> > +};
> > +
> > +/* list of regulators */
> > +static const char * const qmp_phy_vreg_l[] = {
> > +     "vdda-phy", "vdda-pll",
> > +};
> > +
> > +static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
> > +     .serdes         = 0x0,
> > +     .pcs            = 0xc00,
> > +     .pcs_misc       = 0xa00,
> > +     .tx             = 0x200,
> > +     .rx             = 0x400,
> > +     .tx2            = 0x600,
> > +     .rx2            = 0x800,
> > +};
> > +
> > +static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
> > +     .lanes                  = 2,
> > +
> > +     .offsets                = &qmp_usbc_offsets_v3_qcm2290,
> > +
> > +     .serdes_tbl             = msm8998_usb3_serdes_tbl,
> > +     .serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
> > +     .tx_tbl                 = msm8998_usb3_tx_tbl,
> > +     .tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
> > +     .rx_tbl                 = msm8998_usb3_rx_tbl,
> > +     .rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
> > +     .pcs_tbl                = msm8998_usb3_pcs_tbl,
> > +     .pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
> > +     .vreg_list              = qmp_phy_vreg_l,
> > +     .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
> > +     .regs                   = qmp_v3_usb3phy_regs_layout,
> > +};
> > +
> > +static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
> > +     .lanes                  = 2,
> > +
> > +     .offsets                = &qmp_usbc_offsets_v3_qcm2290,
> > +
> > +     .serdes_tbl             = qcm2290_usb3_serdes_tbl,
> > +     .serdes_tbl_num         = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
> > +     .tx_tbl                 = qcm2290_usb3_tx_tbl,
> > +     .tx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
> > +     .rx_tbl                 = qcm2290_usb3_rx_tbl,
> > +     .rx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
> > +     .pcs_tbl                = qcm2290_usb3_pcs_tbl,
> > +     .pcs_tbl_num            = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> > +     .vreg_list              = qmp_phy_vreg_l,
> > +     .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
> > +     .regs                   = qmp_v3_usb3phy_regs_layout_qcm2290,
> > +};
> > +
> > +static void qmp_usbc_configure_lane(void __iomem *base,
> > +                                     const struct qmp_phy_init_tbl tbl[],
> > +                                     int num,
> > +                                     u8 lane_mask)
> > +{
> > +     int i;
> > +     const struct qmp_phy_init_tbl *t = tbl;
> > +
> > +     if (!t)
> > +             return;
> > +
> > +     for (i = 0; i < num; i++, t++) {
> > +             if (!(t->lane_mask & lane_mask))
> > +                     continue;
> > +
> > +             writel(t->val, base + t->offset);
> > +     }
> > +}
> > +
> > +static void qmp_usbc_configure(void __iomem *base,
> > +                                const struct qmp_phy_init_tbl tbl[],
> > +                                int num)
> > +{
> > +     qmp_usbc_configure_lane(base, tbl, num, 0xff);
> > +}
> > +
>
> Can this be inlined?

Yes and yes.

>
> > +static int qmp_usbc_serdes_init(struct qmp_usbc *qmp)
> > +{
> > +     const struct qmp_phy_cfg *cfg = qmp->cfg;
> > +     void __iomem *serdes = qmp->serdes;
> > +     const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
> > +     int serdes_tbl_num = cfg->serdes_tbl_num;
> > +
> > +     qmp_usbc_configure(serdes, serdes_tbl, serdes_tbl_num);
> > +
> > +     return 0;
> > +}
>
> Can this be inlined?
>
> [...]
>
> > +     /* Tx, Rx, and PCS configurations */
> > +     qmp_usbc_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
> > +     qmp_usbc_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
> > +
> > +     if (cfg->lanes >= 2) {
>
> Again, if (true) IIUC
>
>
> > +             qmp_usbc_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
> > +             qmp_usbc_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
> > +     }
> > +
> > +     qmp_usbc_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
> > +
> > +     if (pcs_usb)
>
> if (false)?

Nice catch.

>
> [...]
>
> The rest looks to be boilerplate that's already present in at least
> one more driver..
>
> Konrad



-- 
With best wishes
Dmitry

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

* Re: [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling
  2024-01-13 10:46   ` Konrad Dybcio
@ 2024-01-13 14:16     ` Dmitry Baryshkov
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13 14:16 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Bjorn Andersson, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma, linux-arm-msm, devicetree,
	linux-usb, linux-phy

On Sat, 13 Jan 2024 at 12:46, Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>
> On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> > All USB-C PHYs use 2 lanes for the USB. Drop single lane handling in
> > this driver.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
>
> Why is this not part of the introduction of that driver then?

Sure, let's squash it and perform other mentioned cleanups.

>
> Konrad



-- 
With best wishes
Dmitry

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

* Re: [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling
  2024-01-13 10:48   ` Konrad Dybcio
@ 2024-01-13 14:17     ` Dmitry Baryshkov
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13 14:17 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Bjorn Andersson, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma, linux-arm-msm, devicetree,
	linux-usb, linux-phy

On Sat, 13 Jan 2024 at 12:48, Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>
> On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> > The USB-C PHYs on the msm8998, QCM2290 and SM6115 platforms use special
> > register to control which lanes of the Type-C port are used for the
> > SuperSpeed USB connection. Mimic the qmp-combo driver and handle this
> > register.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
>
> [...]
>
> > +#if IS_ENABLED(CONFIG_TYPEC)
>
> I understand some people may want their USB to work without TC compiled
> in, but it looks funky to have a "USB-C PHY" with optional USB-C support..
>
> Should we just depend on it in kconfig?

Well, we didn't for combo PHY. Also both PHYs support working with
just micro-/mini-USB OTG.
I'll wait for Vinod's feedback here.


-- 
With best wishes
Dmitry

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

* Re: [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling
  2024-01-13 10:52   ` Konrad Dybcio
@ 2024-01-13 14:20     ` Dmitry Baryshkov
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13 14:20 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Bjorn Andersson, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma, linux-arm-msm, devicetree,
	linux-usb, linux-phy

On Sat, 13 Jan 2024 at 12:52, Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>
> On 13.01.2024 06:42, Dmitry Baryshkov wrote:
> > Plug in USB-C related bits and pieces to enable USB role switching and
> > USB-C orientation handling for the Qualcomm RB2 board.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >  arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 62 ++++++++++++++++++++++++++++++++
> >  arch/arm64/boot/dts/qcom/sm6115.dtsi     | 38 ++++++++++++++++++++
> >  2 files changed, 100 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
> > index 52f31f3166c2..a96e3afb65bc 100644
> > --- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
> > +++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
> > @@ -6,8 +6,10 @@
> >  /dts-v1/;
> >
> >  #include <dt-bindings/leds/common.h>
> > +#include <dt-bindings/usb/pd.h>
> >  #include "sm4250.dtsi"
> >  #include "pm6125.dtsi"
> > +#include "pmi632.dtsi"
> >
> >  / {
> >       model = "Qualcomm Technologies, Inc. QRB4210 RB2";
> > @@ -256,6 +258,53 @@ kypd_vol_up_n: kypd-vol-up-n-state {
> >       };
> >  };
> >
> > +&pmi632_typec {
> > +     status = "okay";
> > +
> > +     connector {
> > +             compatible = "usb-c-connector";
> > +
> > +             power-role = "dual";
> > +             data-role = "dual";
> > +             self-powered;
> > +
> > +             source-pdos = <PDO_FIXED(5000, 3000,
> > +                                      PDO_FIXED_DUAL_ROLE |
> > +                                      PDO_FIXED_USB_COMM |
> > +                                      PDO_FIXED_DATA_SWAP)>;
> > +             sink-pdos = <PDO_FIXED(5000, 500,
> > +                                      PDO_FIXED_DUAL_ROLE |
> > +                                      PDO_FIXED_USB_COMM |
> > +                                      PDO_FIXED_DATA_SWAP)>;
> > +             op-sink-microwatt = <10000000>;
> So RB2 can provide 15 watts over the USB-C port, consume 2.5 but
> requires 10? That doesn't make a whole lot of sense..
>
> Unless I'm reading this wrong..

Let me double-check the properties and the docs before answering.

>
> > +&usb_dwc3 {
> > +     usb-role-switch;
>
> Since this is a dual-role controller, I think this could live in the SoC

Sure. Should we update other boards too?

> DT
>
> > +};
> > +
> > +&usb_dwc3_hs {
> > +     remote-endpoint = <&pmi632_hs_in>;
> > +};
> > +
> >  &usb_hsphy {
> >       vdd-supply = <&vreg_l4a_0p9>;
> >       vdda-pll-supply = <&vreg_l12a_1p8>;
> > @@ -618,10 +675,15 @@ &usb_hsphy {
> >  &usb_qmpphy {
> >       vdda-phy-supply = <&vreg_l4a_0p9>;
> >       vdda-pll-supply = <&vreg_l12a_1p8>;
> > +     orientation-switch;
>
> Similarly, if this doesn't kaboom w/ our implementation too much, the
> PHY itself has orientation detection capabilities
>
> Konrad



-- 
With best wishes
Dmitry

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

* Re: [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY
  2024-01-13 13:43   ` Bryan O'Donoghue
@ 2024-01-13 14:24     ` Dmitry Baryshkov
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Baryshkov @ 2024-01-13 14:24 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Bjorn Andersson, Konrad Dybcio, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Greg Kroah-Hartman, Vinod Koul, Kishon Vijay Abraham I,
	Guenter Roeck, Heikki Krogerus, Philipp Zabel, Bhupesh Sharma,
	linux-arm-msm, devicetree, linux-usb, linux-phy

On Sat, 13 Jan 2024 at 15:43, Bryan O'Donoghue
<bryan.odonoghue@linaro.org> wrote:
>
> On 13/01/2024 05:42, Dmitry Baryshkov wrote:
> > Rework Qualcomm PMIC TCPM driver to allow different platform-specific
> > implementations of the PD PHY interface. While majority of platforms
> > has the same of register for the PD PHY, some obscure ones (PMI632) do
> > not have real PD PHY support. Add proper interface between the main
> > module and the PD PHY backend to allow switching the PD PHY
> > implementation.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c      | 100 ++-----------
> >   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h      |  25 ++++
> >   .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c    | 155 ++++++++++++++++++---
> >   .../usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h    |  90 +-----------
> >   drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h |   4 +-
> >   5 files changed, 178 insertions(+), 196 deletions(-)
> >
> > diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> > index 1a2b4bddaa97..4f2dbf20da12 100644
> > --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> > +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> > @@ -20,26 +20,15 @@
> >
> >   #include <drm/bridge/aux-bridge.h>
> >
> > +#include "qcom_pmic_typec.h"
> >   #include "qcom_pmic_typec_pdphy.h"
> >   #include "qcom_pmic_typec_port.h"
> >
> >   struct pmic_typec_resources {
> > -     struct pmic_typec_pdphy_resources       *pdphy_res;
> > +     const struct pmic_typec_pdphy_resources *pdphy_res;
>
> If you are making one resource struct const then make both const.

Let's maybe implement a similar patch for the port implementation.
Maybe this will help with Type-C support on sdm845 / sdm660 platforms,
which have the same PDPHY but different TYPEC block.

>
> >       struct pmic_typec_port_resources        *port_res;
> >   };
> >
> > -struct pmic_typec {
> > -     struct device           *dev;
> > -     struct tcpm_port        *tcpm_port;
> > -     struct tcpc_dev         tcpc;
> > -     struct pmic_typec_pdphy *pmic_typec_pdphy;
> > -     struct pmic_typec_port  *pmic_typec_port;
> > -     bool                    vbus_enabled;
> > -     struct mutex            lock;           /* VBUS state serialization */
> > -};
> > -
> > -#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
> > -
> >   static int qcom_pmic_typec_get_vbus(struct tcpc_dev *tcpc)
> >   {
> >       struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > @@ -116,34 +105,6 @@ static int qcom_pmic_typec_start_toggling(struct tcpc_dev *tcpc,
> >                                                  port_type, cc);
> >   }
> >
> > -static int qcom_pmic_typec_set_roles(struct tcpc_dev *tcpc, bool attached,
> > -                                  enum typec_role power_role,
> > -                                  enum typec_data_role data_role)
> > -{
> > -     struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > -
> > -     return qcom_pmic_typec_pdphy_set_roles(tcpm->pmic_typec_pdphy,
> > -                                            data_role, power_role);
> > -}
> > -
> > -static int qcom_pmic_typec_set_pd_rx(struct tcpc_dev *tcpc, bool on)
> > -{
> > -     struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > -
> > -     return qcom_pmic_typec_pdphy_set_pd_rx(tcpm->pmic_typec_pdphy, on);
> > -}
> > -
> > -static int qcom_pmic_typec_pd_transmit(struct tcpc_dev *tcpc,
> > -                                    enum tcpm_transmit_type type,
> > -                                    const struct pd_message *msg,
> > -                                    unsigned int negotiated_rev)
> > -{
> > -     struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > -
> > -     return qcom_pmic_typec_pdphy_pd_transmit(tcpm->pmic_typec_pdphy, type,
> > -                                              msg, negotiated_rev);
> > -}
> > -
> >   static int qcom_pmic_typec_init(struct tcpc_dev *tcpc)
> >   {
> >       return 0;
> > @@ -177,9 +138,6 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
> >       tcpm->tcpc.set_polarity = qcom_pmic_typec_set_polarity;
> >       tcpm->tcpc.set_vconn = qcom_pmic_typec_set_vconn;
> >       tcpm->tcpc.start_toggling = qcom_pmic_typec_start_toggling;
> > -     tcpm->tcpc.set_pd_rx = qcom_pmic_typec_set_pd_rx;
> > -     tcpm->tcpc.set_roles = qcom_pmic_typec_set_roles;
> > -     tcpm->tcpc.pd_transmit = qcom_pmic_typec_pd_transmit;
> >
> >       regmap = dev_get_regmap(dev->parent, NULL);
> >       if (!regmap) {
> > @@ -195,17 +153,13 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
> >       if (IS_ERR(tcpm->pmic_typec_port))
> >               return PTR_ERR(tcpm->pmic_typec_port);
> >
> > -     tcpm->pmic_typec_pdphy = qcom_pmic_typec_pdphy_alloc(dev);
> > -     if (IS_ERR(tcpm->pmic_typec_pdphy))
> > -             return PTR_ERR(tcpm->pmic_typec_pdphy);
> > -
> >       ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
> >                                        res->port_res, regmap, base[0]);
> >       if (ret)
> >               return ret;
> >
> > -     ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm->pmic_typec_pdphy,
> > -                                       res->pdphy_res, regmap, base[1]);
> > +     ret = res->pdphy_probe(pdev, tcpm,
> > +                            res->pdphy_res, regmap, base[1]);
> >       if (ret)
> >               return ret;
> >
> > @@ -231,10 +185,11 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
> >       if (ret)
> >               goto fwnode_remove;
> >
> > -     ret = qcom_pmic_typec_pdphy_start(tcpm->pmic_typec_pdphy,
> > -                                       tcpm->tcpm_port);
> > -     if (ret)
> > -             goto fwnode_remove;
> > +     if (tcpm->pdphy_start) {
> > +             ret = tcpm->pdphy_start(tcpm, tcpm->tcpm_port);
> > +             if (ret)
> > +                     goto fwnode_remove;
> > +     }
>
> Its a bit of a minor nit but, instead of checking for tcpm->pdphy_start
> and tcpm->ppdphy_stop you could also populate the callbacks to return
> zero from stubs you add and make this code look just a bit neater.
>
> I'd say that optional though but, for preference unless there's a good
> technical argument against it.

I don't like empty callbacks for the sake of the callback itself. But
this will follow the TCPM ideology.

>
> >
> >       return 0;
> >
> > @@ -248,46 +203,13 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
> >   {
> >       struct pmic_typec *tcpm = platform_get_drvdata(pdev);
> >
> > -     qcom_pmic_typec_pdphy_stop(tcpm->pmic_typec_pdphy);
> > +     if (tcpm->pdphy_stop)
> > +             tcpm->pdphy_stop(tcpm);
> >       qcom_pmic_typec_port_stop(tcpm->pmic_typec_port);
> >       tcpm_unregister_port(tcpm->tcpm_port);
> >       fwnode_remove_software_node(tcpm->tcpc.fwnode);
> >   }
> >
> > -static struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
> > -     .irq_params = {
> > -             {
> > -                     .virq = PMIC_PDPHY_SIG_TX_IRQ,
> > -                     .irq_name = "sig-tx",
> > -             },
> > -             {
> > -                     .virq = PMIC_PDPHY_SIG_RX_IRQ,
> > -                     .irq_name = "sig-rx",
> > -             },
> > -             {
> > -                     .virq = PMIC_PDPHY_MSG_TX_IRQ,
> > -                     .irq_name = "msg-tx",
> > -             },
> > -             {
> > -                     .virq = PMIC_PDPHY_MSG_RX_IRQ,
> > -                     .irq_name = "msg-rx",
> > -             },
> > -             {
> > -                     .virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
> > -                     .irq_name = "msg-tx-failed",
> > -             },
> > -             {
> > -                     .virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
> > -                     .irq_name = "msg-tx-discarded",
> > -             },
> > -             {
> > -                     .virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
> > -                     .irq_name = "msg-rx-discarded",
> > -             },
> > -     },
> > -     .nr_irqs = 7,
> > -};
> > -
> >   static struct pmic_typec_port_resources pm8150b_port_res = {
> >       .irq_params = {
> >               {
> > diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
> > new file mode 100644
> > index 000000000000..da035916c12a
> > --- /dev/null
> > +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> > + */
> > +
> > +#ifndef __QCOM_PMIC_TYPEC_H__
> > +#define __QCOM_PMIC_TYPEC_H__
> > +
> > +struct pmic_typec {
> > +     struct device           *dev;
> > +     struct tcpm_port        *tcpm_port;
> > +     struct tcpc_dev         tcpc;
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy;
> > +     struct pmic_typec_port  *pmic_typec_port;
> > +     bool                    vbus_enabled;
> > +     struct mutex            lock;           /* VBUS state serialization */
> > +
> > +     int (*pdphy_start)(struct pmic_typec *tcpm,
> > +                        struct tcpm_port *tcpm_port);
> > +     void (*pdphy_stop)(struct pmic_typec *tcpm);
> > +};
> > +
> > +#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
> > +
> > +#endif
> > diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
> > index 52c81378e36e..40511ce86a34 100644
> > --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
> > +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
> > @@ -14,8 +14,74 @@
> >   #include <linux/slab.h>
> >   #include <linux/usb/pd.h>
> >   #include <linux/usb/tcpm.h>
> > +#include "qcom_pmic_typec.h"
> >   #include "qcom_pmic_typec_pdphy.h"
> >
> > +/* PD PHY register offsets and bit fields */
> > +#define USB_PDPHY_MSG_CONFIG_REG     0x40
> > +#define MSG_CONFIG_PORT_DATA_ROLE    BIT(3)
> > +#define MSG_CONFIG_PORT_POWER_ROLE   BIT(2)
> > +#define MSG_CONFIG_SPEC_REV_MASK     (BIT(1) | BIT(0))
> > +
> > +#define USB_PDPHY_EN_CONTROL_REG     0x46
> > +#define CONTROL_ENABLE                       BIT(0)
> > +
> > +#define USB_PDPHY_RX_STATUS_REG              0x4A
> > +#define RX_FRAME_TYPE                        (BIT(0) | BIT(1) | BIT(2))
> > +
> > +#define USB_PDPHY_FRAME_FILTER_REG   0x4C
> > +#define FRAME_FILTER_EN_HARD_RESET   BIT(5)
> > +#define FRAME_FILTER_EN_SOP          BIT(0)
> > +
> > +#define USB_PDPHY_TX_SIZE_REG                0x42
> > +#define TX_SIZE_MASK                 0xF
> > +
> > +#define USB_PDPHY_TX_CONTROL_REG     0x44
> > +#define TX_CONTROL_RETRY_COUNT(n)    (((n) & 0x3) << 5)
> > +#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
> > +#define TX_CONTROL_FRAME_TYPE_CABLE_RESET    (0x1 << 2)
> > +#define TX_CONTROL_SEND_SIGNAL               BIT(1)
> > +#define TX_CONTROL_SEND_MSG          BIT(0)
> > +
> > +#define USB_PDPHY_RX_SIZE_REG                0x48
> > +
> > +#define USB_PDPHY_RX_ACKNOWLEDGE_REG 0x4B
> > +#define RX_BUFFER_TOKEN                      BIT(0)
> > +
> > +#define USB_PDPHY_BIST_MODE_REG              0x4E
> > +#define BIST_MODE_MASK                       0xF
> > +#define BIST_ENABLE                  BIT(7)
> > +#define PD_MSG_BIST                  0x3
> > +#define PD_BIST_TEST_DATA_MODE               0x8
> > +
> > +#define USB_PDPHY_TX_BUFFER_HDR_REG  0x60
> > +#define USB_PDPHY_TX_BUFFER_DATA_REG 0x62
> > +
> > +#define USB_PDPHY_RX_BUFFER_REG              0x80
> > +
> > +/* VDD regulator */
> > +#define VDD_PDPHY_VOL_MIN            2800000 /* uV */
> > +#define VDD_PDPHY_VOL_MAX            3300000 /* uV */
> > +#define VDD_PDPHY_HPM_LOAD           3000    /* uA */
> > +
> > +/* Message Spec Rev field */
> > +#define PD_MSG_HDR_REV(hdr)          (((hdr) >> 6) & 3)
> > +
> > +/* timers */
> > +#define RECEIVER_RESPONSE_TIME               15      /* tReceiverResponse */
> > +#define HARD_RESET_COMPLETE_TIME     5       /* tHardResetComplete */
> > +
> > +/* Interrupt numbers */
> > +#define PMIC_PDPHY_SIG_TX_IRQ                0x0
> > +#define PMIC_PDPHY_SIG_RX_IRQ                0x1
> > +#define PMIC_PDPHY_MSG_TX_IRQ                0x2
> > +#define PMIC_PDPHY_MSG_RX_IRQ                0x3
> > +#define PMIC_PDPHY_MSG_TX_FAIL_IRQ   0x4
> > +#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ        0x5
> > +#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ        0x6
> > +#define PMIC_PDPHY_FR_SWAP_IRQ               0x7
> > +
> > +
> >   struct pmic_typec_pdphy_irq_data {
> >       int                             virq;
> >       int                             irq;
> > @@ -231,11 +297,13 @@ qcom_pmic_typec_pdphy_pd_transmit_payload(struct pmic_typec_pdphy *pmic_typec_pd
> >       return ret;
> >   }
> >
> > -int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                                   enum tcpm_transmit_type type,
> > -                                   const struct pd_message *msg,
> > -                                   unsigned int negotiated_rev)
> > +static int qcom_pmic_typec_pdphy_pd_transmit(struct tcpc_dev *tcpc,
> > +                                          enum tcpm_transmit_type type,
> > +                                          const struct pd_message *msg,
> > +                                          unsigned int negotiated_rev)
> >   {
> > +     struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
> >       struct device *dev = pmic_typec_pdphy->dev;
> >       int ret;
> >
> > @@ -336,8 +404,10 @@ static irqreturn_t qcom_pmic_typec_pdphy_isr(int irq, void *dev_id)
> >       return IRQ_HANDLED;
> >   }
> >
> > -int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on)
> > +static int qcom_pmic_typec_pdphy_set_pd_rx(struct tcpc_dev *tcpc, bool on)
> >   {
> > +     struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
> >       unsigned long flags;
> >       int ret;
> >
> > @@ -353,9 +423,12 @@ int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, b
> >       return ret;
> >   }
> >
> > -int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                                 bool data_role_host, bool power_role_src)
> > +static int qcom_pmic_typec_pdphy_set_roles(struct tcpc_dev *tcpc, bool attached,
> > +                                        enum typec_role power_role,
> > +                                        enum typec_data_role data_role)
> >   {
> > +     struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
> >       struct device *dev = pmic_typec_pdphy->dev;
> >       unsigned long flags;
> >       int ret;
> > @@ -366,12 +439,13 @@ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
> >                                pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
> >                                MSG_CONFIG_PORT_DATA_ROLE |
> >                                MSG_CONFIG_PORT_POWER_ROLE,
> > -                              data_role_host << 3 | power_role_src << 2);
> > +                              (data_role == TYPEC_HOST ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
> > +                              (power_role == TYPEC_SOURCE ? MSG_CONFIG_PORT_POWER_ROLE : 0));
> >
> >       spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
> >
> >       dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
> > -             data_role_host, power_role_src);
> > +             data_role, power_role);
> >
> >       return ret;
> >   }
> > @@ -435,9 +509,10 @@ static int pmic_typec_pdphy_reset(struct pmic_typec_pdphy *pmic_typec_pdphy)
> >       return ret;
> >   }
> >
> > -int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                             struct tcpm_port *tcpm_port)
> > +static int qcom_pmic_typec_pdphy_start(struct pmic_typec *tcpm,
> > +                                    struct tcpm_port *tcpm_port)
> >   {
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
> >       int i;
> >       int ret;
> >
> > @@ -457,8 +532,9 @@ int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
> >       return 0;
> >   }
> >
> > -void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
> > +static void qcom_pmic_typec_pdphy_stop(struct pmic_typec *tcpm)
> >   {
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
> >       int i;
> >
> >       for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
> > @@ -469,21 +545,55 @@ void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
> >       regulator_disable(pmic_typec_pdphy->vdd_pdphy);
> >   }
> >
> > -struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev)
> > -{
> > -     return devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
> > -}
> > +const struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
> > +     .irq_params = {
> > +             {
> > +                     .virq = PMIC_PDPHY_SIG_TX_IRQ,
> > +                     .irq_name = "sig-tx",
> > +             },
> > +             {
> > +                     .virq = PMIC_PDPHY_SIG_RX_IRQ,
> > +                     .irq_name = "sig-rx",
> > +             },
> > +             {
> > +                     .virq = PMIC_PDPHY_MSG_TX_IRQ,
> > +                     .irq_name = "msg-tx",
> > +             },
> > +             {
> > +                     .virq = PMIC_PDPHY_MSG_RX_IRQ,
> > +                     .irq_name = "msg-rx",
> > +             },
> > +             {
> > +                     .virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
> > +                     .irq_name = "msg-tx-failed",
> > +             },
> > +             {
> > +                     .virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
> > +                     .irq_name = "msg-tx-discarded",
> > +             },
> > +             {
> > +                     .virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
> > +                     .irq_name = "msg-rx-discarded",
> > +             },
> > +     },
> > +     .nr_irqs = 7,
> > +};
> >
> >   int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
> > -                             struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                             struct pmic_typec_pdphy_resources *res,
> > +                             struct pmic_typec *tcpm,
> > +                             const struct pmic_typec_pdphy_resources *res,
> >                               struct regmap *regmap,
> >                               u32 base)
> >   {
> > +     struct pmic_typec_pdphy *pmic_typec_pdphy;
> >       struct device *dev = &pdev->dev;
> >       struct pmic_typec_pdphy_irq_data *irq_data;
> >       int i, ret, irq;
> >
> > +     pmic_typec_pdphy = devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
> > +     if (!pmic_typec_pdphy)
> > +             return -ENOMEM;
> > +
> >       if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
> >               return -EINVAL;
> >
> > @@ -522,5 +632,14 @@ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
> >                       return ret;
> >       }
> >
> > +     tcpm->pmic_typec_pdphy = pmic_typec_pdphy;
> > +
> > +     tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_set_pd_rx;
> > +     tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_set_roles;
> > +     tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_pd_transmit;
> > +
> > +     tcpm->pdphy_start = qcom_pmic_typec_pdphy_start;
> > +     tcpm->pdphy_stop = qcom_pmic_typec_pdphy_stop;
> > +
> >       return 0;
> >   }
> > diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> > index e67954e31b14..b94eccadb042 100644
> > --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> > +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
> > @@ -8,74 +8,6 @@
> >
> >   #include <linux/platform_device.h>
> >   #include <linux/regmap.h>
> > -#include <linux/usb/tcpm.h>
> > -
> > -#define USB_PDPHY_MAX_DATA_OBJ_LEN   28
> > -#define USB_PDPHY_MSG_HDR_LEN                2
> > -
> > -/* PD PHY register offsets and bit fields */
> > -#define USB_PDPHY_MSG_CONFIG_REG     0x40
> > -#define MSG_CONFIG_PORT_DATA_ROLE    BIT(3)
> > -#define MSG_CONFIG_PORT_POWER_ROLE   BIT(2)
> > -#define MSG_CONFIG_SPEC_REV_MASK     (BIT(1) | BIT(0))
> > -
> > -#define USB_PDPHY_EN_CONTROL_REG     0x46
> > -#define CONTROL_ENABLE                       BIT(0)
> > -
> > -#define USB_PDPHY_RX_STATUS_REG              0x4A
> > -#define RX_FRAME_TYPE                        (BIT(0) | BIT(1) | BIT(2))
> > -
> > -#define USB_PDPHY_FRAME_FILTER_REG   0x4C
> > -#define FRAME_FILTER_EN_HARD_RESET   BIT(5)
> > -#define FRAME_FILTER_EN_SOP          BIT(0)
> > -
> > -#define USB_PDPHY_TX_SIZE_REG                0x42
> > -#define TX_SIZE_MASK                 0xF
> > -
> > -#define USB_PDPHY_TX_CONTROL_REG     0x44
> > -#define TX_CONTROL_RETRY_COUNT(n)    (((n) & 0x3) << 5)
> > -#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
> > -#define TX_CONTROL_FRAME_TYPE_CABLE_RESET    (0x1 << 2)
> > -#define TX_CONTROL_SEND_SIGNAL               BIT(1)
> > -#define TX_CONTROL_SEND_MSG          BIT(0)
> > -
> > -#define USB_PDPHY_RX_SIZE_REG                0x48
> > -
> > -#define USB_PDPHY_RX_ACKNOWLEDGE_REG 0x4B
> > -#define RX_BUFFER_TOKEN                      BIT(0)
> > -
> > -#define USB_PDPHY_BIST_MODE_REG              0x4E
> > -#define BIST_MODE_MASK                       0xF
> > -#define BIST_ENABLE                  BIT(7)
> > -#define PD_MSG_BIST                  0x3
> > -#define PD_BIST_TEST_DATA_MODE               0x8
> > -
> > -#define USB_PDPHY_TX_BUFFER_HDR_REG  0x60
> > -#define USB_PDPHY_TX_BUFFER_DATA_REG 0x62
> > -
> > -#define USB_PDPHY_RX_BUFFER_REG              0x80
> > -
> > -/* VDD regulator */
> > -#define VDD_PDPHY_VOL_MIN            2800000 /* uV */
> > -#define VDD_PDPHY_VOL_MAX            3300000 /* uV */
> > -#define VDD_PDPHY_HPM_LOAD           3000    /* uA */
> > -
> > -/* Message Spec Rev field */
> > -#define PD_MSG_HDR_REV(hdr)          (((hdr) >> 6) & 3)
> > -
> > -/* timers */
> > -#define RECEIVER_RESPONSE_TIME               15      /* tReceiverResponse */
> > -#define HARD_RESET_COMPLETE_TIME     5       /* tHardResetComplete */
> > -
> > -/* Interrupt numbers */
> > -#define PMIC_PDPHY_SIG_TX_IRQ                0x0
> > -#define PMIC_PDPHY_SIG_RX_IRQ                0x1
> > -#define PMIC_PDPHY_MSG_TX_IRQ                0x2
> > -#define PMIC_PDPHY_MSG_RX_IRQ                0x3
> > -#define PMIC_PDPHY_MSG_TX_FAIL_IRQ   0x4
> > -#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ        0x5
> > -#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ        0x6
> > -#define PMIC_PDPHY_FR_SWAP_IRQ               0x7
> >
> >   /* Resources */
> >   #define PMIC_PDPHY_MAX_IRQS         0x08
> > @@ -93,27 +25,11 @@ struct pmic_typec_pdphy_resources {
> >   /* API */
> >   struct pmic_typec_pdphy;
> >
> > -struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev);
> > -
> > +extern const struct pmic_typec_pdphy_resources pm8150b_pdphy_res;
> >   int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
> > -                             struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                             struct pmic_typec_pdphy_resources *res,
> > +                             struct pmic_typec *tcpm,
> > +                             const struct pmic_typec_pdphy_resources *res,
> >                               struct regmap *regmap,
> >                               u32 base);
> >
> > -int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                             struct tcpm_port *tcpm_port);
> > -
> > -void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy);
> > -
> > -int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                                 bool power_role_src, bool data_role_host);
> > -
> > -int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on);
> > -
> > -int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
> > -                                   enum tcpm_transmit_type type,
> > -                                   const struct pd_message *msg,
> > -                                   unsigned int negotiated_rev);
> > -
> >   #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
> > diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
> > index d4d358c680b6..4a892048908e 100644
> > --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
> > +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
> > @@ -3,8 +3,8 @@
> >    * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
> >    * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> >    */
> > -#ifndef __QCOM_PMIC_TYPEC_H__
> > -#define __QCOM_PMIC_TYPEC_H__
> > +#ifndef __QCOM_PMIC_TYPEC_PORT_H__
> > +#define __QCOM_PMIC_TYPEC_PORT_H__
> >
> >   #include <linux/platform_device.h>
> >   #include <linux/usb/tcpm.h>
> >
>
> Other than my nit above looks good.
>
> Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>


-- 
With best wishes
Dmitry

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

* Re: [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver
  2024-01-13 14:15     ` Dmitry Baryshkov
@ 2024-01-13 14:48       ` Konrad Dybcio
  0 siblings, 0 replies; 35+ messages in thread
From: Konrad Dybcio @ 2024-01-13 14:48 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
	Bryan O'Donoghue, Greg Kroah-Hartman, Vinod Koul,
	Kishon Vijay Abraham I, Guenter Roeck, Heikki Krogerus,
	Philipp Zabel, Bhupesh Sharma, linux-arm-msm, devicetree,
	linux-usb, linux-phy

On 13.01.2024 15:15, Dmitry Baryshkov wrote:
> On Sat, 13 Jan 2024 at 12:42, Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>>
>> On 13.01.2024 06:42, Dmitry Baryshkov wrote:
>>> In preparation to adding Type-C handling for MSM8998, QCM2290 and SM6115
>>> platforms, create new QMP USB-C PHY driver by splitting mentioned
>>> platforms to a separate file. In future it will also be extended with
>>> support for the DisplayPort handling. It will also be reused later for
>>> such platforms as SDM660, SM6125, SM6150.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>
>> [...]
>>
>>
>>> +#include "phy-qcom-qmp.h"
>>> +#include "phy-qcom-qmp-pcs-misc-v3.h"
>>> +
>>> +/* QPHY_SW_RESET bit */
>>> +#define SW_RESET                             BIT(0)
>>> +/* QPHY_POWER_DOWN_CONTROL */
>>> +#define SW_PWRDN                             BIT(0)
>>
>> Most / all of these defines could probably live in a header file.
> 
> For this (and several other comments), see
> https://lore.kernel.org/linux-arm-msm/20240109-phy-qmp-merge-common-v1-0-572899a14318@linaro.org/

So, I'd assume the plan is to land these two series in parallel and
then submit a cleanup to this one? Sounds ok then!

Konrad


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

* Re: [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling
  2024-01-13  5:42 ` [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling Dmitry Baryshkov
  2024-01-13 10:46   ` Konrad Dybcio
@ 2024-01-17  0:04   ` Jeff Johnson
  1 sibling, 0 replies; 35+ messages in thread
From: Jeff Johnson @ 2024-01-17  0:04 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Wesley Cheng, Bryan O'Donoghue, Greg Kroah-Hartman,
	Vinod Koul, Kishon Vijay Abraham I, Guenter Roeck,
	Heikki Krogerus, Philipp Zabel, Bhupesh Sharma
  Cc: linux-arm-msm, devicetree, linux-usb, linux-phy

On 1/12/2024 9:42 PM, Dmitry Baryshkov wrote:
> Now as all dual-lane PHYs have been migrated to a new driver, drop
> support for dual lanes configuration. If the PHY uses two lanes for USB,
> it is symthom that it should use either a combo USB+DP or a USB-C PHY

if you re-spin: s/symthom/symptom/


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

end of thread, other threads:[~2024-01-17  0:04 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-13  5:42 [PATCH 00/13] usb: typec: qcom-pmic-typec: enable support for PMI632 PMIC Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 01/13] dt-bindings: regulator: qcom,usb-vbus-regulator: add support for PMI632 Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 02/13] dt-bindings: usb: qcom,pmic-typec: add support for the PMI632 block Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 03/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: split from sc8280xp PHY schema Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 04/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: support USB-C data Dmitry Baryshkov
2024-01-13 12:09   ` Bryan O'Donoghue
2024-01-13  5:42 ` [PATCH 05/13] usb: typec: qcom-pmic-typec: allow different implementations for the PD PHY Dmitry Baryshkov
2024-01-13 10:32   ` Konrad Dybcio
2024-01-13 13:43   ` Bryan O'Donoghue
2024-01-13 14:24     ` Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 06/13] usb: typec: qcom-pmic-typec: add support for PMI632 PMIC Dmitry Baryshkov
2024-01-13 10:33   ` Konrad Dybcio
2024-01-13 13:58     ` Bryan O'Donoghue
2024-01-13 13:40   ` Bryan O'Donoghue
2024-01-13  5:42 ` [PATCH 07/13] phy: qcom: qmp-usb: split USB-C PHY driver Dmitry Baryshkov
2024-01-13 10:42   ` Konrad Dybcio
2024-01-13 14:15     ` Dmitry Baryshkov
2024-01-13 14:48       ` Konrad Dybcio
2024-01-13  5:42 ` [PATCH 08/13] phy: qcom: qmp-usb: drop dual-lane handling Dmitry Baryshkov
2024-01-13 10:46   ` Konrad Dybcio
2024-01-17  0:04   ` Jeff Johnson
2024-01-13  5:42 ` [PATCH 09/13] phy: qcom: qmp-usbc: drop single lane handling Dmitry Baryshkov
2024-01-13 10:46   ` Konrad Dybcio
2024-01-13 14:16     ` Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 10/13] phy: qcom: qmp-usbc: add support for the Type-C handling Dmitry Baryshkov
2024-01-13 10:48   ` Konrad Dybcio
2024-01-13 14:17     ` Dmitry Baryshkov
2024-01-13  5:42 ` [PATCH 11/13] arm64: dts: qcom: pmi632: define USB-C related blocks Dmitry Baryshkov
2024-01-13 10:48   ` Konrad Dybcio
2024-01-13 12:18   ` Bryan O'Donoghue
2024-01-13  5:42 ` [PATCH 12/13] arm64: dts: qcom: sm6115: drop pipe clock selection Dmitry Baryshkov
2024-01-13 10:49   ` Konrad Dybcio
2024-01-13  5:42 ` [PATCH 13/13] arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling Dmitry Baryshkov
2024-01-13 10:52   ` Konrad Dybcio
2024-01-13 14:20     ` Dmitry Baryshkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).