Merge tag 'phy-for-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 16 Mar 2024 18:24:51 +0000 (11:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 16 Mar 2024 18:24:51 +0000 (11:24 -0700)
Pull phy updates from Vinod Koul:
 "New hardware support:

   - Qualcomm X1E80100 PCIe phy support, SM8550 PCIe1 PHY, SC7180 UFS
     PHY and SDM630 USBC support

   - Rockchip HDMI/eDP Combo PHY driver

   - Mediatek MT8365 CSI phy driver

  Updates:

   - Rework on Qualcomm phy PCS registers and type-c handling

   - Cadence torrent phy updates for multilink configuration

   - TI gmii resume support"

* tag 'phy-for-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (41 commits)
  phy: constify of_phandle_args in xlate
  phy: ti: tusb1210: Define device IDs
  phy: ti: tusb1210: Use temporary variable for struct device
  phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver
  dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY schema
  phy: ti: gmii-sel: add resume support
  phy: mtk-mipi-csi: add driver for CSI phy
  dt-bindings: phy: add mediatek MIPI CD-PHY module v0.5
  phy: cadence-torrent: Add USXGMII(156.25MHz) + SGMII/QSGMII(100MHz) multilink config for TI J7200
  dt-bindings: phy: cadence-torrent: Add a separate compatible for TI J7200
  phy: cadence-torrent: Add USXGMII(156.25MHz) + SGMII/QSGMII(100MHz) multilink configuration
  phy: cadence-torrent: Add PCIe(100MHz) + USXGMII(156.25MHz) multilink configuration
  dt-bindings: phy: cadence-torrent: Add optional input reference clock for PLL1
  phy: qcom-qmp-ufs: Switch to devm_clk_bulk_get_all() API
  dt-bindings: phy: qmp-ufs: Fix PHY clocks
  phy: qcom: sgmii-eth: move PCS registers to separate header
  phy: qcom: sgmii-eth: use existing register definitions
  phy: qcom: qmp-usbc: drop has_pwrdn_delay handling
  phy: qcom: qmp: move common bits definitions to common header
  phy: qcom: qmp: split DP PHY registers to separate headers
  ...

87 files changed:
Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml [new file with mode: 0644]
MAINTAINERS
drivers/phy/allwinner/phy-sun4i-usb.c
drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
drivers/phy/broadcom/phy-bcm-sr-pcie.c
drivers/phy/broadcom/phy-bcm-sr-usb.c
drivers/phy/broadcom/phy-bcm63xx-usbh.c
drivers/phy/broadcom/phy-brcm-usb.c
drivers/phy/cadence/phy-cadence-torrent.c
drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
drivers/phy/freescale/phy-fsl-lynx-28g.c
drivers/phy/hisilicon/phy-histb-combphy.c
drivers/phy/intel/phy-intel-lgm-combo.c
drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
drivers/phy/marvell/phy-armada375-usb2.c
drivers/phy/marvell/phy-armada38x-comphy.c
drivers/phy/marvell/phy-berlin-sata.c
drivers/phy/marvell/phy-mvebu-a3700-comphy.c
drivers/phy/marvell/phy-mvebu-cp110-comphy.c
drivers/phy/mediatek/Kconfig
drivers/phy/mediatek/Makefile
drivers/phy/mediatek/phy-mtk-mipi-csi-0-5-rx-reg.h [new file with mode: 0644]
drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c [new file with mode: 0644]
drivers/phy/mediatek/phy-mtk-tphy.c
drivers/phy/mediatek/phy-mtk-xsphy.c
drivers/phy/microchip/lan966x_serdes.c
drivers/phy/microchip/sparx5_serdes.c
drivers/phy/mscc/phy-ocelot-serdes.c
drivers/phy/phy-core.c
drivers/phy/phy-xgene.c
drivers/phy/qualcomm/Makefile
drivers/phy/qualcomm/phy-qcom-edp.c
drivers/phy/qualcomm/phy-qcom-qmp-combo.c
drivers/phy/qualcomm/phy-qcom-qmp-common.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-dp-com-v3.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v3.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v4.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h
drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
drivers/phy/qualcomm/phy-qcom-qmp-usb.c
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c [new file with mode: 0644]
drivers/phy/qualcomm/phy-qcom-qmp.h
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
drivers/phy/ralink/phy-mt7621-pci.c
drivers/phy/renesas/phy-rcar-gen2.c
drivers/phy/renesas/phy-rcar-gen3-usb2.c
drivers/phy/renesas/r8a779f0-ether-serdes.c
drivers/phy/rockchip/Kconfig
drivers/phy/rockchip/Makefile
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
drivers/phy/rockchip/phy-rockchip-pcie.c
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c [new file with mode: 0644]
drivers/phy/samsung/phy-exynos-mipi-video.c
drivers/phy/samsung/phy-exynos5-usbdrd.c
drivers/phy/samsung/phy-samsung-usb2.c
drivers/phy/socionext/phy-uniphier-usb2.c
drivers/phy/st/phy-miphy28lp.c
drivers/phy/st/phy-spear1310-miphy.c
drivers/phy/st/phy-spear1340-miphy.c
drivers/phy/st/phy-stm32-usbphyc.c
drivers/phy/tegra/xusb.c
drivers/phy/ti/phy-am654-serdes.c
drivers/phy/ti/phy-da8xx-usb.c
drivers/phy/ti/phy-gmii-sel.c
drivers/phy/ti/phy-tusb1210.c
drivers/phy/xilinx/phy-zynqmp.c
drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
include/linux/phy/phy.h

diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml
new file mode 100644 (file)
index 0000000..2127a57
--- /dev/null
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2023 MediaTek, BayLibre
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,mt8365-csi-rx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Sensor Interface MIPI CSI CD-PHY
+
+maintainers:
+  - Julien Stephan <jstephan@baylibre.com>
+  - Andy Hsieh <andy.hsieh@mediatek.com>
+
+description:
+  The SENINF CD-PHY is a set of CD-PHY connected to the SENINF CSI-2
+  receivers. The number of PHYs depends on the SoC model.
+  Depending on the SoC model, each PHYs can be either CD-PHY or D-PHY only
+  capable.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8365-csi-rx
+
+  reg:
+    maxItems: 1
+
+  num-lanes:
+    enum: [2, 3, 4]
+
+  '#phy-cells':
+    enum: [0, 1]
+    description: |
+      If the PHY doesn't support mode selection then #phy-cells must be 0 and
+      PHY mode is described using phy-type property.
+      If the PHY supports mode selection, then #phy-cells must be 1 and mode
+      is set in the PHY cells. Supported modes are:
+        - PHY_TYPE_DPHY
+        - PHY_TYPE_CPHY
+      See include/dt-bindings/phy/phy.h for constants.
+
+  phy-type:
+    description:
+      If the PHY doesn't support mode selection then this set the operating mode.
+      See include/dt-bindings/phy/phy.h for constants.
+    const: 10
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+required:
+  - compatible
+  - reg
+  - num-lanes
+  - '#phy-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/phy/phy.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      csi0_rx: phy@11c10000 {
+        compatible = "mediatek,mt8365-csi-rx";
+        reg = <0 0x11c10000 0 0x2000>;
+        num-lanes = <2>;
+        #phy-cells = <1>;
+      };
+
+      csi1_rx: phy@11c12000 {
+        compatible = "mediatek,mt8365-csi-rx";
+        reg = <0 0x11c12000 0 0x2000>;
+        phy-type = <PHY_TYPE_DPHY>;
+        num-lanes = <2>;
+        #phy-cells = <0>;
+      };
+    };
+...
index dfb31314face761bd300a12c0066901fdbca6035..15dc8efe6ffe74f0fdb258db54481cc4d75d5091 100644 (file)
@@ -20,6 +20,7 @@ properties:
   compatible:
     enum:
       - cdns,torrent-phy
+      - ti,j7200-serdes-10g
       - ti,j721e-serdes-10g
 
   '#address-cells':
@@ -35,14 +36,18 @@ properties:
     minItems: 1
     maxItems: 2
     description:
-      PHY reference clock for 1 item. Must contain an entry in clock-names.
-      Optional Parent to enable output reference clock.
+      PHY input reference clocks - refclk (for PLL0) & pll1_refclk (for PLL1).
+      pll1_refclk is optional and used for multi-protocol configurations requiring
+      separate reference clock for each protocol.
+      Same refclk is used for both PLL0 and PLL1 if no separate pll1_refclk is used.
+      Optional parent clock (phy_en_refclk) to enable a reference clock output feature
+      on some platforms to output either derived or received reference clock.
 
   clock-names:
     minItems: 1
     items:
       - const: refclk
-      - const: phy_en_refclk
+      - enum: [ pll1_refclk, phy_en_refclk ]
 
   reg:
     minItems: 1
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 (file)
index 0000000..f1f4e4f
--- /dev/null
@@ -0,0 +1,184 @@
+# 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,sdm660-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
+
+  orientation-switch:
+    description:
+      Flag the PHY as possible handler of USB Type-C orientation switching
+    type: boolean
+
+  qcom,tcsr-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to TCSR hardware block
+          - description: offset of the VLS CLAMP register
+    description: Clamp register present in the TCSR
+
+  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
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+  - "#clock-cells"
+  - clock-output-names
+  - "#phy-cells"
+  - qcom,tcsr-reg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,msm8998-qmp-usb3-phy
+              - qcom,sdm660-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>;
+
+      orientation-switch;
+
+      qcom,tcsr-reg = <&tcsr_regs_1 0x6b244>;
+
+      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>;
+          };
+        };
+      };
+    };
index 6c03f2d5fca3cca6ad0cccc4ae3f8679e4c59026..ba966a78a1283f5249a7c015c45d605845b85e41 100644 (file)
@@ -38,6 +38,8 @@ properties:
       - qcom,sm8550-qmp-gen4x2-pcie-phy
       - qcom,sm8650-qmp-gen3x2-pcie-phy
       - qcom,sm8650-qmp-gen4x2-pcie-phy
+      - qcom,x1e80100-qmp-gen3x2-pcie-phy
+      - qcom,x1e80100-qmp-gen4x2-pcie-phy
 
   reg:
     minItems: 1
@@ -151,6 +153,8 @@ allOf:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen3x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
+              - qcom,x1e80100-qmp-gen3x2-pcie-phy
+              - qcom,x1e80100-qmp-gen4x2-pcie-phy
     then:
       properties:
         clocks:
@@ -194,6 +198,8 @@ allOf:
             enum:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
+              - qcom,x1e80100-qmp-gen3x2-pcie-phy
+              - qcom,x1e80100-qmp-gen4x2-pcie-phy
     then:
       properties:
         resets:
index 8474eef8d0ff5233a075bf5c17ca0abaa14fbd41..91a6cc38ff7ff5d8df2fd33997b540e4338e9ab2 100644 (file)
@@ -19,6 +19,7 @@ properties:
       - qcom,msm8996-qmp-ufs-phy
       - qcom,msm8998-qmp-ufs-phy
       - qcom,sa8775p-qmp-ufs-phy
+      - qcom,sc7180-qmp-ufs-phy
       - qcom,sc7280-qmp-ufs-phy
       - qcom,sc8180x-qmp-ufs-phy
       - qcom,sc8280xp-qmp-ufs-phy
@@ -38,15 +39,12 @@ properties:
     maxItems: 1
 
   clocks:
-    minItems: 1
+    minItems: 2
     maxItems: 3
 
   clock-names:
-    minItems: 1
-    items:
-      - const: ref
-      - const: ref_aux
-      - const: qref
+    minItems: 2
+    maxItems: 3
 
   power-domains:
     maxItems: 1
@@ -86,22 +84,9 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,msm8998-qmp-ufs-phy
               - qcom,sa8775p-qmp-ufs-phy
               - qcom,sc7280-qmp-ufs-phy
-              - qcom,sm8450-qmp-ufs-phy
-    then:
-      properties:
-        clocks:
-          minItems: 3
-        clock-names:
-          minItems: 3
-
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - qcom,msm8998-qmp-ufs-phy
               - qcom,sc8180x-qmp-ufs-phy
               - qcom,sc8280xp-qmp-ufs-phy
               - qcom,sdm845-qmp-ufs-phy
@@ -112,14 +97,19 @@ allOf:
               - qcom,sm8150-qmp-ufs-phy
               - qcom,sm8250-qmp-ufs-phy
               - qcom,sm8350-qmp-ufs-phy
+              - qcom,sm8450-qmp-ufs-phy
               - qcom,sm8550-qmp-ufs-phy
               - qcom,sm8650-qmp-ufs-phy
     then:
       properties:
         clocks:
-          maxItems: 2
+          minItems: 3
+          maxItems: 3
         clock-names:
-          maxItems: 2
+          items:
+            - const: ref
+            - const: ref_aux
+            - const: qref
 
   - if:
       properties:
@@ -130,22 +120,28 @@ allOf:
     then:
       properties:
         clocks:
-          maxItems: 1
+          minItems: 2
+          maxItems: 2
         clock-names:
-          maxItems: 1
+          items:
+            - const: ref
+            - const: qref
 
 additionalProperties: false
 
 examples:
   - |
     #include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
 
     ufs_mem_phy: phy@1d87000 {
         compatible = "qcom,sc8280xp-qmp-ufs-phy";
         reg = <0x01d87000 0x1000>;
 
-        clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
-        clock-names = "ref", "ref_aux";
+        clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+                 <&gcc GCC_UFS_REF_CLKREF_CLK>;
+
+        clock-names = "ref", "ref_aux", "qref";
 
         power-domains = <&gcc UFS_PHY_GDSC>;
 
index 15d82c67f157b6ceadc366540fca0c200201d920..1e2d4ddc5391f10e2d1c983a4058bbe6225d4f42 100644 (file)
@@ -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:
diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
new file mode 100644 (file)
index 0000000..54e822c
--- /dev/null
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/rockchip,rk3588-hdptx-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC HDMI/eDP Transmitter Combo PHY
+
+maintainers:
+  - Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3588-hdptx-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Reference clock
+      - description: APB clock
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+  resets:
+    items:
+      - description: PHY reset line
+      - description: APB reset line
+      - description: INIT reset line
+      - description: CMN reset line
+      - description: LANE reset line
+      - description: ROPLL reset line
+      - description: LCPLL reset line
+
+  reset-names:
+    items:
+      - const: phy
+      - const: apb
+      - const: init
+      - const: cmn
+      - const: lane
+      - const: ropll
+      - const: lcpll
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Some PHY related data is accessed through GRF regs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - resets
+  - reset-names
+  - rockchip,grf
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy@fed60000 {
+        compatible = "rockchip,rk3588-hdptx-phy";
+        reg = <0x0 0xfed60000 0x0 0x2000>;
+        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+        clock-names = "ref", "apb";
+        #phy-cells = <0>;
+        resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+                 <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+                 <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+                 <&cru SRST_HDPTX0_LCPLL>;
+        reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", "lcpll";
+        rockchip,grf = <&hdptxphy_grf>;
+      };
+    };
index be59443034d0eed30a67564692883c80a84314c2..d4300cab7062440dfbccd6b6a0b4e7c65d39236e 100644 (file)
@@ -13800,6 +13800,13 @@ F:     Documentation/devicetree/bindings/media/mediatek-vpu.txt
 F:     drivers/media/platform/mediatek/vcodec/
 F:     drivers/media/platform/mediatek/vpu/
 
+MEDIATEK MIPI-CSI CDPHY DRIVER
+M:     Julien Stephan <jstephan@baylibre.com>
+M:     Andy Hsieh <andy.hsieh@mediatek.com>
+S:     Supported
+F:     Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml
+F:     drivers/phy/mediatek/phy-mtk-mipi-csi-0-5*
+
 MEDIATEK MMC/SD/SDIO DRIVER
 M:     Chaotian Jing <chaotian.jing@mediatek.com>
 S:     Maintained
index e53a9a9317bc2592475c9e5e2085dd28a4858e44..b0f19e95060107431810197bddfd16f292526129 100644 (file)
@@ -683,7 +683,7 @@ static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb,
 }
 
 static struct phy *sun4i_usb_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
 
index 2712c4bd549d87a4607f7f7907ae65d74e2a159d..5468831d6ab9bb5b8ff057d6f8c6061616ff626d 100644 (file)
@@ -350,7 +350,7 @@ static int phy_g12a_usb3_pcie_exit(struct phy *phy)
 }
 
 static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev,
-                                           struct of_phandle_args *args)
+                                           const struct of_phandle_args *args)
 {
        struct phy_g12a_usb3_pcie_priv *priv = dev_get_drvdata(dev);
        unsigned int mode;
index 8a4aadf166cf9e778af011f235b971d625877215..ff9b3862bf7af42473cf80f739123e54d114787d 100644 (file)
@@ -195,7 +195,7 @@ static const struct phy_ops sr_paxc_phy_ops = {
 };
 
 static struct phy *sr_pcie_phy_xlate(struct device *dev,
-                                    struct of_phandle_args *args)
+                                    const struct of_phandle_args *args)
 {
        struct sr_pcie_phy_core *core;
        int phy_idx;
index b0bd18a5df8794fcc192a5b927ebfa3065c5fa6e..6bcfe83609c865d3c54c87252c8ef622d78b304e 100644 (file)
@@ -209,7 +209,7 @@ static const struct phy_ops sr_phy_ops = {
 };
 
 static struct phy *bcm_usb_phy_xlate(struct device *dev,
-                                    struct of_phandle_args *args)
+                                    const struct of_phandle_args *args)
 {
        struct bcm_usb_phy_cfg *phy_cfg;
        int phy_idx;
index f8183dea774b697a2cfab9fb6f04926029f0c353..647644de041bba86ded64484b751bf781345ac43 100644 (file)
@@ -366,7 +366,7 @@ static const struct phy_ops bcm63xx_usbh_phy_ops = {
 };
 
 static struct phy *bcm63xx_usbh_phy_xlate(struct device *dev,
-                                         struct of_phandle_args *args)
+                                         const struct of_phandle_args *args)
 {
        struct bcm63xx_usbh_phy *usbh = dev_get_drvdata(dev);
 
index a16f0b58eb74538e9bd7a31fe0a1723563f3abeb..ad2eec0956016d96bfe61729545901909d8c593a 100644 (file)
@@ -175,7 +175,7 @@ static const struct phy_ops brcm_usb_phy_ops = {
 };
 
 static struct phy *brcm_usb_phy_xlate(struct device *dev,
-                                     struct of_phandle_args *args)
+                                     const struct of_phandle_args *args)
 {
        struct brcm_usb_phy_data *data = dev_get_drvdata(dev);
 
index a75c96385c57acd9400b67d70f657d4fea1942e7..95924a09960cce0bd0fdeb88639940d584226aad 100644 (file)
@@ -355,7 +355,9 @@ struct cdns_torrent_phy {
        struct reset_control *apb_rst;
        struct device *dev;
        struct clk *clk;
+       struct clk *clk1;
        enum cdns_torrent_ref_clk ref_clk_rate;
+       enum cdns_torrent_ref_clk ref_clk1_rate;
        struct cdns_torrent_inst phys[MAX_NUM_LANES];
        int nsubnodes;
        const struct cdns_torrent_data *init_data;
@@ -2460,9 +2462,11 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
 {
        const struct cdns_torrent_data *init_data = cdns_phy->init_data;
        struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
+       enum cdns_torrent_ref_clk ref_clk1 = cdns_phy->ref_clk1_rate;
        enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate;
        struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
        enum cdns_torrent_phy_type phy_t1, phy_t2;
+       struct cdns_torrent_vals *phy_pma_cmn_vals;
        struct cdns_torrent_vals *pcs_cmn_vals;
        int i, j, node, mlane, num_lanes, ret;
        struct cdns_reg_pairs *reg_pairs;
@@ -2489,6 +2493,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
                         * Get the array values as [phy_t2][phy_t1][ssc].
                         */
                        swap(phy_t1, phy_t2);
+                       swap(ref_clk, ref_clk1);
                }
 
                mlane = cdns_phy->phys[node].mlane;
@@ -2552,9 +2557,22 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
                                             reg_pairs[i].val);
                }
 
+               /* PHY PMA common registers configurations */
+               phy_pma_cmn_vals = cdns_torrent_get_tbl_vals(&init_data->phy_pma_cmn_vals_tbl,
+                                                            CLK_ANY, CLK_ANY,
+                                                            phy_t1, phy_t2, ANY_SSC);
+               if (phy_pma_cmn_vals) {
+                       reg_pairs = phy_pma_cmn_vals->reg_pairs;
+                       num_regs = phy_pma_cmn_vals->num_regs;
+                       regmap = cdns_phy->regmap_phy_pma_common_cdb;
+                       for (i = 0; i < num_regs; i++)
+                               regmap_write(regmap, reg_pairs[i].off,
+                                            reg_pairs[i].val);
+               }
+
                /* PMA common registers configurations */
                cmn_vals = cdns_torrent_get_tbl_vals(&init_data->cmn_vals_tbl,
-                                                    ref_clk, ref_clk,
+                                                    ref_clk, ref_clk1,
                                                     phy_t1, phy_t2, ssc);
                if (cmn_vals) {
                        reg_pairs = cmn_vals->reg_pairs;
@@ -2567,7 +2585,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
 
                /* PMA TX lane registers configurations */
                tx_ln_vals = cdns_torrent_get_tbl_vals(&init_data->tx_ln_vals_tbl,
-                                                      ref_clk, ref_clk,
+                                                      ref_clk, ref_clk1,
                                                       phy_t1, phy_t2, ssc);
                if (tx_ln_vals) {
                        reg_pairs = tx_ln_vals->reg_pairs;
@@ -2582,7 +2600,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
 
                /* PMA RX lane registers configurations */
                rx_ln_vals = cdns_torrent_get_tbl_vals(&init_data->rx_ln_vals_tbl,
-                                                      ref_clk, ref_clk,
+                                                      ref_clk, ref_clk1,
                                                       phy_t1, phy_t2, ssc);
                if (rx_ln_vals) {
                        reg_pairs = rx_ln_vals->reg_pairs;
@@ -2684,9 +2702,11 @@ static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)
 static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
 {
        struct device *dev = cdns_phy->dev;
+       unsigned long ref_clk1_rate;
        unsigned long ref_clk_rate;
        int ret;
 
+       /* refclk: Input reference clock for PLL0 */
        cdns_phy->clk = devm_clk_get(dev, "refclk");
        if (IS_ERR(cdns_phy->clk)) {
                dev_err(dev, "phy ref clock not found\n");
@@ -2695,15 +2715,15 @@ static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
 
        ret = clk_prepare_enable(cdns_phy->clk);
        if (ret) {
-               dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+               dev_err(cdns_phy->dev, "Failed to prepare ref clock: %d\n", ret);
                return ret;
        }
 
        ref_clk_rate = clk_get_rate(cdns_phy->clk);
        if (!ref_clk_rate) {
                dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
-               clk_disable_unprepare(cdns_phy->clk);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto disable_clk;
        }
 
        switch (ref_clk_rate) {
@@ -2720,12 +2740,62 @@ static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
                cdns_phy->ref_clk_rate = CLK_156_25_MHZ;
                break;
        default:
-               dev_err(cdns_phy->dev, "Invalid Ref Clock Rate\n");
-               clk_disable_unprepare(cdns_phy->clk);
-               return -EINVAL;
+               dev_err(cdns_phy->dev, "Invalid ref clock rate\n");
+               ret = -EINVAL;
+               goto disable_clk;
+       }
+
+       /* refclk1: Input reference clock for PLL1 */
+       cdns_phy->clk1 = devm_clk_get_optional(dev, "pll1_refclk");
+       if (IS_ERR(cdns_phy->clk1)) {
+               dev_err(dev, "phy PLL1 ref clock not found\n");
+               ret = PTR_ERR(cdns_phy->clk1);
+               goto disable_clk;
+       }
+
+       if (cdns_phy->clk1) {
+               ret = clk_prepare_enable(cdns_phy->clk1);
+               if (ret) {
+                       dev_err(cdns_phy->dev, "Failed to prepare PLL1 ref clock: %d\n", ret);
+                       goto disable_clk;
+               }
+
+               ref_clk1_rate = clk_get_rate(cdns_phy->clk1);
+               if (!ref_clk1_rate) {
+                       dev_err(cdns_phy->dev, "Failed to get PLL1 ref clock rate\n");
+                       ret = -EINVAL;
+                       goto disable_clk1;
+               }
+
+               switch (ref_clk1_rate) {
+               case REF_CLK_19_2MHZ:
+                       cdns_phy->ref_clk1_rate = CLK_19_2_MHZ;
+                       break;
+               case REF_CLK_25MHZ:
+                       cdns_phy->ref_clk1_rate = CLK_25_MHZ;
+                       break;
+               case REF_CLK_100MHZ:
+                       cdns_phy->ref_clk1_rate = CLK_100_MHZ;
+                       break;
+               case REF_CLK_156_25MHZ:
+                       cdns_phy->ref_clk1_rate = CLK_156_25_MHZ;
+                       break;
+               default:
+                       dev_err(cdns_phy->dev, "Invalid PLL1 ref clock rate\n");
+                       ret = -EINVAL;
+                       goto disable_clk1;
+               }
+       } else {
+               cdns_phy->ref_clk1_rate = cdns_phy->ref_clk_rate;
        }
 
        return 0;
+
+disable_clk1:
+       clk_disable_unprepare(cdns_phy->clk1);
+disable_clk:
+       clk_disable_unprepare(cdns_phy->clk);
+       return ret;
 }
 
 static int cdns_torrent_phy_probe(struct platform_device *pdev)
@@ -2980,6 +3050,7 @@ put_lnk_rst:
                reset_control_put(cdns_phy->phys[i].lnk_rst);
        of_node_put(child);
        reset_control_assert(cdns_phy->apb_rst);
+       clk_disable_unprepare(cdns_phy->clk1);
        clk_disable_unprepare(cdns_phy->clk);
 clk_cleanup:
        cdns_torrent_clk_cleanup(cdns_phy);
@@ -2998,6 +3069,7 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)
                reset_control_put(cdns_phy->phys[i].lnk_rst);
        }
 
+       clk_disable_unprepare(cdns_phy->clk1);
        clk_disable_unprepare(cdns_phy->clk);
        cdns_torrent_clk_cleanup(cdns_phy);
 }
@@ -3034,6 +3106,216 @@ static struct cdns_torrent_vals dp_usb_xcvr_diag_ln_vals = {
        .num_regs = ARRAY_SIZE(dp_usb_xcvr_diag_ln_regs),
 };
 
+/* USXGMII and SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs usxgmii_sgmii_link_cmn_regs[] = {
+       {0x0002, PHY_PLL_CFG},
+       {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M0},
+       {0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs usxgmii_sgmii_xcvr_diag_ln_regs[] = {
+       {0x0000, XCVR_DIAG_HSCLK_SEL},
+       {0x0001, XCVR_DIAG_HSCLK_DIV},
+       {0x0001, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs sgmii_usxgmii_xcvr_diag_ln_regs[] = {
+       {0x0111, XCVR_DIAG_HSCLK_SEL},
+       {0x0103, XCVR_DIAG_HSCLK_DIV},
+       {0x0A9B, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals usxgmii_sgmii_link_cmn_vals = {
+       .reg_pairs = usxgmii_sgmii_link_cmn_regs,
+       .num_regs = ARRAY_SIZE(usxgmii_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals usxgmii_sgmii_xcvr_diag_ln_vals = {
+       .reg_pairs = usxgmii_sgmii_xcvr_diag_ln_regs,
+       .num_regs = ARRAY_SIZE(usxgmii_sgmii_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals sgmii_usxgmii_xcvr_diag_ln_vals = {
+       .reg_pairs = sgmii_usxgmii_xcvr_diag_ln_regs,
+       .num_regs = ARRAY_SIZE(sgmii_usxgmii_xcvr_diag_ln_regs),
+};
+
+/* Multilink USXGMII, using PLL0, 156.25 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs ml_usxgmii_pll0_156_25_no_ssc_cmn_regs[] = {
+       {0x0014, CMN_PLL0_DSM_FBH_OVRD_M0},
+       {0x0005, CMN_PLL0_DSM_FBL_OVRD_M0},
+       {0x061B, CMN_PLL0_VCOCAL_INIT_TMR},
+       {0x0019, CMN_PLL0_VCOCAL_ITER_TMR},
+       {0x1354, CMN_PLL0_VCOCAL_REFTIM_START},
+       {0x1354, CMN_PLL0_VCOCAL_PLLCNT_START},
+       {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+       {0x0138, CMN_PLL0_LOCK_REFCNT_START},
+       {0x0138, CMN_PLL0_LOCK_PLLCNT_START}
+};
+
+static struct cdns_torrent_vals ml_usxgmii_pll0_156_25_no_ssc_cmn_vals = {
+       .reg_pairs = ml_usxgmii_pll0_156_25_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(ml_usxgmii_pll0_156_25_no_ssc_cmn_regs),
+};
+
+/* Multilink SGMII/QSGMII, using PLL1, 100 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs ml_sgmii_pll1_100_no_ssc_cmn_regs[] = {
+       {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+       {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+       {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
+       {0x0003, CMN_PLL1_VCOCAL_TCTRL},
+       {0x007F, CMN_TXPUCAL_TUNE},
+       {0x007F, CMN_TXPDCAL_TUNE}
+};
+
+static struct cdns_torrent_vals ml_sgmii_pll1_100_no_ssc_cmn_vals = {
+       .reg_pairs = ml_sgmii_pll1_100_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(ml_sgmii_pll1_100_no_ssc_cmn_regs),
+};
+
+/* TI J7200, Multilink USXGMII, using PLL0, 156.25 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_regs[] = {
+       {0x0014, CMN_SSM_BIAS_TMR},
+       {0x0028, CMN_PLLSM0_PLLPRE_TMR},
+       {0x00A4, CMN_PLLSM0_PLLLOCK_TMR},
+       {0x0062, CMN_BGCAL_INIT_TMR},
+       {0x0062, CMN_BGCAL_ITER_TMR},
+       {0x0014, CMN_IBCAL_INIT_TMR},
+       {0x0018, CMN_TXPUCAL_INIT_TMR},
+       {0x0005, CMN_TXPUCAL_ITER_TMR},
+       {0x0018, CMN_TXPDCAL_INIT_TMR},
+       {0x0005, CMN_TXPDCAL_ITER_TMR},
+       {0x024A, CMN_RXCAL_INIT_TMR},
+       {0x0005, CMN_RXCAL_ITER_TMR},
+       {0x000B, CMN_SD_CAL_REFTIM_START},
+       {0x0132, CMN_SD_CAL_PLLCNT_START},
+       {0x0014, CMN_PLL0_DSM_FBH_OVRD_M0},
+       {0x0005, CMN_PLL0_DSM_FBL_OVRD_M0},
+       {0x061B, CMN_PLL0_VCOCAL_INIT_TMR},
+       {0x0019, CMN_PLL0_VCOCAL_ITER_TMR},
+       {0x1354, CMN_PLL0_VCOCAL_REFTIM_START},
+       {0x1354, CMN_PLL0_VCOCAL_PLLCNT_START},
+       {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+       {0x0138, CMN_PLL0_LOCK_REFCNT_START},
+       {0x0138, CMN_PLL0_LOCK_PLLCNT_START}
+};
+
+static struct cdns_torrent_vals j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_vals = {
+       .reg_pairs = j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_regs),
+};
+
+/* TI J7200, Multilink SGMII/QSGMII, using PLL1, 100 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs j7200_ml_sgmii_pll1_100_no_ssc_cmn_regs[] = {
+       {0x0028, CMN_PLLSM1_PLLPRE_TMR},
+       {0x00A4, CMN_PLLSM1_PLLLOCK_TMR},
+       {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+       {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+       {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
+       {0x0003, CMN_PLL1_VCOCAL_TCTRL},
+       {0x007F, CMN_TXPUCAL_TUNE},
+       {0x007F, CMN_TXPDCAL_TUNE}
+};
+
+static struct cdns_torrent_vals j7200_ml_sgmii_pll1_100_no_ssc_cmn_vals = {
+       .reg_pairs = j7200_ml_sgmii_pll1_100_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(j7200_ml_sgmii_pll1_100_no_ssc_cmn_regs),
+};
+
+/* PCIe and USXGMII link configuration */
+static struct cdns_reg_pairs pcie_usxgmii_link_cmn_regs[] = {
+       {0x0003, PHY_PLL_CFG},
+       {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
+       {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
+       {0x0400, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs pcie_usxgmii_xcvr_diag_ln_regs[] = {
+       {0x0000, XCVR_DIAG_HSCLK_SEL},
+       {0x0001, XCVR_DIAG_HSCLK_DIV},
+       {0x0012, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs usxgmii_pcie_xcvr_diag_ln_regs[] = {
+       {0x0011, XCVR_DIAG_HSCLK_SEL},
+       {0x0001, XCVR_DIAG_HSCLK_DIV},
+       {0x0089, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals pcie_usxgmii_link_cmn_vals = {
+       .reg_pairs = pcie_usxgmii_link_cmn_regs,
+       .num_regs = ARRAY_SIZE(pcie_usxgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals pcie_usxgmii_xcvr_diag_ln_vals = {
+       .reg_pairs = pcie_usxgmii_xcvr_diag_ln_regs,
+       .num_regs = ARRAY_SIZE(pcie_usxgmii_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals usxgmii_pcie_xcvr_diag_ln_vals = {
+       .reg_pairs = usxgmii_pcie_xcvr_diag_ln_regs,
+       .num_regs = ARRAY_SIZE(usxgmii_pcie_xcvr_diag_ln_regs),
+};
+
+/*
+ * Multilink USXGMII, using PLL1, 156.25 MHz Ref clk, no SSC
+ */
+static struct cdns_reg_pairs ml_usxgmii_pll1_156_25_no_ssc_cmn_regs[] = {
+       {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+       {0x0014, CMN_PLL1_DSM_FBH_OVRD_M0},
+       {0x0005, CMN_PLL1_DSM_FBL_OVRD_M0},
+       {0x061B, CMN_PLL1_VCOCAL_INIT_TMR},
+       {0x0019, CMN_PLL1_VCOCAL_ITER_TMR},
+       {0x1354, CMN_PLL1_VCOCAL_REFTIM_START},
+       {0x1354, CMN_PLL1_VCOCAL_PLLCNT_START},
+       {0x0003, CMN_PLL1_VCOCAL_TCTRL},
+       {0x0138, CMN_PLL1_LOCK_REFCNT_START},
+       {0x0138, CMN_PLL1_LOCK_PLLCNT_START},
+       {0x007F, CMN_TXPUCAL_TUNE},
+       {0x007F, CMN_TXPDCAL_TUNE}
+};
+
+static struct cdns_reg_pairs ml_usxgmii_156_25_no_ssc_tx_ln_regs[] = {
+       {0x00F3, TX_PSC_A0},
+       {0x04A2, TX_PSC_A2},
+       {0x04A2, TX_PSC_A3 },
+       {0x0000, TX_TXCC_CPOST_MULT_00},
+       {0x0000, XCVR_DIAG_PSC_OVRD}
+};
+
+static struct cdns_reg_pairs ml_usxgmii_156_25_no_ssc_rx_ln_regs[] = {
+       {0x091D, RX_PSC_A0},
+       {0x0900, RX_PSC_A2},
+       {0x0100, RX_PSC_A3},
+       {0x0030, RX_REE_SMGM_CTRL1},
+       {0x03C7, RX_REE_GCSM1_EQENM_PH1},
+       {0x01C7, RX_REE_GCSM1_EQENM_PH2},
+       {0x0000, RX_DIAG_DFE_CTRL},
+       {0x0019, RX_REE_TAP1_CLIP},
+       {0x0019, RX_REE_TAP2TON_CLIP},
+       {0x00B9, RX_DIAG_NQST_CTRL},
+       {0x0C21, RX_DIAG_DFE_AMP_TUNE_2},
+       {0x0002, RX_DIAG_DFE_AMP_TUNE_3},
+       {0x0033, RX_DIAG_PI_RATE},
+       {0x0001, RX_DIAG_ACYA},
+       {0x018C, RX_CDRLF_CNFG}
+};
+
+static struct cdns_torrent_vals ml_usxgmii_pll1_156_25_no_ssc_cmn_vals = {
+       .reg_pairs = ml_usxgmii_pll1_156_25_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(ml_usxgmii_pll1_156_25_no_ssc_cmn_regs),
+};
+
+static struct cdns_torrent_vals ml_usxgmii_156_25_no_ssc_tx_ln_vals = {
+       .reg_pairs = ml_usxgmii_156_25_no_ssc_tx_ln_regs,
+       .num_regs = ARRAY_SIZE(ml_usxgmii_156_25_no_ssc_tx_ln_regs),
+};
+
+static struct cdns_torrent_vals ml_usxgmii_156_25_no_ssc_rx_ln_vals = {
+       .reg_pairs = ml_usxgmii_156_25_no_ssc_rx_ln_regs,
+       .num_regs = ARRAY_SIZE(ml_usxgmii_156_25_no_ssc_rx_ln_regs),
+};
+
 /* TI USXGMII configuration: Enable cmn_refclk_rcv_out_en */
 static struct cdns_reg_pairs ti_usxgmii_phy_pma_cmn_regs[] = {
        {0x0040, PHY_PMA_CMN_CTRL1},
@@ -3811,6 +4093,50 @@ static struct cdns_torrent_vals sgmii_100_no_ssc_rx_ln_vals = {
        .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_rx_ln_regs),
 };
 
+/* TI J7200, multilink SGMII */
+static struct cdns_reg_pairs j7200_sgmii_100_no_ssc_tx_ln_regs[] = {
+       {0x07A2, TX_RCVDET_ST_TMR},
+       {0x00F3, TX_PSC_A0},
+       {0x04A2, TX_PSC_A2},
+       {0x04A2, TX_PSC_A3 },
+       {0x0000, TX_TXCC_CPOST_MULT_00},
+       {0x00B3, DRV_DIAG_TX_DRV},
+       {0x0002, XCVR_DIAG_PSC_OVRD},
+       {0x4000, XCVR_DIAG_RXCLK_CTRL}
+};
+
+static struct cdns_torrent_vals j7200_sgmii_100_no_ssc_tx_ln_vals = {
+       .reg_pairs = j7200_sgmii_100_no_ssc_tx_ln_regs,
+       .num_regs = ARRAY_SIZE(j7200_sgmii_100_no_ssc_tx_ln_regs),
+};
+
+static struct cdns_reg_pairs j7200_sgmii_100_no_ssc_rx_ln_regs[] = {
+       {0x0014, RX_SDCAL0_INIT_TMR},
+       {0x0062, RX_SDCAL0_ITER_TMR},
+       {0x0014, RX_SDCAL1_INIT_TMR},
+       {0x0062, RX_SDCAL1_ITER_TMR},
+       {0x091D, RX_PSC_A0},
+       {0x0900, RX_PSC_A2},
+       {0x0100, RX_PSC_A3},
+       {0x03C7, RX_REE_GCSM1_EQENM_PH1},
+       {0x01C7, RX_REE_GCSM1_EQENM_PH2},
+       {0x0000, RX_DIAG_DFE_CTRL},
+       {0x0019, RX_REE_TAP1_CLIP},
+       {0x0019, RX_REE_TAP2TON_CLIP},
+       {0x0098, RX_DIAG_NQST_CTRL},
+       {0x0C01, RX_DIAG_DFE_AMP_TUNE_2},
+       {0x0000, RX_DIAG_DFE_AMP_TUNE_3},
+       {0x0000, RX_DIAG_PI_CAP},
+       {0x0010, RX_DIAG_PI_RATE},
+       {0x0001, RX_DIAG_ACYA},
+       {0x018C, RX_CDRLF_CNFG}
+};
+
+static struct cdns_torrent_vals j7200_sgmii_100_no_ssc_rx_ln_vals = {
+       .reg_pairs = j7200_sgmii_100_no_ssc_rx_ln_regs,
+       .num_regs = ARRAY_SIZE(j7200_sgmii_100_no_ssc_rx_ln_regs),
+};
+
 /* SGMII 100 MHz Ref clk, internal SSC */
 static struct cdns_reg_pairs sgmii_100_int_ssc_cmn_regs[] = {
        {0x0004, CMN_PLL0_DSM_DIAG_M0},
@@ -3944,6 +4270,51 @@ static struct cdns_torrent_vals qsgmii_100_no_ssc_rx_ln_vals = {
        .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_rx_ln_regs),
 };
 
+/* TI J7200, multilink QSGMII */
+static struct cdns_reg_pairs j7200_qsgmii_100_no_ssc_tx_ln_regs[] = {
+       {0x07A2, TX_RCVDET_ST_TMR},
+       {0x00F3, TX_PSC_A0},
+       {0x04A2, TX_PSC_A2},
+       {0x04A2, TX_PSC_A3 },
+       {0x0000, TX_TXCC_CPOST_MULT_00},
+       {0x0011, TX_TXCC_MGNFS_MULT_100},
+       {0x0003, DRV_DIAG_TX_DRV},
+       {0x0002, XCVR_DIAG_PSC_OVRD},
+       {0x4000, XCVR_DIAG_RXCLK_CTRL}
+};
+
+static struct cdns_torrent_vals j7200_qsgmii_100_no_ssc_tx_ln_vals = {
+       .reg_pairs = j7200_qsgmii_100_no_ssc_tx_ln_regs,
+       .num_regs = ARRAY_SIZE(j7200_qsgmii_100_no_ssc_tx_ln_regs),
+};
+
+static struct cdns_reg_pairs j7200_qsgmii_100_no_ssc_rx_ln_regs[] = {
+       {0x0014, RX_SDCAL0_INIT_TMR},
+       {0x0062, RX_SDCAL0_ITER_TMR},
+       {0x0014, RX_SDCAL1_INIT_TMR},
+       {0x0062, RX_SDCAL1_ITER_TMR},
+       {0x091D, RX_PSC_A0},
+       {0x0900, RX_PSC_A2},
+       {0x0100, RX_PSC_A3},
+       {0x03C7, RX_REE_GCSM1_EQENM_PH1},
+       {0x01C7, RX_REE_GCSM1_EQENM_PH2},
+       {0x0000, RX_DIAG_DFE_CTRL},
+       {0x0019, RX_REE_TAP1_CLIP},
+       {0x0019, RX_REE_TAP2TON_CLIP},
+       {0x0098, RX_DIAG_NQST_CTRL},
+       {0x0C01, RX_DIAG_DFE_AMP_TUNE_2},
+       {0x0000, RX_DIAG_DFE_AMP_TUNE_3},
+       {0x0000, RX_DIAG_PI_CAP},
+       {0x0010, RX_DIAG_PI_RATE},
+       {0x0001, RX_DIAG_ACYA},
+       {0x018C, RX_CDRLF_CNFG}
+};
+
+static struct cdns_torrent_vals j7200_qsgmii_100_no_ssc_rx_ln_vals = {
+       .reg_pairs = j7200_qsgmii_100_no_ssc_rx_ln_regs,
+       .num_regs = ARRAY_SIZE(j7200_qsgmii_100_no_ssc_rx_ln_regs),
+};
+
 /* QSGMII 100 MHz Ref clk, internal SSC */
 static struct cdns_reg_pairs qsgmii_100_int_ssc_cmn_regs[] = {
        {0x0004, CMN_PLL0_DSM_DIAG_M0},
@@ -4166,14 +4537,17 @@ static struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_QSGMII), &pcie_sgmii_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_link_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_link_cmn_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USB), &usb_sgmii_link_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USXGMII), &usxgmii_sgmii_link_cmn_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USB), &usb_sgmii_link_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USXGMII), &usxgmii_sgmii_link_cmn_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &sl_usb_link_cmn_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &pcie_usb_link_cmn_vals},
@@ -4182,6 +4556,9 @@ static struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_dp_link_cmn_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_NONE), &sl_usxgmii_link_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &pcie_usxgmii_link_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_link_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_link_cmn_vals},
 };
 
 static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
@@ -4194,14 +4571,17 @@ static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_QSGMII), &pcie_sgmii_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_xcvr_diag_ln_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_xcvr_diag_ln_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USB), &sgmii_usb_xcvr_diag_ln_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USXGMII), &sgmii_usxgmii_xcvr_diag_ln_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USB), &sgmii_usb_xcvr_diag_ln_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USXGMII), &sgmii_usxgmii_xcvr_diag_ln_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &sl_usb_xcvr_diag_ln_vals},
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &usb_pcie_xcvr_diag_ln_vals},
@@ -4210,6 +4590,9 @@ static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_dp_xcvr_diag_ln_vals},
 
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_NONE), &sl_usxgmii_xcvr_diag_ln_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &usxgmii_pcie_xcvr_diag_ln_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_xcvr_diag_ln_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_xcvr_diag_ln_vals},
 };
 
 static struct cdns_torrent_vals_entry pcs_cmn_vals_entries[] = {
@@ -4285,6 +4668,17 @@ static struct cdns_torrent_vals_entry cmn_vals_entries[] = {
        {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals},
 
        {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &ml_sgmii_pll1_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &ml_sgmii_pll1_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_pll1_156_25_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_pll0_156_25_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_pll0_156_25_no_ssc_cmn_vals},
 };
 
 static struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {
@@ -4352,6 +4746,17 @@ static struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {
        {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
 
        {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &sgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
 };
 
 static struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {
@@ -4419,6 +4824,17 @@ static struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {
        {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
 
        {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals},
 };
 
 static const struct cdns_torrent_data cdns_map_torrent = {
@@ -4452,6 +4868,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
 
 static struct cdns_torrent_vals_entry j721e_phy_pma_cmn_vals_entries[] = {
        {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_NONE), &ti_usxgmii_phy_pma_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &ti_usxgmii_phy_pma_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &ti_usxgmii_phy_pma_cmn_vals},
+       {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &ti_usxgmii_phy_pma_cmn_vals},
 };
 
 static struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {
@@ -4519,6 +4938,17 @@ static struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {
        {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
 
        {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
 };
 
 static const struct cdns_torrent_data ti_j721e_map_torrent = {
@@ -4554,6 +4984,274 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
        },
 };
 
+/* TI J7200 (Torrent SD0805) */
+static struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = {
+       {CDNS_TORRENT_KEY(CLK_19_2_MHZ, CLK_19_2_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_19_2_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_25_MHZ, CLK_25_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_25_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_PCIE, NO_SSC), &dp_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_USB, NO_SSC), &sl_dp_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, NO_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &sl_pcie_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, NO_SSC), &pcie_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, NO_SSC), &pcie_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sl_sgmii_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_NONE, NO_SSC), &sl_qsgmii_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, NO_SSC), &qsgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, NO_SSC), &sl_usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, NO_SSC), &usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &sl_usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, NO_SSC), &sl_usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &j7200_ml_sgmii_pll1_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &j7200_ml_sgmii_pll1_100_no_ssc_cmn_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_pll1_156_25_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_vals},
+};
+
+static struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = {
+       {CDNS_TORRENT_KEY(CLK_19_2_MHZ, CLK_19_2_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_19_2_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_25_MHZ, CLK_25_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_25_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_PCIE, NO_SSC), &dp_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_USB, NO_SSC), &dp_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, NO_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, NO_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, EXTERNAL_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, INTERNAL_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, NO_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, EXTERNAL_SSC), NULL},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_NONE, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &j7200_sgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &j7200_qsgmii_100_no_ssc_tx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
+};
+
+static struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = {
+       {CDNS_TORRENT_KEY(CLK_19_2_MHZ, CLK_19_2_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_19_2_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_25_MHZ, CLK_25_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_25_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_PCIE, NO_SSC), &dp_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_USB, NO_SSC), &dp_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_NONE, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals},
+
+       /* Dual refclk */
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &j7200_sgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &j7200_qsgmii_100_no_ssc_rx_ln_vals},
+
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals},
+       {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals},
+};
+
+static const struct cdns_torrent_data ti_j7200_map_torrent = {
+       .block_offset_shift = 0x0,
+       .reg_offset_shift = 0x1,
+       .link_cmn_vals_tbl = {
+               .entries = link_cmn_vals_entries,
+               .num_entries = ARRAY_SIZE(link_cmn_vals_entries),
+       },
+       .xcvr_diag_vals_tbl = {
+               .entries = xcvr_diag_vals_entries,
+               .num_entries = ARRAY_SIZE(xcvr_diag_vals_entries),
+       },
+       .pcs_cmn_vals_tbl = {
+               .entries = pcs_cmn_vals_entries,
+               .num_entries = ARRAY_SIZE(pcs_cmn_vals_entries),
+       },
+       .phy_pma_cmn_vals_tbl = {
+               .entries = j721e_phy_pma_cmn_vals_entries,
+               .num_entries = ARRAY_SIZE(j721e_phy_pma_cmn_vals_entries),
+       },
+       .cmn_vals_tbl = {
+               .entries = ti_j7200_cmn_vals_entries,
+               .num_entries = ARRAY_SIZE(ti_j7200_cmn_vals_entries),
+       },
+       .tx_ln_vals_tbl = {
+               .entries = ti_j7200_tx_ln_vals_entries,
+               .num_entries = ARRAY_SIZE(ti_j7200_tx_ln_vals_entries),
+       },
+       .rx_ln_vals_tbl = {
+               .entries = ti_j7200_rx_ln_vals_entries,
+               .num_entries = ARRAY_SIZE(ti_j7200_rx_ln_vals_entries),
+       },
+};
+
 static const struct of_device_id cdns_torrent_phy_of_match[] = {
        {
                .compatible = "cdns,torrent-phy",
@@ -4563,6 +5261,10 @@ static const struct of_device_id cdns_torrent_phy_of_match[] = {
                .compatible = "ti,j721e-serdes-10g",
                .data = &ti_j721e_map_torrent,
        },
+       {
+               .compatible = "ti,j7200-serdes-10g",
+               .data = &ti_j7200_map_torrent,
+       },
        {}
 };
 MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match);
index 0ae052df3765525ebc1424f81c7fc7200592b08d..38388dd04bdc1d67018c113c1ad5779c50a07196 100644 (file)
@@ -294,7 +294,7 @@ static int mixel_lvds_phy_reset(struct device *dev)
 }
 
 static struct phy *mixel_lvds_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct mixel_lvds_phy_priv *priv = dev_get_drvdata(dev);
        unsigned int phy_id;
index e2187767ce00ce5658109e820c173a8a2fc04d12..b86da8e9daa46549148c2501666e85ddccd1e2e7 100644 (file)
@@ -556,7 +556,7 @@ static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane)
 }
 
 static struct phy *lynx_28g_xlate(struct device *dev,
-                                 struct of_phandle_args *args)
+                                 const struct of_phandle_args *args)
 {
        struct lynx_28g_priv *priv = dev_get_drvdata(dev);
        int idx = args->args[0];
index c44588fd5a53e44d7391ec24db6d390fed0065ca..7436dcae398184d5644dc92594f8c316fc3d44d0 100644 (file)
@@ -163,7 +163,7 @@ static const struct phy_ops histb_combphy_ops = {
 };
 
 static struct phy *histb_combphy_xlate(struct device *dev,
-                                      struct of_phandle_args *args)
+                                      const struct of_phandle_args *args)
 {
        struct histb_combphy_priv *priv = dev_get_drvdata(dev);
        struct histb_combphy_mode *mode = &priv->mode;
index d32e267c0001d8a6ea47c8da522e1c11076b193e..f8e3054a9e5977c2ce9e9dd6492857185f506fd7 100644 (file)
@@ -508,7 +508,7 @@ static const struct phy_ops intel_cbphy_ops = {
 };
 
 static struct phy *intel_cbphy_xlate(struct device *dev,
-                                    struct of_phandle_args *args)
+                                    const struct of_phandle_args *args)
 {
        struct intel_combo_phy *cbphy = dev_get_drvdata(dev);
        u32 iphy_id;
index ef93bf2cba1053be5196c83a8bb8f6def7460e1f..406a87c8b7599084cc82a5a1d43cbcea3aa3fc53 100644 (file)
@@ -358,7 +358,7 @@ static const struct phy_ops ltq_vrx200_pcie_phy_ops = {
 };
 
 static struct phy *ltq_vrx200_pcie_phy_xlate(struct device *dev,
-                                            struct of_phandle_args *args)
+                                            const struct of_phandle_args *args)
 {
        struct ltq_vrx200_pcie_phy_priv *priv = dev_get_drvdata(dev);
        unsigned int mode;
index b141e3cd8a941998ef3140def0edfba331671d0b..3731f9b25655e4f23295f1416e706107766facf6 100644 (file)
@@ -61,7 +61,7 @@ static const struct phy_ops armada375_usb_phy_ops = {
  * USB3 case it still optional and we use ENODEV.
  */
 static struct phy *armada375_usb_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct armada375_cluster_phy *cluster_phy = dev_get_drvdata(dev);
 
index b7d99861526a559fe2aaaed2f22105667a1f0ab7..5063361b01208eb59d81a9946a1e58c4dd4615fe 100644 (file)
@@ -47,8 +47,13 @@ struct a38x_comphy {
        struct a38x_comphy_lane lane[MAX_A38X_COMPHY];
 };
 
+/*
+ * Map serdes lanes and gbe ports to serdes mux configuration values:
+ * row index = serdes lane,
+ * column index = gbe port number.
+ */
 static const u8 gbe_mux[MAX_A38X_COMPHY][MAX_A38X_PORTS] = {
-       { 0, 0, 0 },
+       { 3, 0, 0 },
        { 4, 5, 0 },
        { 0, 4, 0 },
        { 0, 0, 4 },
@@ -155,7 +160,7 @@ static const struct phy_ops a38x_comphy_ops = {
 };
 
 static struct phy *a38x_comphy_xlate(struct device *dev,
-                                    struct of_phandle_args *args)
+                                    const struct of_phandle_args *args)
 {
        struct a38x_comphy_lane *lane;
        struct phy *phy;
index f972d78372eaf5fb19cdebdb0a177a58ad7fc39e..c90e2867900c3f372a688fdde8a271348df18a6b 100644 (file)
@@ -155,7 +155,7 @@ static int phy_berlin_sata_power_off(struct phy *phy)
 }
 
 static struct phy *phy_berlin_sata_phy_xlate(struct device *dev,
-                                            struct of_phandle_args *args)
+                                            const struct of_phandle_args *args)
 {
        struct phy_berlin_priv *priv = dev_get_drvdata(dev);
        int i;
index 24c3371e2bb294402a5be470520f4835bdd49522..41162d7228c919dadc65c526657e120eff268f59 100644 (file)
@@ -1213,7 +1213,7 @@ static const struct phy_ops mvebu_a3700_comphy_ops = {
 };
 
 static struct phy *mvebu_a3700_comphy_xlate(struct device *dev,
-                                           struct of_phandle_args *args)
+                                           const struct of_phandle_args *args)
 {
        struct mvebu_a3700_comphy_lane *lane;
        unsigned int port;
index b0dd133665986e377ca164b726257d15ffb0892e..da5e8f4057490ca581109d13c7c8e736cc4b136e 100644 (file)
@@ -917,7 +917,7 @@ static const struct phy_ops mvebu_comphy_ops = {
 };
 
 static struct phy *mvebu_comphy_xlate(struct device *dev,
-                                     struct of_phandle_args *args)
+                                     const struct of_phandle_args *args)
 {
        struct mvebu_comphy_lane *lane;
        struct phy *phy;
index 3125ecb5d119fec8f6a93655d95f306b9562e085..3849b7c87d287254a766817ff819dac2efd5b097 100644 (file)
@@ -58,6 +58,18 @@ config PHY_MTK_HDMI
        help
          Support HDMI PHY for Mediatek SoCs.
 
+config PHY_MTK_MIPI_CSI_0_5
+       tristate "MediaTek MIPI CSI CD-PHY v0.5 Driver"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       depends on OF
+       select GENERIC_PHY
+       help
+         Enable this to support the MIPI CSI CD-PHY receiver version 0.5.
+         The driver supports multiple CSI cdphy ports simultaneously.
+
+         To compile this driver as a module, choose M here: the
+         module will be called phy-mtk-mipi-csi-0-5.
+
 config PHY_MTK_MIPI_DSI
        tristate "MediaTek MIPI-DSI Driver"
        depends on ARCH_MEDIATEK || COMPILE_TEST
index c9a50395533eb1f859baf8609864125939fbbb2a..f6e24a47e08153bbafc1b94fe6c30248c98e61e9 100644 (file)
@@ -15,6 +15,8 @@ phy-mtk-hdmi-drv-y                    += phy-mtk-hdmi-mt8173.o
 phy-mtk-hdmi-drv-y                     += phy-mtk-hdmi-mt8195.o
 obj-$(CONFIG_PHY_MTK_HDMI)             += phy-mtk-hdmi-drv.o
 
+obj-$(CONFIG_PHY_MTK_MIPI_CSI_0_5)     += phy-mtk-mipi-csi-0-5.o
+
 phy-mtk-mipi-dsi-drv-y                 := phy-mtk-mipi-dsi.o
 phy-mtk-mipi-dsi-drv-y                 += phy-mtk-mipi-dsi-mt8173.o
 phy-mtk-mipi-dsi-drv-y                 += phy-mtk-mipi-dsi-mt8183.o
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5-rx-reg.h b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5-rx-reg.h
new file mode 100644 (file)
index 0000000..97b4c27
--- /dev/null
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, MediaTek Inc.
+ * Copyright (c) 2023, BayLibre Inc.
+ */
+
+#ifndef __PHY_MTK_MIPI_CSI_V_0_5_RX_REG_H__
+#define __PHY_MTK_MIPI_CSI_V_0_5_RX_REG_H__
+
+/*
+ * CSI1 and CSI2 are identical, and similar to CSI0. All CSIX macros are
+ * applicable to the three PHYs. Where differences exist, they are denoted by
+ * macro names using CSI0 and CSI1, the latter being applicable to CSI1 and
+ * CSI2 alike.
+ */
+
+#define MIPI_RX_ANA00_CSIXA                    0x0000
+#define RG_CSI0A_CPHY_EN                       BIT(0)
+#define RG_CSIXA_EQ_PROTECT_EN                 BIT(1)
+#define RG_CSIXA_BG_LPF_EN                     BIT(2)
+#define RG_CSIXA_BG_CORE_EN                    BIT(3)
+#define RG_CSIXA_DPHY_L0_CKMODE_EN             BIT(5)
+#define RG_CSIXA_DPHY_L0_CKSEL                 BIT(6)
+#define RG_CSIXA_DPHY_L1_CKMODE_EN             BIT(8)
+#define RG_CSIXA_DPHY_L1_CKSEL                 BIT(9)
+#define RG_CSIXA_DPHY_L2_CKMODE_EN             BIT(11)
+#define RG_CSIXA_DPHY_L2_CKSEL                 BIT(12)
+
+#define MIPI_RX_ANA18_CSIXA                    0x0018
+#define RG_CSI0A_L0_T0AB_EQ_IS                 GENMASK(5, 4)
+#define RG_CSI0A_L0_T0AB_EQ_BW                 GENMASK(7, 6)
+#define RG_CSI0A_L1_T1AB_EQ_IS                 GENMASK(21, 20)
+#define RG_CSI0A_L1_T1AB_EQ_BW                 GENMASK(23, 22)
+#define RG_CSI0A_L2_T1BC_EQ_IS                 GENMASK(21, 20)
+#define RG_CSI0A_L2_T1BC_EQ_BW                 GENMASK(23, 22)
+#define RG_CSI1A_L0_EQ_IS                      GENMASK(5, 4)
+#define RG_CSI1A_L0_EQ_BW                      GENMASK(7, 6)
+#define RG_CSI1A_L1_EQ_IS                      GENMASK(21, 20)
+#define RG_CSI1A_L1_EQ_BW                      GENMASK(23, 22)
+#define RG_CSI1A_L2_EQ_IS                      GENMASK(5, 4)
+#define RG_CSI1A_L2_EQ_BW                      GENMASK(7, 6)
+
+#define MIPI_RX_ANA1C_CSIXA                    0x001c
+#define MIPI_RX_ANA20_CSI0A                    0x0020
+
+#define MIPI_RX_ANA24_CSIXA                    0x0024
+#define RG_CSIXA_RESERVE                       GENMASK(31, 24)
+
+#define MIPI_RX_ANA40_CSIXA                    0x0040
+#define RG_CSIXA_CPHY_FMCK_SEL                 GENMASK(1, 0)
+#define RG_CSIXA_ASYNC_OPTION                  GENMASK(7, 4)
+#define RG_CSIXA_CPHY_SPARE                    GENMASK(31, 16)
+
+#define MIPI_RX_WRAPPER80_CSIXA                        0x0080
+#define CSR_CSI_RST_MODE                       GENMASK(17, 16)
+
+#define MIPI_RX_ANAA8_CSIXA                    0x00a8
+#define RG_CSIXA_CDPHY_L0_T0_BYTECK_INVERT     BIT(0)
+#define RG_CSIXA_DPHY_L1_BYTECK_INVERT         BIT(1)
+#define RG_CSIXA_CDPHY_L2_T1_BYTECK_INVERT     BIT(2)
+
+#endif
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
new file mode 100644 (file)
index 0000000..058e1d9
--- /dev/null
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek MIPI CSI v0.5 driver
+ *
+ * Copyright (c) 2023, MediaTek Inc.
+ * Copyright (c) 2023, BayLibre Inc.
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "phy-mtk-io.h"
+#include "phy-mtk-mipi-csi-0-5-rx-reg.h"
+
+#define CSIXB_OFFSET           0x1000
+
+struct mtk_mipi_cdphy_port {
+       struct device *dev;
+       void __iomem *base;
+       struct phy *phy;
+       u32 type;
+       u32 mode;
+       u32 num_lanes;
+};
+
+enum PHY_TYPE {
+       DPHY = 0,
+       CPHY,
+       CDPHY,
+};
+
+static void mtk_phy_csi_cdphy_ana_eq_tune(void __iomem *base)
+{
+       mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_IS, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_BW, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_IS, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_BW, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_IS, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_BW, 1);
+
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_IS, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_BW, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_IS, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_BW, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_IS, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_BW, 1);
+}
+
+static void mtk_phy_csi_dphy_ana_eq_tune(void __iomem *base)
+{
+       mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_IS, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_BW, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_IS, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_BW, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_IS, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_BW, 1);
+
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_IS, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_BW, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_IS, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_BW, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_IS, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_BW, 1);
+}
+
+static int mtk_mipi_phy_power_on(struct phy *phy)
+{
+       struct mtk_mipi_cdphy_port *port = phy_get_drvdata(phy);
+       void __iomem *base = port->base;
+
+       /*
+        * The driver currently supports DPHY and CD-PHY phys,
+        * but the only mode supported is DPHY,
+        * so CD-PHY capable phys must be configured in DPHY mode
+        */
+       if (port->type == CDPHY) {
+               mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSI0A_CPHY_EN, 0);
+               mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA,
+                                    RG_CSI0A_CPHY_EN, 0);
+       }
+
+       /*
+        * Lane configuration:
+        *
+        * Only 4 data + 1 clock is supported for now with the following mapping:
+        *
+        * CSIXA_LNR0 --> D2
+        * CSIXA_LNR1 --> D0
+        * CSIXA_LNR2 --> C
+        * CSIXB_LNR0 --> D1
+        * CSIXB_LNR1 --> D3
+        */
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L0_CKMODE_EN, 0);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L0_CKSEL, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L1_CKMODE_EN, 0);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L1_CKSEL, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L2_CKMODE_EN, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L2_CKSEL, 1);
+
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA,
+                            RG_CSIXA_DPHY_L0_CKMODE_EN, 0);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L0_CKSEL, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA,
+                            RG_CSIXA_DPHY_L1_CKMODE_EN, 0);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L1_CKSEL, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA,
+                            RG_CSIXA_DPHY_L2_CKMODE_EN, 0);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L2_CKSEL, 1);
+
+       /* Byte clock invert */
+       mtk_phy_update_field(base + MIPI_RX_ANAA8_CSIXA, RG_CSIXA_CDPHY_L0_T0_BYTECK_INVERT, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANAA8_CSIXA, RG_CSIXA_DPHY_L1_BYTECK_INVERT, 1);
+       mtk_phy_update_field(base + MIPI_RX_ANAA8_CSIXA, RG_CSIXA_CDPHY_L2_T1_BYTECK_INVERT, 1);
+
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANAA8_CSIXA,
+                            RG_CSIXA_CDPHY_L0_T0_BYTECK_INVERT, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANAA8_CSIXA,
+                            RG_CSIXA_DPHY_L1_BYTECK_INVERT, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANAA8_CSIXA,
+                            RG_CSIXA_CDPHY_L2_T1_BYTECK_INVERT, 1);
+
+       /* Start ANA EQ tuning */
+       if (port->type == CDPHY)
+               mtk_phy_csi_cdphy_ana_eq_tune(base);
+       else
+               mtk_phy_csi_dphy_ana_eq_tune(base);
+
+       /* End ANA EQ tuning */
+       mtk_phy_set_bits(base + MIPI_RX_ANA40_CSIXA, 0x90);
+
+       mtk_phy_update_field(base + MIPI_RX_ANA24_CSIXA, RG_CSIXA_RESERVE, 0x40);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA24_CSIXA, RG_CSIXA_RESERVE, 0x40);
+       mtk_phy_update_field(base + MIPI_RX_WRAPPER80_CSIXA, CSR_CSI_RST_MODE, 0);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_WRAPPER80_CSIXA, CSR_CSI_RST_MODE, 0);
+       /* ANA power on */
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 1);
+       usleep_range(20, 40);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 1);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 1);
+
+       return 0;
+}
+
+static int mtk_mipi_phy_power_off(struct phy *phy)
+{
+       struct mtk_mipi_cdphy_port *port = phy_get_drvdata(phy);
+       void __iomem *base = port->base;
+
+       /* Disable MIPI BG. */
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 0);
+       mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 0);
+
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 0);
+       mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 0);
+
+       return 0;
+}
+
+static struct phy *mtk_mipi_cdphy_xlate(struct device *dev,
+                                       const struct of_phandle_args *args)
+{
+       struct mtk_mipi_cdphy_port *priv = dev_get_drvdata(dev);
+
+       /*
+        * If PHY is CD-PHY then we need to get the operating mode
+        * For now only D-PHY mode is supported
+        */
+       if (priv->type == CDPHY) {
+               if (args->args_count != 1) {
+                       dev_err(dev, "invalid number of arguments\n");
+                       return ERR_PTR(-EINVAL);
+               }
+               switch (args->args[0]) {
+               case PHY_TYPE_DPHY:
+                       priv->mode = DPHY;
+                       if (priv->num_lanes != 4) {
+                               dev_err(dev, "Only 4D1C mode is supported for now!\n");
+                               return ERR_PTR(-EINVAL);
+                       }
+                       break;
+               default:
+                       dev_err(dev, "Unsupported PHY type: %i\n", args->args[0]);
+                       return ERR_PTR(-EINVAL);
+               }
+       } else {
+               if (args->args_count) {
+                       dev_err(dev, "invalid number of arguments\n");
+                       return ERR_PTR(-EINVAL);
+               }
+               priv->mode = DPHY;
+       }
+
+       return priv->phy;
+}
+
+static const struct phy_ops mtk_cdphy_ops = {
+       .power_on       = mtk_mipi_phy_power_on,
+       .power_off      = mtk_mipi_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static int mtk_mipi_cdphy_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct phy_provider *phy_provider;
+       struct mtk_mipi_cdphy_port *port;
+       struct phy *phy;
+       int ret;
+       u32 phy_type;
+
+       port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+       if (!port)
+               return -ENOMEM;
+
+       dev_set_drvdata(dev, port);
+
+       port->dev = dev;
+
+       port->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(port->base))
+               return PTR_ERR(port->base);
+
+       ret = of_property_read_u32(dev->of_node, "num-lanes", &port->num_lanes);
+       if (ret) {
+               dev_err(dev, "Failed to read num-lanes property: %i\n", ret);
+               return ret;
+       }
+
+       /*
+        * phy-type is optional, if not present, PHY is considered to be CD-PHY
+        */
+       if (device_property_present(dev, "phy-type")) {
+               ret = of_property_read_u32(dev->of_node, "phy-type", &phy_type);
+               if (ret) {
+                       dev_err(dev, "Failed to read phy-type property: %i\n", ret);
+                       return ret;
+               }
+               switch (phy_type) {
+               case PHY_TYPE_DPHY:
+                       port->type = DPHY;
+                       break;
+               default:
+                       dev_err(dev, "Unsupported PHY type: %i\n", phy_type);
+                       return -EINVAL;
+               }
+       } else {
+               port->type = CDPHY;
+       }
+
+       phy = devm_phy_create(dev, NULL, &mtk_cdphy_ops);
+       if (IS_ERR(phy)) {
+               dev_err(dev, "Failed to create PHY: %ld\n", PTR_ERR(phy));
+               return PTR_ERR(phy);
+       }
+
+       port->phy = phy;
+       phy_set_drvdata(phy, port);
+
+       phy_provider = devm_of_phy_provider_register(dev, mtk_mipi_cdphy_xlate);
+       if (IS_ERR(phy_provider)) {
+               dev_err(dev, "Failed to register PHY provider: %ld\n",
+                       PTR_ERR(phy_provider));
+               return PTR_ERR(phy_provider);
+       }
+
+       return 0;
+}
+
+static const struct of_device_id mtk_mipi_cdphy_of_match[] = {
+       { .compatible = "mediatek,mt8365-csi-rx" },
+       { /* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mtk_mipi_cdphy_of_match);
+
+static struct platform_driver mipi_cdphy_pdrv = {
+       .probe = mtk_mipi_cdphy_probe,
+       .driver = {
+               .name   = "mtk-mipi-csi-0-5",
+               .of_match_table = mtk_mipi_cdphy_of_match,
+       },
+};
+module_platform_driver(mipi_cdphy_pdrv);
+
+MODULE_DESCRIPTION("MediaTek MIPI CSI CD-PHY v0.5 Driver");
+MODULE_AUTHOR("Louis Kuo <louis.kuo@mediatek.com>");
+MODULE_LICENSE("GPL");
index a4746f6cb8a187e2a1172fd5fc2dd1f7ceee7bb1..25b86bbb9cec049a069f54d17016738e72df522b 100644 (file)
@@ -1467,7 +1467,7 @@ static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 }
 
 static struct phy *mtk_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct mtk_tphy *tphy = dev_get_drvdata(dev);
        struct mtk_phy_instance *instance = NULL;
index b222fbbd71d18642cddbb4029cb1823510087853..064fd09417275e53581c8d47d5aa942c9bad7ddf 100644 (file)
@@ -378,7 +378,7 @@ static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 }
 
 static struct phy *mtk_phy_xlate(struct device *dev,
-                                struct of_phandle_args *args)
+                                const struct of_phandle_args *args)
 {
        struct mtk_xsphy *xsphy = dev_get_drvdata(dev);
        struct xsphy_instance *inst = NULL;
index b5ac2b7995e7156b73e348814ce4e29b6f71a874..835e369cdfc5fe6f56162fee4d9437e035b857d6 100644 (file)
@@ -518,7 +518,7 @@ static const struct phy_ops serdes_ops = {
 };
 
 static struct phy *serdes_simple_xlate(struct device *dev,
-                                      struct of_phandle_args *args)
+                                      const struct of_phandle_args *args)
 {
        struct serdes_ctrl *ctrl = dev_get_drvdata(dev);
        unsigned int port, idx, i;
index 01bd5ea620c5b7d26abb100909cfb67ce689a273..7cb85029fab399e61b3e7f973b3730e4ad3f295b 100644 (file)
@@ -2509,7 +2509,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
-                                    struct of_phandle_args *args)
+                                    const struct of_phandle_args *args)
 {
        struct sparx5_serdes_private *priv = dev_get_drvdata(dev);
        int idx;
index d9443e865a780f11ec03105e373f2bcf9bded8aa..1cd1b5db2ad7cf4eb721a14a1f150b1f8ffe9834 100644 (file)
@@ -441,7 +441,7 @@ static const struct phy_ops serdes_ops = {
 };
 
 static struct phy *serdes_simple_xlate(struct device *dev,
-                                      struct of_phandle_args *args)
+                                      const struct of_phandle_args *args)
 {
        struct serdes_ctrl *ctrl = dev_get_drvdata(dev);
        unsigned int port, idx, i;
index d9be6a4d538387fac816d4d46c781ebd84cc29de..7f9b4de772eedfb9f28448511dccfd0a462b658a 100644 (file)
@@ -700,8 +700,8 @@ EXPORT_SYMBOL_GPL(devm_phy_put);
  * should provide a custom of_xlate function that reads the *args* and returns
  * the appropriate phy.
  */
-struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
-       *args)
+struct phy *of_phy_simple_xlate(struct device *dev,
+                               const struct of_phandle_args *args)
 {
        struct phy *phy;
        struct class_dev_iter iter;
@@ -1095,7 +1095,7 @@ EXPORT_SYMBOL_GPL(devm_phy_destroy);
 struct phy_provider *__of_phy_provider_register(struct device *dev,
        struct device_node *children, struct module *owner,
        struct phy * (*of_xlate)(struct device *dev,
-                                struct of_phandle_args *args))
+                                const struct of_phandle_args *args))
 {
        struct phy_provider *phy_provider;
 
@@ -1158,7 +1158,7 @@ EXPORT_SYMBOL_GPL(__of_phy_provider_register);
 struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
        struct device_node *children, struct module *owner,
        struct phy * (*of_xlate)(struct device *dev,
-                                struct of_phandle_args *args))
+                                const struct of_phandle_args *args))
 {
        struct phy_provider **ptr, *phy_provider;
 
index 1f0f908323f0e660a108622cb90ca55c7f595b32..5007dc7a357cb7b1d3df2958deead20a59ed7172 100644 (file)
@@ -1611,7 +1611,7 @@ static const struct phy_ops xgene_phy_ops = {
 };
 
 static struct phy *xgene_phy_xlate(struct device *dev,
-                                  struct of_phandle_args *args)
+                                  const struct of_phandle_args *args)
 {
        struct xgene_phy_ctx *ctx = dev_get_drvdata(dev);
 
index ffd609ac62336c1e7fcbb1d287d5a13ea69b399d..eb60e950ad53334a3ada3db618aa584afb33fb93 100644 (file)
@@ -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
index 8e5078304646e9fcd4a758aabc712052b61369fe..9818d994c68b2ed30e10c8eecb7b800d034711be 100644 (file)
@@ -21,7 +21,8 @@
 
 #include <dt-bindings/phy/phy.h>
 
-#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-dp-phy.h"
+#include "phy-qcom-qmp-qserdes-com-v4.h"
 
 /* EDP_PHY registers */
 #define DP_PHY_CFG                              0x0010
index 17c4ad7553a5edd0960e8ff7e64e97dd7f22b5f5..7d585a4bbbba950c803412d829bed4140d57d898 100644 (file)
 
 #include <dt-bindings/phy/phy-qcom-qmp.h>
 
+#include "phy-qcom-qmp-common.h"
+
 #include "phy-qcom-qmp.h"
 #include "phy-qcom-qmp-pcs-misc-v3.h"
 #include "phy-qcom-qmp-pcs-usb-v4.h"
 #include "phy-qcom-qmp-pcs-usb-v5.h"
 #include "phy-qcom-qmp-pcs-usb-v6.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)
+#include "phy-qcom-qmp-dp-com-v3.h"
+
+#include "phy-qcom-qmp-dp-phy.h"
+#include "phy-qcom-qmp-dp-phy-v3.h"
+#include "phy-qcom-qmp-dp-phy-v4.h"
+#include "phy-qcom-qmp-dp-phy-v5.h"
+#include "phy-qcom-qmp-dp-phy-v6.h"
 
 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
 /* DP PHY soft reset */
 #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 */
-
 /* QPHY_V3_DP_COM_TYPEC_CTRL register bits */
 #define SW_PORTSELECT_VAL                      BIT(0)
 #define SW_PORTSELECT_MUX                      BIT(1)
 
 #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 */
@@ -2031,55 +1996,29 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
 };
 
-static void qmp_combo_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_combo_configure(void __iomem *base,
-                                  const struct qmp_phy_init_tbl tbl[],
-                                  int num)
-{
-       qmp_combo_configure_lane(base, tbl, num, 0xff);
-}
-
 static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)
 {
        const struct qmp_phy_cfg *cfg = qmp->cfg;
        void __iomem *serdes = qmp->dp_serdes;
        const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
 
-       qmp_combo_configure(serdes, cfg->dp_serdes_tbl, cfg->dp_serdes_tbl_num);
+       qmp_configure(serdes, cfg->dp_serdes_tbl, cfg->dp_serdes_tbl_num);
 
        switch (dp_opts->link_rate) {
        case 1620:
-               qmp_combo_configure(serdes, cfg->serdes_tbl_rbr,
+               qmp_configure(serdes, cfg->serdes_tbl_rbr,
                                cfg->serdes_tbl_rbr_num);
                break;
        case 2700:
-               qmp_combo_configure(serdes, cfg->serdes_tbl_hbr,
+               qmp_configure(serdes, cfg->serdes_tbl_hbr,
                                cfg->serdes_tbl_hbr_num);
                break;
        case 5400:
-               qmp_combo_configure(serdes, cfg->serdes_tbl_hbr2,
+               qmp_configure(serdes, cfg->serdes_tbl_hbr2,
                                cfg->serdes_tbl_hbr2_num);
                break;
        case 8100:
-               qmp_combo_configure(serdes, cfg->serdes_tbl_hbr3,
+               qmp_configure(serdes, cfg->serdes_tbl_hbr3,
                                cfg->serdes_tbl_hbr3_num);
                break;
        default:
@@ -2370,7 +2309,7 @@ static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp)
        u32 status;
        int ret;
 
-       writel(0x0f, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_CFG_1);
+       writel(0x0f, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG_1);
 
        qmp_combo_configure_dp_mode(qmp);
 
@@ -2681,8 +2620,8 @@ static int qmp_combo_dp_power_on(struct phy *phy)
 
        qmp_combo_dp_serdes_init(qmp);
 
-       qmp_combo_configure_lane(tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1);
-       qmp_combo_configure_lane(tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2);
+       qmp_configure_lane(tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1);
+       qmp_configure_lane(tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2);
 
        /* Configure special DP tx tunings */
        cfg->configure_dp_tx(qmp);
@@ -2724,7 +2663,7 @@ static int qmp_combo_usb_power_on(struct phy *phy)
        unsigned int val;
        int ret;
 
-       qmp_combo_configure(serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
+       qmp_configure(serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
 
        ret = clk_prepare_enable(qmp->pipe_clk);
        if (ret) {
@@ -2733,16 +2672,16 @@ static int qmp_combo_usb_power_on(struct phy *phy)
        }
 
        /* Tx, Rx, and PCS configurations */
-       qmp_combo_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
-       qmp_combo_configure_lane(tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
+       qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
+       qmp_configure_lane(tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
 
-       qmp_combo_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
-       qmp_combo_configure_lane(rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
+       qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
+       qmp_configure_lane(rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
 
-       qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+       qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 
        if (pcs_usb)
-               qmp_combo_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
+               qmp_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
 
        if (cfg->has_pwrdn_delay)
                usleep_range(10, 20);
@@ -3515,7 +3454,7 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)
        return 0;
 }
 
-static struct phy *qmp_combo_phy_xlate(struct device *dev, struct of_phandle_args *args)
+static struct phy *qmp_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)
 {
        struct qmp_combo *qmp = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-common.h b/drivers/phy/qualcomm/phy-qcom-qmp-common.h
new file mode 100644 (file)
index 0000000..7993842
--- /dev/null
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_COMMON_H_
+#define QCOM_PHY_QMP_COMMON_H_
+
+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,         \
+       }
+
+static inline void qmp_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 inline void qmp_configure(void __iomem *base,
+                                     const struct qmp_phy_init_tbl tbl[],
+                                     int num)
+{
+       qmp_configure_lane(base, tbl, num, 0xff);
+}
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-com-v3.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-com-v3.h
new file mode 100644 (file)
index 0000000..396179e
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_COM_V3_H_
+#define QCOM_PHY_QMP_DP_COM_V3_H_
+
+/* Only for QMP V3 & V4 PHY - DP COM registers */
+#define QPHY_V3_DP_COM_PHY_MODE_CTRL                   0x00
+#define QPHY_V3_DP_COM_SW_RESET                                0x04
+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL                 0x08
+#define QPHY_V3_DP_COM_SWI_CTRL                                0x0c
+#define QPHY_V3_DP_COM_TYPEC_CTRL                      0x10
+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL                        0x14
+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL                 0x1c
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v3.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v3.h
new file mode 100644 (file)
index 0000000..00a9702
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_PHY_V3_H_
+#define QCOM_PHY_QMP_DP_PHY_V3_H_
+
+/* Only for QMP V3 PHY - DP PHY registers */
+#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK           0x048
+#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR          0x04c
+#define QSERDES_V3_DP_PHY_AUX_BIST_CFG                 0x050
+
+#define QSERDES_V3_DP_PHY_VCO_DIV                      0x064
+#define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL             0x06c
+#define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL             0x088
+
+#define QSERDES_V3_DP_PHY_SPARE0                       0x0ac
+#define QSERDES_V3_DP_PHY_STATUS                       0x0c0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v4.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v4.h
new file mode 100644 (file)
index 0000000..ed6795e
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_PHY_V4_H_
+#define QCOM_PHY_QMP_DP_PHY_V4_H_
+
+/* Only for QMP V4 PHY - DP PHY registers */
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK           0x054
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR          0x058
+#define QSERDES_V4_DP_PHY_VCO_DIV                      0x070
+#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL             0x078
+#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL             0x09c
+#define QSERDES_V4_DP_PHY_SPARE0                       0x0c8
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS         0x0d8
+#define QSERDES_V4_DP_PHY_STATUS                       0x0dc
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h
new file mode 100644 (file)
index 0000000..f5cfacf
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_PHY_V5_H_
+#define QCOM_PHY_QMP_DP_PHY_V5_H_
+
+/* Only for QMP V5 PHY - DP PHY registers */
+#define QSERDES_V5_DP_PHY_AUX_INTERRUPT_STATUS         0x0d8
+#define QSERDES_V5_DP_PHY_STATUS                       0x0dc
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h
new file mode 100644 (file)
index 0000000..01a20d3
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_PHY_V6_H_
+#define QCOM_PHY_QMP_DP_PHY_V6_H_
+
+/* Only for QMP V6 PHY - DP PHY registers */
+#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS         0x0e0
+#define QSERDES_V6_DP_PHY_STATUS                       0x0e4
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
new file mode 100644 (file)
index 0000000..0ebd405
--- /dev/null
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_PHY_H_
+#define QCOM_PHY_QMP_DP_PHY_H_
+
+/* QMP PHY - DP PHY registers */
+#define QSERDES_DP_PHY_REVISION_ID0                    0x000
+#define QSERDES_DP_PHY_REVISION_ID1                    0x004
+#define QSERDES_DP_PHY_REVISION_ID2                    0x008
+#define QSERDES_DP_PHY_REVISION_ID3                    0x00c
+#define QSERDES_DP_PHY_CFG                             0x010
+#define QSERDES_DP_PHY_CFG_1                           0x014
+#define QSERDES_DP_PHY_PD_CTL                          0x018
+#define QSERDES_DP_PHY_MODE                            0x01c
+#define QSERDES_DP_PHY_AUX_CFG0                                0x020
+#define QSERDES_DP_PHY_AUX_CFG1                                0x024
+#define QSERDES_DP_PHY_AUX_CFG2                                0x028
+#define QSERDES_DP_PHY_AUX_CFG3                                0x02c
+#define QSERDES_DP_PHY_AUX_CFG4                                0x030
+#define QSERDES_DP_PHY_AUX_CFG5                                0x034
+#define QSERDES_DP_PHY_AUX_CFG6                                0x038
+#define QSERDES_DP_PHY_AUX_CFG7                                0x03c
+#define QSERDES_DP_PHY_AUX_CFG8                                0x040
+#define QSERDES_DP_PHY_AUX_CFG9                                0x044
+
+/* QSERDES COM_BIAS_EN_CLKBUFLR_EN bits */
+# define QSERDES_V3_COM_BIAS_EN                                0x0001
+# define QSERDES_V3_COM_BIAS_EN_MUX                    0x0002
+# define QSERDES_V3_COM_CLKBUF_R_EN                    0x0004
+# define QSERDES_V3_COM_CLKBUF_L_EN                    0x0008
+# define QSERDES_V3_COM_EN_SYSCLK_TX_SEL               0x0010
+# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L              0x0020
+# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R              0x0040
+
+/* QPHY_TX_TX_EMP_POST1_LVL bits */
+# define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK              0x001f
+# define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN            0x0020
+
+/* QPHY_TX_TX_DRV_LVL bits */
+# define DP_PHY_TXn_TX_DRV_LVL_MASK                    0x001f
+# define DP_PHY_TXn_TX_DRV_LVL_MUX_EN                  0x0020
+
+/* QSERDES_DP_PHY_PD_CTL bits */
+# define DP_PHY_PD_CTL_PWRDN                           0x001
+# define DP_PHY_PD_CTL_PSR_PWRDN                       0x002
+# define DP_PHY_PD_CTL_AUX_PWRDN                       0x004
+# define DP_PHY_PD_CTL_LANE_0_1_PWRDN                  0x008
+# define DP_PHY_PD_CTL_LANE_2_3_PWRDN                  0x010
+# define DP_PHY_PD_CTL_PLL_PWRDN                       0x020
+# define DP_PHY_PD_CTL_DP_CLAMP_EN                     0x040
+
+/* QPHY_DP_PHY_AUX_INTERRUPT_STATUS bits */
+# define PHY_AUX_STOP_ERR_MASK                         0x01
+# define PHY_AUX_DEC_ERR_MASK                          0x02
+# define PHY_AUX_SYNC_ERR_MASK                         0x04
+# define PHY_AUX_ALIGN_ERR_MASK                                0x08
+# define PHY_AUX_REQ_ERR_MASK                          0x10
+
+#endif
index ab61a9c73b189eabffbbe64fc6889338a00091be..0442b31205638cdea16694e256c86e436a3186e6 100644 (file)
 #include <linux/reset.h>
 #include <linux/slab.h>
 
+#include "phy-qcom-qmp-common.h"
+
 #include "phy-qcom-qmp.h"
 
-/* QPHY_SW_RESET bit */
-#define SW_RESET                               BIT(0)
-/* QPHY_POWER_DOWN_CONTROL */
-#define SW_PWRDN                               BIT(0)
-#define REFCLK_DRV_DSBL                                BIT(1)
 /* QPHY_START_CONTROL bits */
-#define SERDES_START                           BIT(0)
-#define PCS_START                              BIT(1)
 #define PLL_READY_GATE_EN                      BIT(3)
-/* QPHY_PCS_STATUS bit */
-#define PHYSTATUS                              BIT(6)
+
 /* QPHY_COM_PCS_READY_STATUS bit */
 #define PCS_READY                              BIT(0)
 
 #define POWER_DOWN_DELAY_US_MIN                        10
 #define POWER_DOWN_DELAY_US_MAX                        20
 
-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 {
        /* Common block control registers */
@@ -307,32 +277,6 @@ static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
        .regs                   = pciephy_regs_layout,
 };
 
-static void qmp_pcie_msm8996_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_pcie_msm8996_configure(void __iomem *base,
-                                  const struct qmp_phy_init_tbl tbl[],
-                                  int num)
-{
-       qmp_pcie_msm8996_configure_lane(base, tbl, num, 0xff);
-}
-
 static int qmp_pcie_msm8996_serdes_init(struct qmp_phy *qphy)
 {
        struct qcom_qmp *qmp = qphy->qmp;
@@ -344,7 +288,7 @@ static int qmp_pcie_msm8996_serdes_init(struct qmp_phy *qphy)
        unsigned int val;
        int ret;
 
-       qmp_pcie_msm8996_configure(serdes, serdes_tbl, serdes_tbl_num);
+       qmp_configure(serdes, serdes_tbl, serdes_tbl_num);
 
        qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
        qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
@@ -487,9 +431,9 @@ static int qmp_pcie_msm8996_power_on(struct phy *phy)
        }
 
        /* Tx, Rx, and PCS configurations */
-       qmp_pcie_msm8996_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
-       qmp_pcie_msm8996_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
-       qmp_pcie_msm8996_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+       qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
+       qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
+       qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 
        /*
         * Pull out PHY from POWER DOWN state.
index 2af7115ef96891ea33443bbcbf823c3d3c03fafd..8836bb1ff0cc1ee31b7778b23f7a5c766091a67c 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/reset.h>
 #include <linux/slab.h>
 
+#include "phy-qcom-qmp-common.h"
+
 #include "phy-qcom-qmp.h"
 #include "phy-qcom-qmp-pcs-misc-v3.h"
 #include "phy-qcom-qmp-pcs-pcie-v4.h"
 #include "phy-qcom-qmp-pcs-pcie-v6_20.h"
 #include "phy-qcom-qmp-pcie-qhp.h"
 
-/* QPHY_SW_RESET bit */
-#define SW_RESET                               BIT(0)
-/* QPHY_POWER_DOWN_CONTROL */
-#define SW_PWRDN                               BIT(0)
-#define REFCLK_DRV_DSBL                                BIT(1)
-/* QPHY_START_CONTROL bits */
-#define SERDES_START                           BIT(0)
-#define PCS_START                              BIT(1)
-/* QPHY_PCS_STATUS bit */
-#define PHYSTATUS                              BIT(6)
-#define PHYSTATUS_4_20                         BIT(7)
-
 #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 */
@@ -116,6 +82,13 @@ static const unsigned int pciephy_v5_regs_layout[QPHY_LAYOUT_SIZE] = {
        [QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V5_PCS_POWER_DOWN_CONTROL,
 };
 
+static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
+       [QPHY_SW_RESET]                 = QPHY_V6_PCS_SW_RESET,
+       [QPHY_START_CTRL]               = QPHY_V6_PCS_START_CONTROL,
+       [QPHY_PCS_STATUS]               = QPHY_V6_PCS_PCS_STATUS1,
+       [QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V6_PCS_POWER_DOWN_CONTROL,
+};
+
 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
        QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -982,6 +955,143 @@ static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
        QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
 };
 
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_serdes_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x1a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0xd4),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x32),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_tx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1d),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x10),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_rx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_BKUP_CTRL1, 0x15),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_1, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_2, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0b),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0xb3),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x26),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0xe4),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xa4),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0x60),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x4b),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G3S2_PRE_GAIN, 0x2e),
+       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_RX_SIGDET_LVL, 0xcc),
+       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG4, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG5, 0x22),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG1, 0x16),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG5, 0x02),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN, 0x2e),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1, 0x03),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG3, 0x28),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_TX_RX_CONFIG, 0xc0),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_POWER_STATE_CONFIG2, 0x1d),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG5, 0x0f),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_FOM_EQ_CONFIG5, 0xf2),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0xf2),
+};
+
 static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
        QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -1747,7 +1857,7 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_rx_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH2, 0x5b),
        QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH3, 0x1a),
        QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH4, 0x89),
-       QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0xf0),
+       QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0x00),
        QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x09),
        QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x05),
        QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
@@ -1767,6 +1877,8 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_pcs_tbl[] = {
 };
 
 static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1, 0x1e),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
@@ -1823,10 +1935,9 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_serdes_tbl[] = {
 
 static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_ln_shrd_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
-       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_Q_EN_RATES, 0xe),
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x00),
-       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x00),
-       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d),
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
@@ -1843,6 +1954,7 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_ln_shrd_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
        QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b),
 };
 
 static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_tx_tbl[] = {
@@ -1855,13 +1967,15 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_tx_tbl[] = {
 };
 
 static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_rx_tbl[] = {
-       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x7c),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x05),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0a),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
@@ -1883,11 +1997,13 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_rx_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x78),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
        QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00),
 };
 
 static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_pcs_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
        QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G3S2_PRE_GAIN, 0x2e),
-       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_COM_ELECIDLE_DLY_SEL, 0x25),
+       QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_RX_SIGDET_LVL, 0xcc),
        QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG4, 0x00),
        QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG5, 0x22),
        QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_TX_RX_CONFIG1, 0x04),
@@ -1898,6 +2014,8 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS, 0x00),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG1, 0x16),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_RXEQEVAL_TIME, 0x27),
+       QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_RXEQEVAL_TIME, 0x27),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG5, 0x02),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN, 0x2e),
        QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1, 0x03),
@@ -2936,7 +3054,7 @@ static const struct qmp_phy_cfg sdx65_qmp_pciephy_cfg = {
        .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
-       .regs                   = pciephy_v5_regs_layout,
+       .regs                   = pciephy_v6_regs_layout,
 
        .pwrdn_ctrl             = SW_PWRDN,
        .phy_status             = PHYSTATUS_4_20,
@@ -3069,7 +3187,7 @@ static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {
        .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
        .vreg_list              = sm8550_qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
-       .regs                   = pciephy_v5_regs_layout,
+       .regs                   = pciephy_v6_regs_layout,
 
        .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
        .phy_status             = PHYSTATUS_4_20,
@@ -3099,7 +3217,7 @@ static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = {
        .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
        .vreg_list              = sm8550_qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
-       .regs                   = pciephy_v5_regs_layout,
+       .regs                   = pciephy_v6_regs_layout,
 
        .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
        .phy_status             = PHYSTATUS_4_20,
@@ -3183,31 +3301,35 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = {
        .phy_status             = PHYSTATUS_4_20,
 };
 
-static void qmp_pcie_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;
+static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = {
+       .lanes = 2,
 
-       for (i = 0; i < num; i++, t++) {
-               if (!(t->lane_mask & lane_mask))
-                       continue;
+       .offsets                = &qmp_pcie_offsets_v6_20,
 
-               writel(t->val, base + t->offset);
-       }
-}
+       .tbls = {
+               .serdes                 = x1e80100_qmp_gen4x2_pcie_serdes_tbl,
+               .serdes_num             = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_serdes_tbl),
+               .tx                     = x1e80100_qmp_gen4x2_pcie_tx_tbl,
+               .tx_num                 = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_tx_tbl),
+               .rx                     = x1e80100_qmp_gen4x2_pcie_rx_tbl,
+               .rx_num                 = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_rx_tbl),
+               .pcs                    = x1e80100_qmp_gen4x2_pcie_pcs_tbl,
+               .pcs_num                = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_pcs_tbl),
+               .pcs_misc               = x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl,
+               .pcs_misc_num           = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl),
+               .ln_shrd                = x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl,
+               .ln_shrd_num            = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl),
+       },
+       .reset_list             = sdm845_pciephy_reset_l,
+       .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
+       .vreg_list              = sm8550_qmp_phy_vreg_l,
+       .num_vregs              = ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
+       .regs                   = pciephy_v6_regs_layout,
 
-static void qmp_pcie_configure(void __iomem *base,
-                                       const struct qmp_phy_init_tbl tbl[],
-                                       int num)
-{
-       qmp_pcie_configure_lane(base, tbl, num, 0xff);
-}
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+       .phy_status             = PHYSTATUS_4_20,
+       .has_nocsr_reset        = true,
+};
 
 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
@@ -3220,11 +3342,11 @@ static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_
        tx4 = qmp->port_b + offs->tx2;
        rx4 = qmp->port_b + offs->rx2;
 
-       qmp_pcie_configure_lane(tx3, tbls->tx, tbls->tx_num, 1);
-       qmp_pcie_configure_lane(rx3, tbls->rx, tbls->rx_num, 1);
+       qmp_configure_lane(tx3, tbls->tx, tbls->tx_num, 1);
+       qmp_configure_lane(rx3, tbls->rx, tbls->rx_num, 1);
 
-       qmp_pcie_configure_lane(tx4, tbls->tx, tbls->tx_num, 2);
-       qmp_pcie_configure_lane(rx4, tbls->rx, tbls->rx_num, 2);
+       qmp_configure_lane(tx4, tbls->tx, tbls->tx_num, 2);
+       qmp_configure_lane(rx4, tbls->rx, tbls->rx_num, 2);
 }
 
 static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
@@ -3242,25 +3364,25 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
        if (!tbls)
                return;
 
-       qmp_pcie_configure(serdes, tbls->serdes, tbls->serdes_num);
+       qmp_configure(serdes, tbls->serdes, tbls->serdes_num);
 
-       qmp_pcie_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
-       qmp_pcie_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
+       qmp_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
+       qmp_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
 
        if (cfg->lanes >= 2) {
-               qmp_pcie_configure_lane(tx2, tbls->tx, tbls->tx_num, 2);
-               qmp_pcie_configure_lane(rx2, tbls->rx, tbls->rx_num, 2);
+               qmp_configure_lane(tx2, tbls->tx, tbls->tx_num, 2);
+               qmp_configure_lane(rx2, tbls->rx, tbls->rx_num, 2);
        }
 
-       qmp_pcie_configure(pcs, tbls->pcs, tbls->pcs_num);
-       qmp_pcie_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
+       qmp_configure(pcs, tbls->pcs, tbls->pcs_num);
+       qmp_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
 
        if (cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
-               qmp_pcie_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
+               qmp_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
                qmp_pcie_init_port_b(qmp, tbls);
        }
 
-       qmp_pcie_configure(ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
+       qmp_configure(ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
 }
 
 static int qmp_pcie_init(struct phy *phy)
@@ -3885,6 +4007,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
        }, {
                .compatible = "qcom,sm8650-qmp-gen4x2-pcie-phy",
                .data = &sm8650_qmp_gen4x2_pciephy_cfg,
+       }, {
+               .compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy",
+               .data = &sm8550_qmp_gen3x2_pciephy_cfg,
+       }, {
+               .compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy",
+               .data = &x1e80100_qmp_gen4x2_pciephy_cfg,
        },
        { },
 };
index 91e70002eb4777a2b0089f0f53787a8d32ef49f9..0ca79333d94261610f7274968c96362dcfb1f354 100644 (file)
@@ -7,6 +7,8 @@
 #define QCOM_PHY_QMP_PCS_PCIE_V6_H_
 
 /* Only for QMP V6 PHY - PCIE have different offsets than V5 */
+#define QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1               0xa4
+#define QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME            0xf4
 #define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2      0x0c
 #define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4      0x14
 #define QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE    0x20
index e3eb08776339d1d6d3bb6ea95259ceb20947bee3..dfcecf31a6060981b912646fcdf5db83906f5835 100644 (file)
@@ -12,6 +12,8 @@
 #define QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE      0x01c
 #define QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS           0x090
 #define QPHY_PCIE_V6_20_PCS_EQ_CONFIG1                 0x0a0
+#define QPHY_PCIE_V6_20_PCS_G3_RXEQEVAL_TIME           0x0f0
+#define QPHY_PCIE_V6_20_PCS_G4_RXEQEVAL_TIME           0x0f4
 #define QPHY_PCIE_V6_20_PCS_EQ_CONFIG5                 0x108
 #define QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN                        0x15c
 #define QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1       0x17c
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
new file mode 100644 (file)
index 0000000..4d8c962
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_SGMII_H_
+#define QCOM_PHY_QMP_PCS_SGMII_H_
+
+#define QPHY_PCS_PHY_START                             0x000
+#define QPHY_PCS_POWER_DOWN_CONTROL                    0x004
+#define QPHY_PCS_SW_RESET                              0x008
+#define QPHY_PCS_LINE_RESET_TIME                       0x00c
+#define QPHY_PCS_TX_LARGE_AMP_DRV_LVL                  0x020
+#define QPHY_PCS_TX_SMALL_AMP_DRV_LVL                  0x028
+#define QPHY_PCS_PCS_READY_STATUS                      0x094
+#define QPHY_PCS_TX_MID_TERM_CTRL1                     0x0d8
+#define QPHY_PCS_TX_MID_TERM_CTRL2                     0x0dc
+#define QPHY_PCS_SGMII_MISC_CTRL8                      0x118
+
+#endif
index fe6c450f612382b281ccceab453a086373a27ab0..970cc0667809465d83ba881f771c2f270c0cabac 100644 (file)
@@ -19,6 +19,7 @@
 #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
 #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
 #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
+#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
 #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
 #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
 #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
@@ -28,5 +29,6 @@
 #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
 #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
 #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
+#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
 
 #endif
index 9c3f1e4950e6ba4dffeaddb5c50e24df2f3cbe90..4d9615cc0383cee27f312cbb39771d7ae79f71bb 100644 (file)
@@ -7,6 +7,7 @@
 #define QCOM_PHY_QMP_PCS_V6_20_H_
 
 /* Only for QMP V6_20 PHY - USB/PCIe PCS registers */
+#define QPHY_V6_20_PCS_G12S1_TXDEEMPH_M6DB             0x170
 #define QPHY_V6_20_PCS_G3S2_PRE_GAIN                   0x178
 #define QPHY_V6_20_PCS_RX_SIGDET_LVL                   0x190
 #define QPHY_V6_20_PCS_COM_ELECIDLE_DLY_SEL            0x1b8
index ec7291424dd1f1bb7f706bbb5b77419f76d0bfda..328c6c0b0b09ae4ff5bf14e846772e6d0f31ce5a 100644 (file)
@@ -60,6 +60,8 @@
 #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
 #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
 #define QSERDES_V6_COM_PLL_IVCO_MODE1                          0xf8
+#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
+#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
 #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
 #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
 #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
index 35d497fd9f9a4420e8c02ae8dd91de011c94c14a..d9a87bd95590811de5484e084d4fea1872b22bcb 100644 (file)
 
 #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
 #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
 #define QSERDES_UFS_V6_RX_UCDR_SO_SATURATION                   0x28
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
 #define QSERDES_UFS_V6_RX_UCDR_PI_CTRL1                                0x58
 #define QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0                     0xc4
 #define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
 #define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
+#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
+#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
 #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
+#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
 #define QSERDES_UFS_V6_RX_INTERFACE_MODE                       0x1e0
+#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
@@ -33,6 +39,8 @@
 #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
 #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
 #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
 #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
+#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
 
 #endif
index 6ed5339fd2ea86dd4a69df077887ea9a0713dcdd..7bac5d5c6c34485bdb357bf3a3caa7658ba07aa0 100644 (file)
@@ -23,6 +23,8 @@
 #define QSERDES_V6_20_RX_DFE_1                                 0xac
 #define QSERDES_V6_20_RX_DFE_2                                 0xb0
 #define QSERDES_V6_20_RX_DFE_3                                 0xb4
+#define QSERDES_V6_20_RX_TX_ADPT_CTRL                          0xd4
+#define QSERDES_V6_20_VGA_CAL_CNTRL1                           0xe0
 #define QSERDES_V6_20_RX_VGA_CAL_MAN_VAL                       0xe8
 #define QSERDES_V6_20_RX_GM_CAL                                        0x10c
 #define QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4                    0x120
index 3c2e6255e26f66d21fec72595c680e5c2cccc9c4..590432d581f97ded35047cd62695f7a72e76dc4e 100644 (file)
@@ -20,6 +20,9 @@
 #include <linux/slab.h>
 
 #include <ufs/unipro.h>
+
+#include "phy-qcom-qmp-common.h"
+
 #include "phy-qcom-qmp.h"
 #include "phy-qcom-qmp-pcs-ufs-v2.h"
 #include "phy-qcom-qmp-pcs-ufs-v3.h"
 
 #include "phy-qcom-qmp-qserdes-txrx-ufs-v6.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_READY_STATUS bit */
 #define PCS_READY                              BIT(0)
 
 #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,         \
-       }
+#define NUM_OVERLAY                            2
 
 /* set of registers with offsets different per-PHY */
 enum qphy_reg_layout {
@@ -754,15 +728,22 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
-       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
-       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
-       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
@@ -771,19 +752,24 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
 };
 
-static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
-       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
+       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
 };
 
 static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
 };
 
 static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
-       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
 
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
@@ -799,16 +785,45 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
        QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
 };
 
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
+};
+
 static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
        QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
        QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
        QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
-       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
        QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
+       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
        QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
        QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
 };
 
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
+       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
+       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
+       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
+};
+
 static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = {
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
        QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
@@ -889,6 +904,8 @@ struct qmp_phy_cfg_tbls {
        int rx_num;
        const struct qmp_phy_init_tbl *pcs;
        int pcs_num;
+       /* Maximum supported Gear of this tbls */
+       u32 max_gear;
 };
 
 /* struct qmp_phy_cfg - per-PHY initialization config */
@@ -896,17 +913,16 @@ struct qmp_phy_cfg {
        int lanes;
 
        const struct qmp_ufs_offsets *offsets;
+       /* Maximum supported Gear of this config */
+       u32 max_supported_gear;
 
        /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
        const struct qmp_phy_cfg_tbls tbls;
        /* Additional sequence for HS Series B */
        const struct qmp_phy_cfg_tbls tbls_hs_b;
-       /* Additional sequence for HS G4 */
-       const struct qmp_phy_cfg_tbls tbls_hs_g4;
+       /* Additional sequence for different HS Gears */
+       const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY];
 
-       /* clock ids to be requested */
-       const char * const *clk_list;
-       int num_clks;
        /* regulators to be requested */
        const char * const *vreg_list;
        int num_vregs;
@@ -932,6 +948,7 @@ struct qmp_ufs {
        void __iomem *rx2;
 
        struct clk_bulk_data *clks;
+       int num_clks;
        struct regulator_bulk_data *vregs;
        struct reset_control *ufs_reset;
 
@@ -964,20 +981,6 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
        readl(base + offset);
 }
 
-/* list of clocks required by phy */
-static const char * const msm8996_ufs_phy_clk_l[] = {
-       "ref",
-};
-
-/* the primary usb3 phy on sm8250 doesn't have a ref clock */
-static const char * const sm8450_ufs_phy_clk_l[] = {
-       "qref", "ref", "ref_aux",
-};
-
-static const char * const sdm845_ufs_phy_clk_l[] = {
-       "ref", "ref_aux",
-};
-
 /* list of regulators */
 static const char * const qmp_phy_vreg_l[] = {
        "vdda-phy", "vdda-pll",
@@ -1005,6 +1008,7 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
        .lanes                  = 1,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G3,
 
        .tbls = {
                .serdes         = msm8996_ufsphy_serdes,
@@ -1015,9 +1019,6 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
                .rx_num         = ARRAY_SIZE(msm8996_ufsphy_rx),
        },
 
-       .clk_list               = msm8996_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
-
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
 
@@ -1030,6 +1031,7 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8350_ufsphy_serdes,
@@ -1045,16 +1047,15 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {
                .serdes         = sm8350_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8350_ufsphy_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
                .rx             = sm8350_ufsphy_g4_rx,
                .rx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
                .pcs            = sm8350_ufsphy_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sm8450_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v5_regs_layout,
@@ -1064,6 +1065,7 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8150_ufsphy_serdes,
@@ -1079,16 +1081,15 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {
                .serdes         = sm8150_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8250_ufsphy_hs_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
                .rx             = sc7280_ufsphy_hs_g4_rx,
                .rx_num         = ARRAY_SIZE(sc7280_ufsphy_hs_g4_rx),
                .pcs            = sm8150_ufsphy_hs_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sm8450_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v4_regs_layout,
@@ -1098,6 +1099,7 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8350_ufsphy_serdes,
@@ -1113,16 +1115,15 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
                .serdes         = sm8350_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8350_ufsphy_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
                .rx             = sm8350_ufsphy_g4_rx,
                .rx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
                .pcs            = sm8350_ufsphy_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v5_regs_layout,
@@ -1132,6 +1133,7 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G3,
 
        .tbls = {
                .serdes         = sdm845_ufsphy_serdes,
@@ -1147,8 +1149,6 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
                .serdes         = sdm845_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v3_regs_layout,
@@ -1160,6 +1160,7 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
        .lanes                  = 1,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G3,
 
        .tbls = {
                .serdes         = sm6115_ufsphy_serdes,
@@ -1175,8 +1176,6 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
                .serdes         = sm6115_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v2_regs_layout,
@@ -1188,6 +1187,7 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {
        .lanes                  = 1,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G3,
 
        .tbls = {
                .serdes         = sdm845_ufsphy_serdes,
@@ -1203,8 +1203,6 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {
                .serdes         = sdm845_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v3_regs_layout,
@@ -1216,6 +1214,7 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8150_ufsphy_serdes,
@@ -1231,16 +1230,15 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
                .serdes         = sm8150_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8150_ufsphy_hs_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8150_ufsphy_hs_g4_tx),
                .rx             = sm8150_ufsphy_hs_g4_rx,
                .rx_num         = ARRAY_SIZE(sm8150_ufsphy_hs_g4_rx),
                .pcs            = sm8150_ufsphy_hs_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v4_regs_layout,
@@ -1250,6 +1248,7 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8150_ufsphy_serdes,
@@ -1265,16 +1264,15 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {
                .serdes         = sm8150_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8250_ufsphy_hs_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
                .rx             = sm8250_ufsphy_hs_g4_rx,
                .rx_num         = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),
                .pcs            = sm8150_ufsphy_hs_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v4_regs_layout,
@@ -1284,6 +1282,7 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8350_ufsphy_serdes,
@@ -1299,16 +1298,15 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
                .serdes         = sm8350_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8350_ufsphy_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
                .rx             = sm8350_ufsphy_g4_rx,
                .rx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
                .pcs            = sm8350_ufsphy_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v5_regs_layout,
@@ -1318,6 +1316,7 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets,
+       .max_supported_gear     = UFS_HS_G4,
 
        .tbls = {
                .serdes         = sm8350_ufsphy_serdes,
@@ -1333,16 +1332,15 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
                .serdes         = sm8350_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
        },
-       .tbls_hs_g4 = {
+       .tbls_hs_overlay[0] = {
                .tx             = sm8350_ufsphy_g4_tx,
                .tx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
                .rx             = sm8350_ufsphy_g4_rx,
                .rx_num         = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
                .pcs            = sm8350_ufsphy_g4_pcs,
                .pcs_num        = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+               .max_gear       = UFS_HS_G4,
        },
-       .clk_list               = sm8450_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v5_regs_layout,
@@ -1352,6 +1350,7 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets_v6,
+       .max_supported_gear     = UFS_HS_G5,
 
        .tbls = {
                .serdes         = sm8550_ufsphy_serdes,
@@ -1367,8 +1366,26 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
                .serdes         = sm8550_ufsphy_hs_b_serdes,
                .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+       .tbls_hs_overlay[0] = {
+               .serdes         = sm8550_ufsphy_g4_serdes,
+               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
+               .tx             = sm8550_ufsphy_g4_tx,
+               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
+               .rx             = sm8550_ufsphy_g4_rx,
+               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
+               .pcs            = sm8550_ufsphy_g4_pcs,
+               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
+               .max_gear       = UFS_HS_G4,
+       },
+       .tbls_hs_overlay[1] = {
+               .serdes         = sm8550_ufsphy_g5_serdes,
+               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
+               .rx             = sm8550_ufsphy_g5_rx,
+               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
+               .pcs            = sm8550_ufsphy_g5_pcs,
+               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
+               .max_gear       = UFS_HS_G5,
+       },
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v6_regs_layout,
@@ -1378,6 +1395,7 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
        .lanes                  = 2,
 
        .offsets                = &qmp_ufs_offsets_v6,
+       .max_supported_gear     = UFS_HS_G5,
 
        .tbls = {
                .serdes         = sm8650_ufsphy_serdes,
@@ -1389,44 +1407,16 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
                .pcs            = sm8650_ufsphy_pcs,
                .pcs_num        = ARRAY_SIZE(sm8650_ufsphy_pcs),
        },
-       .clk_list               = sdm845_ufs_phy_clk_l,
-       .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
        .vreg_list              = qmp_phy_vreg_l,
        .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
        .regs                   = ufsphy_v6_regs_layout,
 };
 
-static void qmp_ufs_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_ufs_configure(void __iomem *base,
-                                  const struct qmp_phy_init_tbl tbl[],
-                                  int num)
-{
-       qmp_ufs_configure_lane(base, tbl, num, 0xff);
-}
-
 static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
        void __iomem *serdes = qmp->serdes;
 
-       qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);
+       qmp_configure(serdes, tbls->serdes, tbls->serdes_num);
 }
 
 static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
@@ -1435,12 +1425,12 @@ static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbl
        void __iomem *tx = qmp->tx;
        void __iomem *rx = qmp->rx;
 
-       qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
-       qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
+       qmp_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
+       qmp_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
 
        if (cfg->lanes >= 2) {
-               qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
-               qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
+               qmp_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
+               qmp_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
        }
 }
 
@@ -1448,20 +1438,52 @@ static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls
 {
        void __iomem *pcs = qmp->pcs;
 
-       qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);
+       qmp_configure(pcs, tbls->pcs, tbls->pcs_num);
+}
+
+static int qmp_ufs_get_gear_overlay(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
+{
+       u32 max_gear, floor_max_gear = cfg->max_supported_gear;
+       int idx, ret = -EINVAL;
+
+       for (idx = NUM_OVERLAY - 1; idx >= 0; idx--) {
+               max_gear = cfg->tbls_hs_overlay[idx].max_gear;
+
+               /* Skip if the table is not available */
+               if (max_gear == 0)
+                       continue;
+
+               /* Direct matching, bail */
+               if (qmp->submode == max_gear)
+                       return idx;
+
+               /* If no direct matching, the lowest gear is the best matching */
+               if (max_gear < floor_max_gear) {
+                       ret = idx;
+                       floor_max_gear = max_gear;
+               }
+       }
+
+       return ret;
 }
 
 static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
 {
+       int i;
+
        qmp_ufs_serdes_init(qmp, &cfg->tbls);
-       if (qmp->mode == PHY_MODE_UFS_HS_B)
-               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
        qmp_ufs_lanes_init(qmp, &cfg->tbls);
-       if (qmp->submode == UFS_HS_G4)
-               qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4);
        qmp_ufs_pcs_init(qmp, &cfg->tbls);
-       if (qmp->submode == UFS_HS_G4)
-               qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4);
+
+       i = qmp_ufs_get_gear_overlay(qmp, cfg);
+       if (i >= 0) {
+               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_overlay[i]);
+               qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_overlay[i]);
+               qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_overlay[i]);
+       }
+
+       if (qmp->mode == PHY_MODE_UFS_HS_B)
+               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
 }
 
 static int qmp_ufs_com_init(struct qmp_ufs *qmp)
@@ -1476,7 +1498,7 @@ static int qmp_ufs_com_init(struct qmp_ufs *qmp)
                return ret;
        }
 
-       ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+       ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
        if (ret)
                goto err_disable_regulators;
 
@@ -1496,7 +1518,7 @@ static int qmp_ufs_com_exit(struct qmp_ufs *qmp)
 
        reset_control_assert(qmp->ufs_reset);
 
-       clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+       clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
 
        regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 
@@ -1633,6 +1655,12 @@ static int qmp_ufs_disable(struct phy *phy)
 static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 {
        struct qmp_ufs *qmp = phy_get_drvdata(phy);
+       const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+       if (submode > cfg->max_supported_gear || submode == 0) {
+               dev_err(qmp->dev, "Invalid PHY submode %d\n", submode);
+               return -EINVAL;
+       }
 
        qmp->mode = mode;
        qmp->submode = submode;
@@ -1666,19 +1694,13 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
 
 static int qmp_ufs_clk_init(struct qmp_ufs *qmp)
 {
-       const struct qmp_phy_cfg *cfg = qmp->cfg;
        struct device *dev = qmp->dev;
-       int num = cfg->num_clks;
-       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 = cfg->clk_list[i];
+       qmp->num_clks = devm_clk_bulk_get_all(dev, &qmp->clks);
+       if (qmp->num_clks < 0)
+               return qmp->num_clks;
 
-       return devm_clk_bulk_get(dev, num, qmp->clks);
+       return 0;
 }
 
 static void qmp_ufs_clk_release_provider(void *res)
@@ -1880,6 +1902,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
        }, {
                .compatible = "qcom,sa8775p-qmp-ufs-phy",
                .data = &sa8775p_ufsphy_cfg,
+       }, {
+               .compatible = "qcom,sc7180-qmp-ufs-phy",
+               .data = &sm7150_ufsphy_cfg,
        }, {
                .compatible = "qcom,sc7280-qmp-ufs-phy",
                .data = &sc7280_ufsphy_cfg,
index cf466f6df94d7a62ab48c90beeaee4295bad677e..6d0ba39c19431e103f0c92d24b79615bdc7d1828 100644 (file)
 #include "phy-qcom-qmp-pcs-usb-v4.h"
 #include "phy-qcom-qmp-pcs-usb-v5.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)
+#include "phy-qcom-qmp-dp-com-v3.h"
 
 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
 /* DP PHY soft reset */
 #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 {
@@ -507,8 +488,6 @@ struct qmp_usb_legacy_offsets {
 
 /* struct qmp_phy_cfg - per-PHY initialization config */
 struct qmp_phy_cfg {
-       int lanes;
-
        const struct qmp_usb_legacy_offsets *offsets;
 
        /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
@@ -621,8 +600,6 @@ static const char * const qmp_phy_vreg_l[] = {
 };
 
 static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
-       .lanes                  = 2,
-
        .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
        .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
        .tx_tbl                 = qmp_v3_usb3_tx_tbl,
@@ -641,8 +618,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
-       .lanes                  = 2,
-
        .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
        .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
        .tx_tbl                 = qmp_v3_usb3_tx_tbl,
@@ -661,8 +636,6 @@ static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
-       .lanes                  = 2,
-
        .serdes_tbl             = sm8150_usb3_serdes_tbl,
        .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
        .tx_tbl                 = sm8150_usb3_tx_tbl,
@@ -684,8 +657,6 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
-       .lanes                  = 2,
-
        .serdes_tbl             = sm8150_usb3_serdes_tbl,
        .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
        .tx_tbl                 = sm8250_usb3_tx_tbl,
@@ -707,8 +678,6 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
-       .lanes                  = 2,
-
        .serdes_tbl             = sm8150_usb3_serdes_tbl,
        .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
        .tx_tbl                 = sm8350_usb3_tx_tbl,
@@ -874,10 +843,8 @@ static int qmp_usb_legacy_power_on(struct phy *phy)
        qmp_usb_legacy_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
        qmp_usb_legacy_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
 
-       if (cfg->lanes >= 2) {
-               qmp_usb_legacy_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
-               qmp_usb_legacy_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
-       }
+       qmp_usb_legacy_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
+       qmp_usb_legacy_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
 
        qmp_usb_legacy_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 
@@ -1180,27 +1147,11 @@ static int phy_pipe_clk_register(struct qmp_usb *qmp, struct device_node *np)
        return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
 }
 
-static void __iomem *qmp_usb_legacy_iomap(struct device *dev, struct device_node *np,
-                                       int index, bool exclusive)
-{
-       struct resource res;
-
-       if (!exclusive) {
-               if (of_address_to_resource(np, index, &res))
-                       return IOMEM_ERR_PTR(-EINVAL);
-
-               return devm_ioremap(dev, res.start, resource_size(&res));
-       }
-
-       return devm_of_iomap(dev, np, index, NULL);
-}
-
 static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb *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;
-       bool exclusive = true;
 
        qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(qmp->serdes))
@@ -1224,27 +1175,22 @@ static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb *qmp, struct device_nod
        if (IS_ERR(qmp->rx))
                return PTR_ERR(qmp->rx);
 
-       qmp->pcs = qmp_usb_legacy_iomap(dev, np, 2, exclusive);
+       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->tx2 = devm_of_iomap(dev, np, 3, NULL);
+       if (IS_ERR(qmp->tx2))
+               return PTR_ERR(qmp->tx2);
 
-               qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
-       } else {
-               qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
-       }
+       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);
        if (IS_ERR(qmp->pcs_misc)) {
                dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
                qmp->pcs_misc = NULL;
index 5c003988c35d38cead7cc6b3e1e2af04a07bdb28..85253936fac352a5189d7b5fa89535ba264b5686 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/reset.h>
 #include <linux/slab.h>
 
+#include "phy-qcom-qmp-common.h"
+
 #include "phy-qcom-qmp.h"
 #include "phy-qcom-qmp-pcs-misc-v3.h"
 #include "phy-qcom-qmp-pcs-misc-v4.h"
 #include "phy-qcom-qmp-pcs-usb-v6.h"
 #include "phy-qcom-qmp-pcs-usb-v7.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 */
@@ -121,15 +64,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 +448,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 +914,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),
@@ -1448,15 +1180,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 */
@@ -1496,8 +1223,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;
@@ -1579,16 +1304,6 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v3_msm8996 = {
        .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,
@@ -1622,8 +1337,6 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v7 = {
 };
 
 static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = {
-       .lanes                  = 1,
-
        .offsets                = &qmp_usb_offsets_v3,
 
        .serdes_tbl             = ipq9574_usb3_serdes_tbl,
@@ -1640,8 +1353,6 @@ static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = {
 };
 
 static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
-       .lanes                  = 1,
-
        .offsets                = &qmp_usb_offsets_v3,
 
        .serdes_tbl             = ipq8074_usb3_serdes_tbl,
@@ -1658,8 +1369,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,
@@ -1676,8 +1385,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_msm8996,
 
        .serdes_tbl             = msm8996_usb3_serdes_tbl,
@@ -1694,8 +1401,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,
@@ -1714,8 +1419,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,
@@ -1734,8 +1437,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,
@@ -1753,27 +1454,7 @@ 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,
-
        .offsets                = &qmp_usb_offsets_v4,
 
        .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
@@ -1795,8 +1476,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,
@@ -1818,8 +1497,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,
@@ -1841,8 +1518,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,
@@ -1864,7 +1539,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,
@@ -1886,8 +1560,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,
@@ -1908,27 +1580,7 @@ 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,
-
        .offsets                = &qmp_usb_offsets_v7,
 
        .serdes_tbl             = x1e80100_usb3_uniphy_serdes_tbl,
@@ -1946,32 +1598,6 @@ static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = {
        .regs                   = qmp_v7_usb3phy_regs_layout,
 };
 
-static void qmp_usb_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_usb_configure(void __iomem *base,
-                                  const struct qmp_phy_init_tbl tbl[],
-                                  int num)
-{
-       qmp_usb_configure_lane(base, tbl, num, 0xff);
-}
-
 static int qmp_usb_serdes_init(struct qmp_usb *qmp)
 {
        const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -1979,7 +1605,7 @@ static int qmp_usb_serdes_init(struct qmp_usb *qmp)
        const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
        int serdes_tbl_num = cfg->serdes_tbl_num;
 
-       qmp_usb_configure(serdes, serdes_tbl, serdes_tbl_num);
+       qmp_configure(serdes, serdes_tbl, serdes_tbl_num);
 
        return 0;
 }
@@ -2060,18 +1686,13 @@ static int qmp_usb_power_on(struct phy *phy)
        }
 
        /* Tx, Rx, and PCS configurations */
-       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_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
+       qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
 
-       qmp_usb_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+       qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 
        if (pcs_usb)
-               qmp_usb_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
+               qmp_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
 
        if (cfg->has_pwrdn_delay)
                usleep_range(10, 20);
@@ -2414,7 +2035,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);
@@ -2432,19 +2052,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");
@@ -2496,11 +2104,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;
@@ -2599,12 +2202,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,
@@ -2623,9 +2220,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 (file)
index 0000000..5cbc5fd
--- /dev/null
@@ -0,0 +1,1149 @@
+// 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/mfd/syscon.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/regmap.h>
+#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-common.h"
+
+#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-misc-v3.h"
+
+#define PHY_INIT_COMPLETE_TIMEOUT              10000
+
+/* 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,
+       /* 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,
+};
+
+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),
+};
+
+/* the only difference is QSERDES_V3_RX_UCDR_PI_CONTROLS */
+static const struct qmp_phy_init_tbl sdm660_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, 0x00),
+       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 tx;
+       u16 rx;
+       /* for PHYs with >= 2 lanes */
+       u16 tx2;
+       u16 rx2;
+};
+
+/* struct qmp_phy_cfg - per-PHY initialization config */
+struct qmp_phy_cfg {
+       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;
+
+       /* regulators to be requested */
+       const char * const *vreg_list;
+       int num_vregs;
+
+       /* array of registers with different offsets */
+       const unsigned int *regs;
+};
+
+struct qmp_usbc {
+       struct device *dev;
+
+       const struct qmp_phy_cfg *cfg;
+
+       void __iomem *serdes;
+       void __iomem *pcs;
+       void __iomem *pcs_misc;
+       void __iomem *tx;
+       void __iomem *rx;
+       void __iomem *tx2;
+       void __iomem *rx2;
+
+       struct regmap *tcsr_map;
+       u32 vls_clamp_reg;
+
+       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;
+
+       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)
+{
+       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 = {
+       .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 = {
+       .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 const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
+       .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                 = sdm660_usb3_rx_tbl,
+       .rx_tbl_num             = ARRAY_SIZE(sdm660_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 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);
+       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);
+
+#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:
+       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 *status;
+       unsigned int val;
+       int ret;
+
+       qmp_configure(qmp->serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
+
+       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_configure_lane(qmp->tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
+       qmp_configure_lane(qmp->rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
+
+       qmp_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
+       qmp_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
+
+       qmp_configure(qmp->pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+
+       /* Pull PHY out of reset state */
+       qphy_clrbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+
+       /* start SerDes and Phy-Coding-Sublayer */
+       qphy_setbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START);
+
+       status = qmp->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)
+{
+       struct qmp_usbc *qmp = phy_get_drvdata(phy);
+       int ret;
+
+       mutex_lock(&qmp->phy_mutex);
+
+       ret = qmp_usbc_init(phy);
+       if (ret)
+               goto out_unlock;
+
+       ret = qmp_usbc_power_on(phy);
+       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;
+       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 = qmp->pcs;
+       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, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+       /* Writing 1 followed by 0 clears the interrupt */
+       qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+
+       qphy_clrbits(pcs, 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, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
+
+       /* Enable i/o clamp_n for autonomous mode */
+       if (qmp->tcsr_map && qmp->vls_clamp_reg)
+               regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 1);
+}
+
+static void qmp_usbc_disable_autonomous_mode(struct qmp_usbc *qmp)
+{
+       const struct qmp_phy_cfg *cfg = qmp->cfg;
+       void __iomem *pcs = qmp->pcs;
+
+       /* Disable i/o clamp_n on resume for normal mode */
+       if (qmp->tcsr_map && qmp->vls_clamp_reg)
+               regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 0);
+
+       qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
+                    ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
+
+       qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+       /* Writing 1 followed by 0 clears the interrupt */
+       qphy_clrbits(pcs, 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);
+}
+
+#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);
+       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);
+
+       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);
+       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_misc)
+               qmp->pcs_misc = base + offs->pcs_misc;
+       qmp->tx = base + offs->tx;
+       qmp->rx = base + offs->rx;
+
+       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_parse_vls_clamp(struct qmp_usbc *qmp)
+{
+       struct of_phandle_args tcsr_args;
+       struct device *dev = qmp->dev;
+       int ret;
+
+       /*  for backwards compatibility ignore if there is no property */
+       ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0,
+                                              &tcsr_args);
+       if (ret == -ENOENT)
+               return 0;
+       else if (ret < 0)
+               return dev_err_probe(dev, ret, "Failed to parse qcom,tcsr-reg\n");
+
+       qmp->tcsr_map = syscon_node_to_regmap(tcsr_args.np);
+       of_node_put(tcsr_args.np);
+       if (IS_ERR(qmp->tcsr_map))
+               return PTR_ERR(qmp->tcsr_map);
+
+       qmp->vls_clamp_reg = tcsr_args.args[0];
+
+       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->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;
+
+       ret = qmp_usbc_parse_vls_clamp(qmp);
+       if (ret)
+               return ret;
+
+       /* Check for legacy binding with child node. */
+       np = of_get_child_by_name(dev->of_node, "phy");
+       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,sdm660-qmp-usb3-phy",
+               .data = &sdm660_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");
index 6923496cbfee21c2bef6d1fa342254f806dc26fd..d10b8f653c4b2395250917ce301c3aba003b71ad 100644 (file)
 
 #include "phy-qcom-qmp-pcs-v7.h"
 
-/* Only for QMP V3 & V4 PHY - DP COM registers */
-#define QPHY_V3_DP_COM_PHY_MODE_CTRL                   0x00
-#define QPHY_V3_DP_COM_SW_RESET                                0x04
-#define QPHY_V3_DP_COM_POWER_DOWN_CTRL                 0x08
-#define QPHY_V3_DP_COM_SWI_CTRL                                0x0c
-#define QPHY_V3_DP_COM_TYPEC_CTRL                      0x10
-#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL                        0x14
-#define QPHY_V3_DP_COM_RESET_OVRD_CTRL                 0x1c
-
-/* QSERDES V3 COM bits */
-# define QSERDES_V3_COM_BIAS_EN                                0x0001
-# define QSERDES_V3_COM_BIAS_EN_MUX                    0x0002
-# define QSERDES_V3_COM_CLKBUF_R_EN                    0x0004
-# define QSERDES_V3_COM_CLKBUF_L_EN                    0x0008
-# define QSERDES_V3_COM_EN_SYSCLK_TX_SEL               0x0010
-# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L              0x0020
-# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R              0x0040
-
-/* QSERDES V3 TX bits */
-# define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK              0x001f
-# define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN            0x0020
-# define DP_PHY_TXn_TX_DRV_LVL_MASK                    0x001f
-# define DP_PHY_TXn_TX_DRV_LVL_MUX_EN                  0x0020
-
-/* QMP PHY - DP PHY registers */
-#define QSERDES_DP_PHY_REVISION_ID0                    0x000
-#define QSERDES_DP_PHY_REVISION_ID1                    0x004
-#define QSERDES_DP_PHY_REVISION_ID2                    0x008
-#define QSERDES_DP_PHY_REVISION_ID3                    0x00c
-#define QSERDES_DP_PHY_CFG                             0x010
-#define QSERDES_DP_PHY_PD_CTL                          0x018
-# define DP_PHY_PD_CTL_PWRDN                           0x001
-# define DP_PHY_PD_CTL_PSR_PWRDN                       0x002
-# define DP_PHY_PD_CTL_AUX_PWRDN                       0x004
-# define DP_PHY_PD_CTL_LANE_0_1_PWRDN                  0x008
-# define DP_PHY_PD_CTL_LANE_2_3_PWRDN                  0x010
-# define DP_PHY_PD_CTL_PLL_PWRDN                       0x020
-# define DP_PHY_PD_CTL_DP_CLAMP_EN                     0x040
-#define QSERDES_DP_PHY_MODE                            0x01c
-#define QSERDES_DP_PHY_AUX_CFG0                                0x020
-#define QSERDES_DP_PHY_AUX_CFG1                                0x024
-#define QSERDES_DP_PHY_AUX_CFG2                                0x028
-#define QSERDES_DP_PHY_AUX_CFG3                                0x02c
-#define QSERDES_DP_PHY_AUX_CFG4                                0x030
-#define QSERDES_DP_PHY_AUX_CFG5                                0x034
-#define QSERDES_DP_PHY_AUX_CFG6                                0x038
-#define QSERDES_DP_PHY_AUX_CFG7                                0x03c
-#define QSERDES_DP_PHY_AUX_CFG8                                0x040
-#define QSERDES_DP_PHY_AUX_CFG9                                0x044
-
-/* Only for QMP V3 PHY - DP PHY registers */
-#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK           0x048
-# define PHY_AUX_STOP_ERR_MASK                         0x01
-# define PHY_AUX_DEC_ERR_MASK                          0x02
-# define PHY_AUX_SYNC_ERR_MASK                         0x04
-# define PHY_AUX_ALIGN_ERR_MASK                                0x08
-# define PHY_AUX_REQ_ERR_MASK                          0x10
-
-#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR          0x04c
-#define QSERDES_V3_DP_PHY_AUX_BIST_CFG                 0x050
-
-#define QSERDES_V3_DP_PHY_VCO_DIV                      0x064
-#define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL             0x06c
-#define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL             0x088
-
-#define QSERDES_V3_DP_PHY_SPARE0                       0x0ac
-#define DP_PHY_SPARE0_MASK                             0x0f
-#define DP_PHY_SPARE0_ORIENTATION_INFO_SHIFT           0x04(0x0004)
-
-#define QSERDES_V3_DP_PHY_STATUS                       0x0c0
-
-/* Only for QMP V4 PHY - DP PHY registers */
-#define QSERDES_V4_DP_PHY_CFG_1                                0x014
-#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK           0x054
-#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR          0x058
-#define QSERDES_V4_DP_PHY_VCO_DIV                      0x070
-#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL             0x078
-#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL             0x09c
-#define QSERDES_V4_DP_PHY_SPARE0                       0x0c8
-#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS         0x0d8
-#define QSERDES_V4_DP_PHY_STATUS                       0x0dc
-
-#define QSERDES_V5_DP_PHY_STATUS                       0x0dc
-
-/* Only for QMP V6 PHY - DP PHY registers */
-#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS         0x0e0
-#define QSERDES_V6_DP_PHY_STATUS                       0x0e4
+/* QPHY_SW_RESET bit */
+#define SW_RESET                               BIT(0)
+/* QPHY_POWER_DOWN_CONTROL */
+#define SW_PWRDN                               BIT(0)
+#define REFCLK_DRV_DSBL                                BIT(1) /* PCIe */
+
+/* QPHY_START_CONTROL bits */
+#define SERDES_START                           BIT(0)
+#define PCS_START                              BIT(1)
+
+/* QPHY_PCS_STATUS bit */
+#define PHYSTATUS                              BIT(6)
+#define PHYSTATUS_4_20                         BIT(7)
+
+/* 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_PCS_MISC_CLAMP_ENABLE register bits */
+#define CLAMP_EN                               BIT(0) /* enables i/o clamp_n */
 
 #endif
index 03dc753f0de1f9c3898ba8a7bcefd4ee0b7b0e21..5b1c82459c126fe3a046a89601483d8c73090fd3 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#define QSERDES_QMP_PLL                                        0x0
-#define QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0         (QSERDES_QMP_PLL + 0x1ac)
-#define QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0         (QSERDES_QMP_PLL + 0x1b0)
-#define QSERDES_COM_BIN_VCOCAL_HSCLK_SEL               (QSERDES_QMP_PLL + 0x1bc)
-#define QSERDES_COM_CORE_CLK_EN                                (QSERDES_QMP_PLL + 0x174)
-#define QSERDES_COM_CORECLK_DIV_MODE0                  (QSERDES_QMP_PLL + 0x168)
-#define QSERDES_COM_CP_CTRL_MODE0                      (QSERDES_QMP_PLL + 0x74)
-#define QSERDES_COM_DEC_START_MODE0                    (QSERDES_QMP_PLL + 0xbc)
-#define QSERDES_COM_DIV_FRAC_START1_MODE0              (QSERDES_QMP_PLL + 0xcc)
-#define QSERDES_COM_DIV_FRAC_START2_MODE0              (QSERDES_QMP_PLL + 0xd0)
-#define QSERDES_COM_DIV_FRAC_START3_MODE0              (QSERDES_QMP_PLL + 0xd4)
-#define QSERDES_COM_HSCLK_HS_SWITCH_SEL                        (QSERDES_QMP_PLL + 0x15c)
-#define QSERDES_COM_HSCLK_SEL                          (QSERDES_QMP_PLL + 0x158)
-#define QSERDES_COM_LOCK_CMP1_MODE0                    (QSERDES_QMP_PLL + 0xac)
-#define QSERDES_COM_LOCK_CMP2_MODE0                    (QSERDES_QMP_PLL + 0xb0)
-#define QSERDES_COM_PLL_CCTRL_MODE0                    (QSERDES_QMP_PLL + 0x84)
-#define QSERDES_COM_PLL_IVCO                           (QSERDES_QMP_PLL + 0x58)
-#define QSERDES_COM_PLL_RCTRL_MODE0                    (QSERDES_QMP_PLL + 0x7c)
-#define QSERDES_COM_SYSCLK_EN_SEL                      (QSERDES_QMP_PLL + 0x94)
-#define QSERDES_COM_VCO_TUNE1_MODE0                    (QSERDES_QMP_PLL + 0x110)
-#define QSERDES_COM_VCO_TUNE2_MODE0                    (QSERDES_QMP_PLL + 0x114)
-#define QSERDES_COM_VCO_TUNE_INITVAL2                  (QSERDES_QMP_PLL + 0x124)
-#define QSERDES_COM_C_READY_STATUS                     (QSERDES_QMP_PLL + 0x178)
-#define QSERDES_COM_CMN_STATUS                         (QSERDES_QMP_PLL + 0x140)
+#include "phy-qcom-qmp-pcs-sgmii.h"
+#include "phy-qcom-qmp-qserdes-com-v5.h"
+#include "phy-qcom-qmp-qserdes-txrx-v5.h"
 
+#define QSERDES_QMP_PLL                                        0x0
 #define QSERDES_RX                                     0x600
-#define QSERDES_RX_UCDR_FO_GAIN                                (QSERDES_RX + 0x8)
-#define QSERDES_RX_UCDR_SO_GAIN                                (QSERDES_RX + 0x14)
-#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN               (QSERDES_RX + 0x30)
-#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE       (QSERDES_RX + 0x34)
-#define QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW             (QSERDES_RX + 0x3c)
-#define QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH            (QSERDES_RX + 0x40)
-#define QSERDES_RX_UCDR_PI_CONTROLS                    (QSERDES_RX + 0x44)
-#define QSERDES_RX_UCDR_PI_CTRL2                       (QSERDES_RX + 0x48)
-#define QSERDES_RX_RX_TERM_BW                          (QSERDES_RX + 0x80)
-#define QSERDES_RX_VGA_CAL_CNTRL2                      (QSERDES_RX + 0xd8)
-#define QSERDES_RX_GM_CAL                              (QSERDES_RX + 0xdc)
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1               (QSERDES_RX + 0xe8)
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2               (QSERDES_RX + 0xec)
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3               (QSERDES_RX + 0xf0)
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4               (QSERDES_RX + 0xf4)
-#define QSERDES_RX_RX_IDAC_TSETTLE_LOW                 (QSERDES_RX + 0xf8)
-#define QSERDES_RX_RX_IDAC_TSETTLE_HIGH                        (QSERDES_RX + 0xfc)
-#define QSERDES_RX_RX_IDAC_MEASURE_TIME                        (QSERDES_RX + 0x100)
-#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1         (QSERDES_RX + 0x110)
-#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2            (QSERDES_RX + 0x114)
-#define QSERDES_RX_SIGDET_CNTRL                                (QSERDES_RX + 0x11c)
-#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL               (QSERDES_RX + 0x124)
-#define QSERDES_RX_RX_BAND                             (QSERDES_RX + 0x128)
-#define QSERDES_RX_RX_MODE_00_LOW                      (QSERDES_RX + 0x15c)
-#define QSERDES_RX_RX_MODE_00_HIGH                     (QSERDES_RX + 0x160)
-#define QSERDES_RX_RX_MODE_00_HIGH2                    (QSERDES_RX + 0x164)
-#define QSERDES_RX_RX_MODE_00_HIGH3                    (QSERDES_RX + 0x168)
-#define QSERDES_RX_RX_MODE_00_HIGH4                    (QSERDES_RX + 0x16c)
-#define QSERDES_RX_RX_MODE_01_LOW                      (QSERDES_RX + 0x170)
-#define QSERDES_RX_RX_MODE_01_HIGH                     (QSERDES_RX + 0x174)
-#define QSERDES_RX_RX_MODE_01_HIGH2                    (QSERDES_RX + 0x178)
-#define QSERDES_RX_RX_MODE_01_HIGH3                    (QSERDES_RX + 0x17c)
-#define QSERDES_RX_RX_MODE_01_HIGH4                    (QSERDES_RX + 0x180)
-#define QSERDES_RX_RX_MODE_10_LOW                      (QSERDES_RX + 0x184)
-#define QSERDES_RX_RX_MODE_10_HIGH                     (QSERDES_RX + 0x188)
-#define QSERDES_RX_RX_MODE_10_HIGH2                    (QSERDES_RX + 0x18c)
-#define QSERDES_RX_RX_MODE_10_HIGH3                    (QSERDES_RX + 0x190)
-#define QSERDES_RX_RX_MODE_10_HIGH4                    (QSERDES_RX + 0x194)
-#define QSERDES_RX_DCC_CTRL1                           (QSERDES_RX + 0x1a8)
-
 #define QSERDES_TX                                     0x400
-#define QSERDES_TX_TX_BAND                             (QSERDES_TX + 0x24)
-#define QSERDES_TX_SLEW_CNTL                           (QSERDES_TX + 0x28)
-#define QSERDES_TX_RES_CODE_LANE_OFFSET_TX             (QSERDES_TX + 0x3c)
-#define QSERDES_TX_RES_CODE_LANE_OFFSET_RX             (QSERDES_TX + 0x40)
-#define QSERDES_TX_LANE_MODE_1                         (QSERDES_TX + 0x84)
-#define QSERDES_TX_LANE_MODE_3                         (QSERDES_TX + 0x8c)
-#define QSERDES_TX_RCV_DETECT_LVL_2                    (QSERDES_TX + 0xa4)
-#define QSERDES_TX_TRAN_DRVR_EMP_EN                    (QSERDES_TX + 0xc0)
-
-#define QSERDES_PCS                                    0xC00
-#define QSERDES_PCS_PHY_START                          (QSERDES_PCS + 0x0)
-#define QSERDES_PCS_POWER_DOWN_CONTROL                 (QSERDES_PCS + 0x4)
-#define QSERDES_PCS_SW_RESET                           (QSERDES_PCS + 0x8)
-#define QSERDES_PCS_LINE_RESET_TIME                    (QSERDES_PCS + 0xc)
-#define QSERDES_PCS_TX_LARGE_AMP_DRV_LVL               (QSERDES_PCS + 0x20)
-#define QSERDES_PCS_TX_SMALL_AMP_DRV_LVL               (QSERDES_PCS + 0x28)
-#define QSERDES_PCS_TX_MID_TERM_CTRL1                  (QSERDES_PCS + 0xd8)
-#define QSERDES_PCS_TX_MID_TERM_CTRL2                  (QSERDES_PCS + 0xdc)
-#define QSERDES_PCS_SGMII_MISC_CTRL8                   (QSERDES_PCS + 0x118)
-#define QSERDES_PCS_PCS_READY_STATUS                   (QSERDES_PCS + 0x94)
+#define QSERDES_PCS                                    0xc00
 
 #define QSERDES_COM_C_READY                            BIT(0)
 #define QSERDES_PCS_READY                              BIT(0)
@@ -112,178 +33,178 @@ struct qcom_dwmac_sgmii_phy_data {
 
 static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
 {
-       regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01);
-       regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01);
-
-       regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F);
-       regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06);
-       regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
-       regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
-       regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A);
-       regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x0A);
-       regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x1A);
-       regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x82);
-       regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55);
-       regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55);
-       regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03);
-       regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0x24);
-
-       regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02);
-       regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00);
-       regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x04);
-       regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00);
-       regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x0A);
-       regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00);
-       regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xB9);
-       regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1E);
-       regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11);
-
-       regmap_write(regmap, QSERDES_TX_TX_BAND, 0x05);
-       regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A);
-       regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
-       regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x09);
-       regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05);
-       regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00);
-       regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12);
-       regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C);
-
-       regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A);
-       regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06);
-       regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
-       regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
-       regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
-       regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
-       regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81);
-       regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80);
-       regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x04);
-       regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08);
-       regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A);
-       regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80);
-       regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
-       regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20);
-       regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
-       regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
-       regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F);
-       regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
-       regmap_write(regmap, QSERDES_RX_RX_BAND, 0x05);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0xE0);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x09);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB1);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7);
-       regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C);
-
-       regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C);
-       regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F);
-       regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
-       regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83);
-       regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
-       regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x0C);
-       regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00);
-
-       regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_POWER_DOWN_CONTROL, 0x01);
+
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_IVCO, 0x0F);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CP_CTRL_MODE0, 0x06);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_SYSCLK_EN_SEL, 0x1A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DEC_START_MODE0, 0x82);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24);
+
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE2_MODE0, 0x02);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_SEL, 0x04);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORE_CLK_EN, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xB9);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1E);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11);
+
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TX_BAND, 0x05);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_SLEW_CNTL, 0x0A);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_1, 0x05);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_3, 0x00);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0C);
+
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FO_GAIN, 0x0A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_GAIN, 0x06);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x81);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_TERM_BW, 0x04);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x08);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_GM_CAL, 0x0F);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_CNTRL, 0x0F);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_BAND, 0x05);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_LOW, 0xE0);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x09);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xB1);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_LOW, 0xE0);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x09);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xB1);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_LOW, 0xE0);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3B);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xB7);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_DCC_CTRL1, 0x0C);
+
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_LINE_RESET_TIME, 0x0C);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL1, 0x83);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL8, 0x0C);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00);
+
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
 }
 
 static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap)
 {
-       regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01);
-       regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01);
-
-       regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F);
-       regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06);
-       regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
-       regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
-       regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A);
-       regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x1A);
-       regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x41);
-       regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x7A);
-       regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00);
-       regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x20);
-       regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x01);
-       regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0xA1);
-
-       regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02);
-       regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00);
-       regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x03);
-       regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00);
-       regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x05);
-       regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00);
-       regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xCD);
-       regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1C);
-       regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11);
-
-       regmap_write(regmap, QSERDES_TX_TX_BAND, 0x04);
-       regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A);
-       regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
-       regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x02);
-       regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05);
-       regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00);
-       regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12);
-       regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C);
-
-       regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A);
-       regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06);
-       regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
-       regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
-       regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
-       regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
-       regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81);
-       regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80);
-       regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x00);
-       regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08);
-       regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
-       regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A);
-       regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80);
-       regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
-       regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20);
-       regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
-       regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
-       regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F);
-       regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
-       regmap_write(regmap, QSERDES_RX_RX_BAND, 0x18);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0x18);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x0C);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B);
-       regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7);
-       regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C);
-
-       regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C);
-       regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F);
-       regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
-       regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83);
-       regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
-       regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x8C);
-       regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00);
-
-       regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_POWER_DOWN_CONTROL, 0x01);
+
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_IVCO, 0x0F);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CP_CTRL_MODE0, 0x06);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_SYSCLK_EN_SEL, 0x1A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x1A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x41);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DEC_START_MODE0, 0x7A);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x20);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x01);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE1_MODE0, 0xA1);
+
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE2_MODE0, 0x02);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_SEL, 0x03);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x05);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORE_CLK_EN, 0x00);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xCD);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1C);
+       regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11);
+
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TX_BAND, 0x04);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_SLEW_CNTL, 0x0A);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x02);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_1, 0x05);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_3, 0x00);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12);
+       regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0C);
+
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FO_GAIN, 0x0A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_GAIN, 0x06);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x81);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_TERM_BW, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x08);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_GM_CAL, 0x0F);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_CNTRL, 0x0F);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_BAND, 0x18);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_LOW, 0x18);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x0C);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xB8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_LOW, 0xE0);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x09);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xB1);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_LOW, 0xE0);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xC8);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3B);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xB7);
+       regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_DCC_CTRL1, 0x0C);
+
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_LINE_RESET_TIME, 0x0C);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL1, 0x83);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL8, 0x8C);
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00);
+
+       regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
 }
 
 static inline int
@@ -313,28 +234,28 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
        }
 
        if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
-                                            QSERDES_COM_C_READY_STATUS,
+                                            QSERDES_QMP_PLL + QSERDES_V5_COM_C_READY_STATUS,
                                             QSERDES_COM_C_READY)) {
                dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");
                return -ETIMEDOUT;
        }
 
        if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
-                                            QSERDES_PCS_PCS_READY_STATUS,
+                                            QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
                                             QSERDES_PCS_READY)) {
                dev_err(dev, "PCS_READY timed-out");
                return -ETIMEDOUT;
        }
 
        if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
-                                            QSERDES_PCS_PCS_READY_STATUS,
+                                            QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
                                             QSERDES_PCS_SGMIIPHY_READY)) {
                dev_err(dev, "SGMIIPHY_READY timed-out");
                return -ETIMEDOUT;
        }
 
        if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
-                                            QSERDES_COM_CMN_STATUS,
+                                            QSERDES_QMP_PLL + QSERDES_V5_COM_CMN_STATUS,
                                             QSERDES_COM_C_PLL_LOCKED)) {
                dev_err(dev, "PLL Lock Status timed-out");
                return -ETIMEDOUT;
@@ -354,11 +275,11 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
 {
        struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
 
-       regmap_write(data->regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
-       regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x01);
+       regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08);
+       regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
        udelay(100);
-       regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x00);
-       regmap_write(data->regmap, QSERDES_PCS_PHY_START, 0x01);
+       regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00);
+       regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
 
        clk_disable_unprepare(data->refclk);
 
index 2f876f158e1df6acd51d20bda470fcc783efcdf8..a591ad95347ccf69a747b337bcbf01cb8eb7dc73 100644 (file)
@@ -263,7 +263,7 @@ static const struct phy_ops mt7621_pci_phy_ops = {
 };
 
 static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
-                                           struct of_phandle_args *args)
+                                           const struct of_phandle_args *args)
 {
        struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev);
 
index 507435af26567f992540e41dd38068815bd69863..c0221e7258c0321005171bdab9c57d5ae784a8d6 100644 (file)
@@ -306,7 +306,7 @@ static const struct of_device_id rcar_gen2_phy_match_table[] = {
 MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
 
 static struct phy *rcar_gen2_phy_xlate(struct device *dev,
-                                      struct of_phandle_args *args)
+                                      const struct of_phandle_args *args)
 {
        struct rcar_gen2_phy_driver *drv;
        struct device_node *np = args->np;
index 6387c0d34c551c0e4e28e09af0792cee69eb2952..fbab6ac0f0d10c89a275b68dd8d0094c1943f357 100644 (file)
@@ -608,7 +608,7 @@ static const unsigned int rcar_gen3_phy_cable[] = {
 };
 
 static struct phy *rcar_gen3_phy_usb2_xlate(struct device *dev,
-                                           struct of_phandle_args *args)
+                                           const struct of_phandle_args *args)
 {
        struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
 
index fc6e398fa3bfb65c5d92f9e87e98fc593bf69ae5..f1f1da4a0b1fe5091da22845522ae7623f187e16 100644 (file)
@@ -334,7 +334,7 @@ static const struct phy_ops r8a779f0_eth_serdes_ops = {
 };
 
 static struct phy *r8a779f0_eth_serdes_xlate(struct device *dev,
-                                            struct of_phandle_args *args)
+                                            const struct of_phandle_args *args)
 {
        struct r8a779f0_eth_serdes_drv_data *dd = dev_get_drvdata(dev);
 
index 94360fc96a6fb2e16cce53e44c0222d719e6e1ab..a34f67bb7e61ad7b23cfc2d510054bb4348b8a36 100644 (file)
@@ -83,6 +83,14 @@ config PHY_ROCKCHIP_PCIE
        help
          Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_SAMSUNG_HDPTX
+       tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
+       depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
+       select GENERIC_PHY
+       help
+         Enable this to support the Rockchip HDMI/eDP Combo PHY
+         with Samsung IP block.
+
 config PHY_ROCKCHIP_SNPS_PCIE3
        tristate "Rockchip Snps PCIe3 PHY Driver"
        depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
index 7eab129230d175bca9d439336ca56e2e5fe1cb35..3d911304e65433b961c777a8e773db85c6452516 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI)    += phy-rockchip-inno-hdmi.o
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)   += phy-rockchip-inno-usb2.o
 obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY)    += phy-rockchip-naneng-combphy.o
 obj-$(CONFIG_PHY_ROCKCHIP_PCIE)                += phy-rockchip-pcie.o
+obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX)       += phy-rockchip-samsung-hdptx.o
 obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)  += phy-rockchip-snps-pcie3.o
 obj-$(CONFIG_PHY_ROCKCHIP_TYPEC)       += phy-rockchip-typec.o
 obj-$(CONFIG_PHY_ROCKCHIP_USB)         += phy-rockchip-usb.o
index 5de5e2e97ffa0f17d1997d49661f3699ef5fe3c1..76b9cf417591de0b7d9f5887dc78b075bd71e6bf 100644 (file)
@@ -251,7 +251,7 @@ static const struct phy_ops rochchip_combphy_ops = {
        .owner = THIS_MODULE,
 };
 
-static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args)
+static struct phy *rockchip_combphy_xlate(struct device *dev, const struct of_phandle_args *args)
 {
        struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
 
index 1bbd6be2a58473db756e85631505bf81bdc29b77..51cc5ece0e63724d1ce6f9d3ece2f378a28786f0 100644 (file)
@@ -82,7 +82,7 @@ static struct rockchip_pcie_phy *to_pcie_phy(struct phy_pcie_instance *inst)
 }
 
 static struct phy *rockchip_pcie_phy_of_xlate(struct device *dev,
-                                             struct of_phandle_args *args)
+                                             const struct of_phandle_args *args)
 {
        struct rockchip_pcie_phy *rk_phy = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
new file mode 100644 (file)
index 0000000..946c012
--- /dev/null
@@ -0,0 +1,1028 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2024 Collabora Ltd.
+ *
+ * Author: Algea Cao <algea.cao@rock-chips.com>
+ * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/rational.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define GRF_HDPTX_CON0                 0x00
+#define HDPTX_I_PLL_EN                 BIT(7)
+#define HDPTX_I_BIAS_EN                        BIT(6)
+#define HDPTX_I_BGR_EN                 BIT(5)
+#define GRF_HDPTX_STATUS               0x80
+#define HDPTX_O_PLL_LOCK_DONE          BIT(3)
+#define HDPTX_O_PHY_CLK_RDY            BIT(2)
+#define HDPTX_O_PHY_RDY                        BIT(1)
+#define HDPTX_O_SB_RDY                 BIT(0)
+
+#define HDTPX_REG(_n, _min, _max)                              \
+       (                                                       \
+               BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +      \
+               BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +      \
+               ((0x##_n) * 4)                                  \
+       )
+
+#define CMN_REG(n)                     HDTPX_REG(n, 0000, 00a7)
+#define SB_REG(n)                      HDTPX_REG(n, 0100, 0129)
+#define LNTOP_REG(n)                   HDTPX_REG(n, 0200, 0229)
+#define LANE_REG(n)                    HDTPX_REG(n, 0300, 062d)
+
+/* CMN_REG(0008) */
+#define LCPLL_EN_MASK                  BIT(6)
+#define LCPLL_LCVCO_MODE_EN_MASK       BIT(4)
+/* CMN_REG(001e) */
+#define LCPLL_PI_EN_MASK               BIT(5)
+#define LCPLL_100M_CLK_EN_MASK         BIT(0)
+/* CMN_REG(0025) */
+#define LCPLL_PMS_IQDIV_RSTN           BIT(4)
+/* CMN_REG(0028) */
+#define LCPLL_SDC_FRAC_EN              BIT(2)
+#define LCPLL_SDC_FRAC_RSTN            BIT(0)
+/* CMN_REG(002d) */
+#define LCPLL_SDC_N_MASK               GENMASK(3, 1)
+/* CMN_REG(002e) */
+#define LCPLL_SDC_NUMBERATOR_MASK      GENMASK(5, 0)
+/* CMN_REG(002f) */
+#define LCPLL_SDC_DENOMINATOR_MASK     GENMASK(7, 2)
+#define LCPLL_SDC_NDIV_RSTN            BIT(0)
+/* CMN_REG(003d) */
+#define ROPLL_LCVCO_EN                 BIT(4)
+/* CMN_REG(004e) */
+#define ROPLL_PI_EN                    BIT(5)
+/* CMN_REG(005c) */
+#define ROPLL_PMS_IQDIV_RSTN           BIT(5)
+/* CMN_REG(005e) */
+#define ROPLL_SDM_EN_MASK              BIT(6)
+#define ROPLL_SDM_FRAC_EN_RBR          BIT(3)
+#define ROPLL_SDM_FRAC_EN_HBR          BIT(2)
+#define ROPLL_SDM_FRAC_EN_HBR2         BIT(1)
+#define ROPLL_SDM_FRAC_EN_HBR3         BIT(0)
+/* CMN_REG(0064) */
+#define ROPLL_SDM_NUM_SIGN_RBR_MASK    BIT(3)
+/* CMN_REG(0069) */
+#define ROPLL_SDC_N_RBR_MASK           GENMASK(2, 0)
+/* CMN_REG(0074) */
+#define ROPLL_SDC_NDIV_RSTN            BIT(2)
+#define ROPLL_SSC_EN                   BIT(0)
+/* CMN_REG(0081) */
+#define OVRD_PLL_CD_CLK_EN             BIT(8)
+#define PLL_CD_HSCLK_EAST_EN           BIT(0)
+/* CMN_REG(0086) */
+#define PLL_PCG_POSTDIV_SEL_MASK       GENMASK(7, 4)
+#define PLL_PCG_CLK_SEL_MASK           GENMASK(3, 1)
+#define PLL_PCG_CLK_EN                 BIT(0)
+/* CMN_REG(0087) */
+#define PLL_FRL_MODE_EN                        BIT(3)
+#define PLL_TX_HS_CLK_EN               BIT(2)
+/* CMN_REG(0089) */
+#define LCPLL_ALONE_MODE               BIT(1)
+/* CMN_REG(0097) */
+#define DIG_CLK_SEL                    BIT(1)
+#define ROPLL_REF                      BIT(1)
+#define LCPLL_REF                      0
+/* CMN_REG(0099) */
+#define CMN_ROPLL_ALONE_MODE           BIT(2)
+#define ROPLL_ALONE_MODE               BIT(2)
+/* CMN_REG(009a) */
+#define HS_SPEED_SEL                   BIT(0)
+#define DIV_10_CLOCK                   BIT(0)
+/* CMN_REG(009b) */
+#define IS_SPEED_SEL                   BIT(4)
+#define LINK_SYMBOL_CLOCK              BIT(4)
+#define LINK_SYMBOL_CLOCK1_2           0
+
+/* SB_REG(0102) */
+#define OVRD_SB_RXTERM_EN_MASK         BIT(5)
+#define SB_RXTERM_EN_MASK              BIT(4)
+#define ANA_SB_RXTERM_OFFSP_MASK       GENMASK(3, 0)
+/* SB_REG(0103) */
+#define ANA_SB_RXTERM_OFFSN_MASK       GENMASK(6, 3)
+#define OVRD_SB_RX_RESCAL_DONE_MASK    BIT(1)
+#define SB_RX_RESCAL_DONE_MASK         BIT(0)
+/* SB_REG(0104) */
+#define OVRD_SB_EN_MASK                        BIT(5)
+#define SB_EN_MASK                     BIT(4)
+/* SB_REG(0105) */
+#define OVRD_SB_EARC_CMDC_EN_MASK      BIT(6)
+#define SB_EARC_CMDC_EN_MASK           BIT(5)
+#define ANA_SB_TX_HLVL_PROG_MASK       GENMASK(2, 0)
+/* SB_REG(0106) */
+#define ANA_SB_TX_LLVL_PROG_MASK       GENMASK(6, 4)
+/* SB_REG(0109) */
+#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK GENMASK(2, 0)
+/* SB_REG(010f) */
+#define OVRD_SB_VREG_EN_MASK           BIT(7)
+#define SB_VREG_EN_MASK                        BIT(6)
+#define OVRD_SB_VREG_LPF_BYPASS_MASK   BIT(5)
+#define SB_VREG_LPF_BYPASS_MASK                BIT(4)
+#define ANA_SB_VREG_GAIN_CTRL_MASK     GENMASK(3, 0)
+/* SB_REG(0110) */
+#define ANA_SB_VREG_REF_SEL_MASK       BIT(0)
+/* SB_REG(0113) */
+#define SB_RX_RCAL_OPT_CODE_MASK       GENMASK(5, 4)
+#define SB_RX_RTERM_CTRL_MASK          GENMASK(3, 0)
+/* SB_REG(0114) */
+#define SB_TG_SB_EN_DELAY_TIME_MASK    GENMASK(5, 3)
+#define SB_TG_RXTERM_EN_DELAY_TIME_MASK        GENMASK(2, 0)
+/* SB_REG(0115) */
+#define SB_READY_DELAY_TIME_MASK       GENMASK(5, 3)
+#define SB_TG_OSC_EN_DELAY_TIME_MASK   GENMASK(2, 0)
+/* SB_REG(0116) */
+#define AFC_RSTN_DELAY_TIME_MASK       GENMASK(6, 4)
+/* SB_REG(0117) */
+#define FAST_PULSE_TIME_MASK           GENMASK(3, 0)
+/* SB_REG(011b) */
+#define SB_EARC_SIG_DET_BYPASS_MASK    BIT(4)
+#define SB_AFC_TOL_MASK                        GENMASK(3, 0)
+/* SB_REG(011f) */
+#define SB_PWM_AFC_CTRL_MASK           GENMASK(7, 2)
+#define SB_RCAL_RSTN_MASK              BIT(1)
+/* SB_REG(0120) */
+#define SB_EARC_EN_MASK                        BIT(1)
+#define SB_EARC_AFC_EN_MASK            BIT(2)
+/* SB_REG(0123) */
+#define OVRD_SB_READY_MASK             BIT(5)
+#define SB_READY_MASK                  BIT(4)
+
+/* LNTOP_REG(0200) */
+#define PROTOCOL_SEL                   BIT(2)
+#define HDMI_MODE                      BIT(2)
+#define HDMI_TMDS_FRL_SEL              BIT(1)
+/* LNTOP_REG(0206) */
+#define DATA_BUS_SEL                   BIT(0)
+#define DATA_BUS_36_40                 BIT(0)
+/* LNTOP_REG(0207) */
+#define LANE_EN                                0xf
+#define ALL_LANE_EN                    0xf
+
+/* LANE_REG(0312) */
+#define LN0_TX_SER_RATE_SEL_RBR                BIT(5)
+#define LN0_TX_SER_RATE_SEL_HBR                BIT(4)
+#define LN0_TX_SER_RATE_SEL_HBR2       BIT(3)
+#define LN0_TX_SER_RATE_SEL_HBR3       BIT(2)
+/* LANE_REG(0412) */
+#define LN1_TX_SER_RATE_SEL_RBR                BIT(5)
+#define LN1_TX_SER_RATE_SEL_HBR                BIT(4)
+#define LN1_TX_SER_RATE_SEL_HBR2       BIT(3)
+#define LN1_TX_SER_RATE_SEL_HBR3       BIT(2)
+/* LANE_REG(0512) */
+#define LN2_TX_SER_RATE_SEL_RBR                BIT(5)
+#define LN2_TX_SER_RATE_SEL_HBR                BIT(4)
+#define LN2_TX_SER_RATE_SEL_HBR2       BIT(3)
+#define LN2_TX_SER_RATE_SEL_HBR3       BIT(2)
+/* LANE_REG(0612) */
+#define LN3_TX_SER_RATE_SEL_RBR                BIT(5)
+#define LN3_TX_SER_RATE_SEL_HBR                BIT(4)
+#define LN3_TX_SER_RATE_SEL_HBR2       BIT(3)
+#define LN3_TX_SER_RATE_SEL_HBR3       BIT(2)
+
+struct lcpll_config {
+       u32 bit_rate;
+       u8 lcvco_mode_en;
+       u8 pi_en;
+       u8 clk_en_100m;
+       u8 pms_mdiv;
+       u8 pms_mdiv_afc;
+       u8 pms_pdiv;
+       u8 pms_refdiv;
+       u8 pms_sdiv;
+       u8 pi_cdiv_rstn;
+       u8 pi_cdiv_sel;
+       u8 sdm_en;
+       u8 sdm_rstn;
+       u8 sdc_frac_en;
+       u8 sdc_rstn;
+       u8 sdm_deno;
+       u8 sdm_num_sign;
+       u8 sdm_num;
+       u8 sdc_n;
+       u8 sdc_n2;
+       u8 sdc_num;
+       u8 sdc_deno;
+       u8 sdc_ndiv_rstn;
+       u8 ssc_en;
+       u8 ssc_fm_dev;
+       u8 ssc_fm_freq;
+       u8 ssc_clk_div_sel;
+       u8 cd_tx_ser_rate_sel;
+};
+
+struct ropll_config {
+       u32 bit_rate;
+       u8 pms_mdiv;
+       u8 pms_mdiv_afc;
+       u8 pms_pdiv;
+       u8 pms_refdiv;
+       u8 pms_sdiv;
+       u8 pms_iqdiv_rstn;
+       u8 ref_clk_sel;
+       u8 sdm_en;
+       u8 sdm_rstn;
+       u8 sdc_frac_en;
+       u8 sdc_rstn;
+       u8 sdm_clk_div;
+       u8 sdm_deno;
+       u8 sdm_num_sign;
+       u8 sdm_num;
+       u8 sdc_n;
+       u8 sdc_num;
+       u8 sdc_deno;
+       u8 sdc_ndiv_rstn;
+       u8 ssc_en;
+       u8 ssc_fm_dev;
+       u8 ssc_fm_freq;
+       u8 ssc_clk_div_sel;
+       u8 ana_cpp_ctrl;
+       u8 ana_lpf_c_sel;
+       u8 cd_tx_ser_rate_sel;
+};
+
+enum rk_hdptx_reset {
+       RST_PHY = 0,
+       RST_APB,
+       RST_INIT,
+       RST_CMN,
+       RST_LANE,
+       RST_ROPLL,
+       RST_LCPLL,
+       RST_MAX
+};
+
+struct rk_hdptx_phy {
+       struct device *dev;
+       struct regmap *regmap;
+       struct regmap *grf;
+
+       struct phy *phy;
+       struct phy_config *phy_cfg;
+       struct clk_bulk_data *clks;
+       int nr_clks;
+       struct reset_control_bulk_data rsts[RST_MAX];
+};
+
+static const struct ropll_config ropll_tmds_cfg[] = {
+       { 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10,
+         1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5,
+         0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1,
+         1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1,
+         1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1,
+         1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+         0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1,
+         1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5,
+         1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+         0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+         0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+       { 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1,
+         1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+};
+
+static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
+       REG_SEQ0(CMN_REG(0009), 0x0c),
+       REG_SEQ0(CMN_REG(000a), 0x83),
+       REG_SEQ0(CMN_REG(000b), 0x06),
+       REG_SEQ0(CMN_REG(000c), 0x20),
+       REG_SEQ0(CMN_REG(000d), 0xb8),
+       REG_SEQ0(CMN_REG(000e), 0x0f),
+       REG_SEQ0(CMN_REG(000f), 0x0f),
+       REG_SEQ0(CMN_REG(0010), 0x04),
+       REG_SEQ0(CMN_REG(0011), 0x00),
+       REG_SEQ0(CMN_REG(0012), 0x26),
+       REG_SEQ0(CMN_REG(0013), 0x22),
+       REG_SEQ0(CMN_REG(0014), 0x24),
+       REG_SEQ0(CMN_REG(0015), 0x77),
+       REG_SEQ0(CMN_REG(0016), 0x08),
+       REG_SEQ0(CMN_REG(0017), 0x00),
+       REG_SEQ0(CMN_REG(0018), 0x04),
+       REG_SEQ0(CMN_REG(0019), 0x48),
+       REG_SEQ0(CMN_REG(001a), 0x01),
+       REG_SEQ0(CMN_REG(001b), 0x00),
+       REG_SEQ0(CMN_REG(001c), 0x01),
+       REG_SEQ0(CMN_REG(001d), 0x64),
+       REG_SEQ0(CMN_REG(001f), 0x00),
+       REG_SEQ0(CMN_REG(0026), 0x53),
+       REG_SEQ0(CMN_REG(0029), 0x01),
+       REG_SEQ0(CMN_REG(0030), 0x00),
+       REG_SEQ0(CMN_REG(0031), 0x20),
+       REG_SEQ0(CMN_REG(0032), 0x30),
+       REG_SEQ0(CMN_REG(0033), 0x0b),
+       REG_SEQ0(CMN_REG(0034), 0x23),
+       REG_SEQ0(CMN_REG(0035), 0x00),
+       REG_SEQ0(CMN_REG(0038), 0x00),
+       REG_SEQ0(CMN_REG(0039), 0x00),
+       REG_SEQ0(CMN_REG(003a), 0x00),
+       REG_SEQ0(CMN_REG(003b), 0x00),
+       REG_SEQ0(CMN_REG(003c), 0x80),
+       REG_SEQ0(CMN_REG(003e), 0x0c),
+       REG_SEQ0(CMN_REG(003f), 0x83),
+       REG_SEQ0(CMN_REG(0040), 0x06),
+       REG_SEQ0(CMN_REG(0041), 0x20),
+       REG_SEQ0(CMN_REG(0042), 0xb8),
+       REG_SEQ0(CMN_REG(0043), 0x00),
+       REG_SEQ0(CMN_REG(0044), 0x46),
+       REG_SEQ0(CMN_REG(0045), 0x24),
+       REG_SEQ0(CMN_REG(0046), 0xff),
+       REG_SEQ0(CMN_REG(0047), 0x00),
+       REG_SEQ0(CMN_REG(0048), 0x44),
+       REG_SEQ0(CMN_REG(0049), 0xfa),
+       REG_SEQ0(CMN_REG(004a), 0x08),
+       REG_SEQ0(CMN_REG(004b), 0x00),
+       REG_SEQ0(CMN_REG(004c), 0x01),
+       REG_SEQ0(CMN_REG(004d), 0x64),
+       REG_SEQ0(CMN_REG(004e), 0x14),
+       REG_SEQ0(CMN_REG(004f), 0x00),
+       REG_SEQ0(CMN_REG(0050), 0x00),
+       REG_SEQ0(CMN_REG(005d), 0x0c),
+       REG_SEQ0(CMN_REG(005f), 0x01),
+       REG_SEQ0(CMN_REG(006b), 0x04),
+       REG_SEQ0(CMN_REG(0073), 0x30),
+       REG_SEQ0(CMN_REG(0074), 0x00),
+       REG_SEQ0(CMN_REG(0075), 0x20),
+       REG_SEQ0(CMN_REG(0076), 0x30),
+       REG_SEQ0(CMN_REG(0077), 0x08),
+       REG_SEQ0(CMN_REG(0078), 0x0c),
+       REG_SEQ0(CMN_REG(0079), 0x00),
+       REG_SEQ0(CMN_REG(007b), 0x00),
+       REG_SEQ0(CMN_REG(007c), 0x00),
+       REG_SEQ0(CMN_REG(007d), 0x00),
+       REG_SEQ0(CMN_REG(007e), 0x00),
+       REG_SEQ0(CMN_REG(007f), 0x00),
+       REG_SEQ0(CMN_REG(0080), 0x00),
+       REG_SEQ0(CMN_REG(0081), 0x09),
+       REG_SEQ0(CMN_REG(0082), 0x04),
+       REG_SEQ0(CMN_REG(0083), 0x24),
+       REG_SEQ0(CMN_REG(0084), 0x20),
+       REG_SEQ0(CMN_REG(0085), 0x03),
+       REG_SEQ0(CMN_REG(0086), 0x01),
+       REG_SEQ0(CMN_REG(0087), 0x0c),
+       REG_SEQ0(CMN_REG(008a), 0x55),
+       REG_SEQ0(CMN_REG(008b), 0x25),
+       REG_SEQ0(CMN_REG(008c), 0x2c),
+       REG_SEQ0(CMN_REG(008d), 0x22),
+       REG_SEQ0(CMN_REG(008e), 0x14),
+       REG_SEQ0(CMN_REG(008f), 0x20),
+       REG_SEQ0(CMN_REG(0090), 0x00),
+       REG_SEQ0(CMN_REG(0091), 0x00),
+       REG_SEQ0(CMN_REG(0092), 0x00),
+       REG_SEQ0(CMN_REG(0093), 0x00),
+       REG_SEQ0(CMN_REG(009a), 0x11),
+       REG_SEQ0(CMN_REG(009b), 0x10),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
+       REG_SEQ0(CMN_REG(0008), 0x00),
+       REG_SEQ0(CMN_REG(0011), 0x01),
+       REG_SEQ0(CMN_REG(0017), 0x20),
+       REG_SEQ0(CMN_REG(001e), 0x14),
+       REG_SEQ0(CMN_REG(0020), 0x00),
+       REG_SEQ0(CMN_REG(0021), 0x00),
+       REG_SEQ0(CMN_REG(0022), 0x11),
+       REG_SEQ0(CMN_REG(0023), 0x00),
+       REG_SEQ0(CMN_REG(0024), 0x00),
+       REG_SEQ0(CMN_REG(0025), 0x53),
+       REG_SEQ0(CMN_REG(0026), 0x00),
+       REG_SEQ0(CMN_REG(0027), 0x00),
+       REG_SEQ0(CMN_REG(0028), 0x01),
+       REG_SEQ0(CMN_REG(002a), 0x00),
+       REG_SEQ0(CMN_REG(002b), 0x00),
+       REG_SEQ0(CMN_REG(002c), 0x00),
+       REG_SEQ0(CMN_REG(002d), 0x00),
+       REG_SEQ0(CMN_REG(002e), 0x04),
+       REG_SEQ0(CMN_REG(002f), 0x00),
+       REG_SEQ0(CMN_REG(0030), 0x20),
+       REG_SEQ0(CMN_REG(0031), 0x30),
+       REG_SEQ0(CMN_REG(0032), 0x0b),
+       REG_SEQ0(CMN_REG(0033), 0x23),
+       REG_SEQ0(CMN_REG(0034), 0x00),
+       REG_SEQ0(CMN_REG(003d), 0x40),
+       REG_SEQ0(CMN_REG(0042), 0x78),
+       REG_SEQ0(CMN_REG(004e), 0x34),
+       REG_SEQ0(CMN_REG(005c), 0x25),
+       REG_SEQ0(CMN_REG(005e), 0x4f),
+       REG_SEQ0(CMN_REG(0074), 0x04),
+       REG_SEQ0(CMN_REG(0081), 0x01),
+       REG_SEQ0(CMN_REG(0087), 0x04),
+       REG_SEQ0(CMN_REG(0089), 0x00),
+       REG_SEQ0(CMN_REG(0095), 0x00),
+       REG_SEQ0(CMN_REG(0097), 0x02),
+       REG_SEQ0(CMN_REG(0099), 0x04),
+       REG_SEQ0(CMN_REG(009b), 0x00),
+};
+
+static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {
+       REG_SEQ0(SB_REG(0114), 0x00),
+       REG_SEQ0(SB_REG(0115), 0x00),
+       REG_SEQ0(SB_REG(0116), 0x00),
+       REG_SEQ0(SB_REG(0117), 0x00),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
+       REG_SEQ0(LNTOP_REG(0201), 0x00),
+       REG_SEQ0(LNTOP_REG(0202), 0x00),
+       REG_SEQ0(LNTOP_REG(0203), 0x0f),
+       REG_SEQ0(LNTOP_REG(0204), 0xff),
+       REG_SEQ0(LNTOP_REG(0205), 0xff),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
+       REG_SEQ0(LNTOP_REG(0201), 0x07),
+       REG_SEQ0(LNTOP_REG(0202), 0xc1),
+       REG_SEQ0(LNTOP_REG(0203), 0xf0),
+       REG_SEQ0(LNTOP_REG(0204), 0x7c),
+       REG_SEQ0(LNTOP_REG(0205), 0x1f),
+};
+
+static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
+       REG_SEQ0(LANE_REG(0303), 0x0c),
+       REG_SEQ0(LANE_REG(0307), 0x20),
+       REG_SEQ0(LANE_REG(030a), 0x17),
+       REG_SEQ0(LANE_REG(030b), 0x77),
+       REG_SEQ0(LANE_REG(030c), 0x77),
+       REG_SEQ0(LANE_REG(030d), 0x77),
+       REG_SEQ0(LANE_REG(030e), 0x38),
+       REG_SEQ0(LANE_REG(0310), 0x03),
+       REG_SEQ0(LANE_REG(0311), 0x0f),
+       REG_SEQ0(LANE_REG(0316), 0x02),
+       REG_SEQ0(LANE_REG(031b), 0x01),
+       REG_SEQ0(LANE_REG(031f), 0x15),
+       REG_SEQ0(LANE_REG(0320), 0xa0),
+       REG_SEQ0(LANE_REG(0403), 0x0c),
+       REG_SEQ0(LANE_REG(0407), 0x20),
+       REG_SEQ0(LANE_REG(040a), 0x17),
+       REG_SEQ0(LANE_REG(040b), 0x77),
+       REG_SEQ0(LANE_REG(040c), 0x77),
+       REG_SEQ0(LANE_REG(040d), 0x77),
+       REG_SEQ0(LANE_REG(040e), 0x38),
+       REG_SEQ0(LANE_REG(0410), 0x03),
+       REG_SEQ0(LANE_REG(0411), 0x0f),
+       REG_SEQ0(LANE_REG(0416), 0x02),
+       REG_SEQ0(LANE_REG(041b), 0x01),
+       REG_SEQ0(LANE_REG(041f), 0x15),
+       REG_SEQ0(LANE_REG(0420), 0xa0),
+       REG_SEQ0(LANE_REG(0503), 0x0c),
+       REG_SEQ0(LANE_REG(0507), 0x20),
+       REG_SEQ0(LANE_REG(050a), 0x17),
+       REG_SEQ0(LANE_REG(050b), 0x77),
+       REG_SEQ0(LANE_REG(050c), 0x77),
+       REG_SEQ0(LANE_REG(050d), 0x77),
+       REG_SEQ0(LANE_REG(050e), 0x38),
+       REG_SEQ0(LANE_REG(0510), 0x03),
+       REG_SEQ0(LANE_REG(0511), 0x0f),
+       REG_SEQ0(LANE_REG(0516), 0x02),
+       REG_SEQ0(LANE_REG(051b), 0x01),
+       REG_SEQ0(LANE_REG(051f), 0x15),
+       REG_SEQ0(LANE_REG(0520), 0xa0),
+       REG_SEQ0(LANE_REG(0603), 0x0c),
+       REG_SEQ0(LANE_REG(0607), 0x20),
+       REG_SEQ0(LANE_REG(060a), 0x17),
+       REG_SEQ0(LANE_REG(060b), 0x77),
+       REG_SEQ0(LANE_REG(060c), 0x77),
+       REG_SEQ0(LANE_REG(060d), 0x77),
+       REG_SEQ0(LANE_REG(060e), 0x38),
+       REG_SEQ0(LANE_REG(0610), 0x03),
+       REG_SEQ0(LANE_REG(0611), 0x0f),
+       REG_SEQ0(LANE_REG(0616), 0x02),
+       REG_SEQ0(LANE_REG(061b), 0x01),
+       REG_SEQ0(LANE_REG(061f), 0x15),
+       REG_SEQ0(LANE_REG(0620), 0xa0),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
+       REG_SEQ0(LANE_REG(0312), 0x00),
+       REG_SEQ0(LANE_REG(031e), 0x00),
+       REG_SEQ0(LANE_REG(0412), 0x00),
+       REG_SEQ0(LANE_REG(041e), 0x00),
+       REG_SEQ0(LANE_REG(0512), 0x00),
+       REG_SEQ0(LANE_REG(051e), 0x00),
+       REG_SEQ0(LANE_REG(0612), 0x00),
+       REG_SEQ0(LANE_REG(061e), 0x08),
+       REG_SEQ0(LANE_REG(0303), 0x2f),
+       REG_SEQ0(LANE_REG(0403), 0x2f),
+       REG_SEQ0(LANE_REG(0503), 0x2f),
+       REG_SEQ0(LANE_REG(0603), 0x2f),
+       REG_SEQ0(LANE_REG(0305), 0x03),
+       REG_SEQ0(LANE_REG(0405), 0x03),
+       REG_SEQ0(LANE_REG(0505), 0x03),
+       REG_SEQ0(LANE_REG(0605), 0x03),
+       REG_SEQ0(LANE_REG(0306), 0x1c),
+       REG_SEQ0(LANE_REG(0406), 0x1c),
+       REG_SEQ0(LANE_REG(0506), 0x1c),
+       REG_SEQ0(LANE_REG(0606), 0x1c),
+};
+
+static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case 0x0000 ... 0x029c:
+       case 0x0400 ... 0x04a4:
+       case 0x0800 ... 0x08a4:
+       case 0x0c00 ... 0x0cb4:
+       case 0x1000 ... 0x10b4:
+       case 0x1400 ... 0x14b4:
+       case 0x1800 ... 0x18b4:
+               return true;
+       }
+
+       return false;
+}
+
+static const struct regmap_config rk_hdptx_phy_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .writeable_reg = rk_hdptx_phy_is_rw_reg,
+       .readable_reg = rk_hdptx_phy_is_rw_reg,
+       .fast_io = true,
+       .max_register = 0x18b4,
+};
+
+#define rk_hdptx_multi_reg_write(hdptx, seq) \
+       regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))
+
+static void rk_hdptx_pre_power_up(struct rk_hdptx_phy *hdptx)
+{
+       u32 val;
+
+       reset_control_assert(hdptx->rsts[RST_APB].rstc);
+       usleep_range(20, 25);
+       reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+       reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+       reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+       reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+       val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+       regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+}
+
+static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
+{
+       u32 val;
+       int ret;
+
+       reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
+
+       val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+              HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+       regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+       ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+                                      (val & HDPTX_O_PHY_RDY) &&
+                                      (val & HDPTX_O_PLL_LOCK_DONE),
+                                      100, 5000);
+       if (ret) {
+               dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret);
+               return ret;
+       }
+
+       dev_dbg(hdptx->dev, "PHY lane locked\n");
+
+       return 0;
+}
+
+static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx)
+{
+       u32 val;
+       int ret;
+
+       val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+              HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+       regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+       usleep_range(10, 15);
+       reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+       usleep_range(10, 15);
+       val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
+       regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+       usleep_range(10, 15);
+       reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+
+       ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+                                      val & HDPTX_O_PHY_CLK_RDY, 20, 400);
+       if (ret) {
+               dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret);
+               return ret;
+       }
+
+       dev_dbg(hdptx->dev, "PHY clk ready\n");
+
+       return 0;
+}
+
+static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
+{
+       u32 val;
+
+       /* reset phy and apb, or phy locked flag may keep 1 */
+       reset_control_assert(hdptx->rsts[RST_PHY].rstc);
+       usleep_range(20, 30);
+       reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
+
+       reset_control_assert(hdptx->rsts[RST_APB].rstc);
+       usleep_range(20, 30);
+       reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+       regmap_write(hdptx->regmap, LANE_REG(0300), 0x82);
+       regmap_write(hdptx->regmap, SB_REG(010f), 0xc1);
+       regmap_write(hdptx->regmap, SB_REG(0110), 0x1);
+       regmap_write(hdptx->regmap, LANE_REG(0301), 0x80);
+       regmap_write(hdptx->regmap, LANE_REG(0401), 0x80);
+       regmap_write(hdptx->regmap, LANE_REG(0501), 0x80);
+       regmap_write(hdptx->regmap, LANE_REG(0601), 0x80);
+
+       reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+       reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+       reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+       val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+       regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+}
+
+static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,
+                                     struct ropll_config *cfg)
+{
+       const unsigned int fout = data_rate / 2, fref = 24000;
+       unsigned long k = 0, lc, k_sub, lc_sub;
+       unsigned int fvco, sdc;
+       u32 mdiv, sdiv, n = 8;
+
+       if (fout > 0xfffffff)
+               return false;
+
+       for (sdiv = 16; sdiv >= 1; sdiv--) {
+               if (sdiv % 2 && sdiv != 1)
+                       continue;
+
+               fvco = fout * sdiv;
+
+               if (fvco < 2000000 || fvco > 4000000)
+                       continue;
+
+               mdiv = DIV_ROUND_UP(fvco, fref);
+               if (mdiv < 20 || mdiv > 255)
+                       continue;
+
+               if (fref * mdiv - fvco) {
+                       for (sdc = 264000; sdc <= 750000; sdc += fref)
+                               if (sdc * n > fref * mdiv)
+                                       break;
+
+                       if (sdc > 750000)
+                               continue;
+
+                       rational_best_approximation(fref * mdiv - fvco,
+                                                   sdc / 16,
+                                                   GENMASK(6, 0),
+                                                   GENMASK(7, 0),
+                                                   &k, &lc);
+
+                       rational_best_approximation(sdc * n - fref * mdiv,
+                                                   sdc,
+                                                   GENMASK(6, 0),
+                                                   GENMASK(7, 0),
+                                                   &k_sub, &lc_sub);
+               }
+
+               break;
+       }
+
+       if (sdiv < 1)
+               return false;
+
+       if (cfg) {
+               cfg->pms_mdiv = mdiv;
+               cfg->pms_mdiv_afc = mdiv;
+               cfg->pms_pdiv = 1;
+               cfg->pms_refdiv = 1;
+               cfg->pms_sdiv = sdiv - 1;
+
+               cfg->sdm_en = k > 0 ? 1 : 0;
+               if (cfg->sdm_en) {
+                       cfg->sdm_deno = lc;
+                       cfg->sdm_num_sign = 1;
+                       cfg->sdm_num = k;
+                       cfg->sdc_n = n - 3;
+                       cfg->sdc_num = k_sub;
+                       cfg->sdc_deno = lc_sub;
+               }
+       }
+
+       return true;
+}
+
+static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
+                                         unsigned int rate)
+{
+       const struct ropll_config *cfg = NULL;
+       struct ropll_config rc = {0};
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
+               if (rate == ropll_tmds_cfg[i].bit_rate) {
+                       cfg = &ropll_tmds_cfg[i];
+                       break;
+               }
+
+       if (!cfg) {
+               if (rk_hdptx_phy_clk_pll_calc(rate, &rc)) {
+                       cfg = &rc;
+               } else {
+                       dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
+                       return -EINVAL;
+               }
+       }
+
+       dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n",
+               cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en,
+               cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
+
+       rk_hdptx_pre_power_up(hdptx);
+
+       reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
+       usleep_range(20, 30);
+       reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
+
+       rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
+       rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
+
+       regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
+       regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
+       regmap_write(hdptx->regmap, CMN_REG(0059),
+                    (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
+       regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4);
+
+       regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
+                          FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
+       if (!cfg->sdm_en)
+               regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0);
+
+       regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,
+                          FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));
+
+       regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno);
+       regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num);
+
+       regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
+                          FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));
+
+       regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num);
+       regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno);
+
+       regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
+                          FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
+
+       regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,
+                          PLL_PCG_CLK_EN);
+
+       return rk_hdptx_post_enable_pll(hdptx);
+}
+
+static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
+                                          unsigned int rate)
+{
+       u32 val;
+       int ret;
+
+       ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
+       if (ret)
+               return ret;
+
+       if (!(val & HDPTX_O_PLL_LOCK_DONE)) {
+               ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
+               if (ret)
+                       return ret;
+       }
+
+       rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
+
+       regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
+
+       if (rate >= 3400000) {
+               /* For 1/40 bitrate clk */
+               rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
+       } else {
+               /* For 1/10 bitrate clk */
+               rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq);
+       }
+
+       regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
+       regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+
+       rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
+       rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);
+
+       return rk_hdptx_post_enable_lane(hdptx);
+}
+
+static int rk_hdptx_phy_power_on(struct phy *phy)
+{
+       struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+       int ret, bus_width = phy_get_bus_width(hdptx->phy);
+       /*
+        * FIXME: Temporary workaround to pass pixel_clk_rate
+        * from the HDMI bridge driver until phy_configure_opts_hdmi
+        * becomes available in the PHY API.
+        */
+       unsigned int rate = bus_width & 0xfffffff;
+
+       dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
+               __func__, bus_width, rate);
+
+       ret = pm_runtime_resume_and_get(hdptx->dev);
+       if (ret) {
+               dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret);
+               return ret;
+       }
+
+       ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
+       if (ret)
+               pm_runtime_put(hdptx->dev);
+
+       return ret;
+}
+
+static int rk_hdptx_phy_power_off(struct phy *phy)
+{
+       struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+       u32 val;
+       int ret;
+
+       ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
+       if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
+               rk_hdptx_phy_disable(hdptx);
+
+       pm_runtime_put(hdptx->dev);
+
+       return ret;
+}
+
+static const struct phy_ops rk_hdptx_phy_ops = {
+       .power_on  = rk_hdptx_phy_power_on,
+       .power_off = rk_hdptx_phy_power_off,
+       .owner     = THIS_MODULE,
+};
+
+static int rk_hdptx_phy_runtime_suspend(struct device *dev)
+{
+       struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);
+
+       clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks);
+
+       return 0;
+}
+
+static int rk_hdptx_phy_runtime_resume(struct device *dev)
+{
+       struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);
+       int ret;
+
+       ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks);
+       if (ret)
+               dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret);
+
+       return ret;
+}
+
+static int rk_hdptx_phy_probe(struct platform_device *pdev)
+{
+       struct phy_provider *phy_provider;
+       struct device *dev = &pdev->dev;
+       struct rk_hdptx_phy *hdptx;
+       void __iomem *regs;
+       int ret;
+
+       hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
+       if (!hdptx)
+               return -ENOMEM;
+
+       hdptx->dev = dev;
+
+       regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(regs))
+               return dev_err_probe(dev, PTR_ERR(regs),
+                                    "Failed to ioremap resource\n");
+
+       ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "Failed to get clocks\n");
+       if (ret == 0)
+               return dev_err_probe(dev, -EINVAL, "Missing clocks\n");
+
+       hdptx->nr_clks = ret;
+
+       hdptx->regmap = devm_regmap_init_mmio(dev, regs,
+                                             &rk_hdptx_phy_regmap_config);
+       if (IS_ERR(hdptx->regmap))
+               return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
+                                    "Failed to init regmap\n");
+
+       hdptx->rsts[RST_PHY].id = "phy";
+       hdptx->rsts[RST_APB].id = "apb";
+       hdptx->rsts[RST_INIT].id = "init";
+       hdptx->rsts[RST_CMN].id = "cmn";
+       hdptx->rsts[RST_LANE].id = "lane";
+       hdptx->rsts[RST_ROPLL].id = "ropll";
+       hdptx->rsts[RST_LCPLL].id = "lcpll";
+
+       ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to get resets\n");
+
+       hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+                                                    "rockchip,grf");
+       if (IS_ERR(hdptx->grf))
+               return dev_err_probe(dev, PTR_ERR(hdptx->grf),
+                                    "Could not get GRF syscon\n");
+
+       hdptx->phy = devm_phy_create(dev, NULL, &rk_hdptx_phy_ops);
+       if (IS_ERR(hdptx->phy))
+               return dev_err_probe(dev, PTR_ERR(hdptx->phy),
+                                    "Failed to create HDMI PHY\n");
+
+       platform_set_drvdata(pdev, hdptx);
+       phy_set_drvdata(hdptx->phy, hdptx);
+       phy_set_bus_width(hdptx->phy, 8);
+
+       ret = devm_pm_runtime_enable(dev);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
+
+       phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return dev_err_probe(dev, PTR_ERR(phy_provider),
+                                    "Failed to register PHY provider\n");
+
+       reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+       reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+       reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+       return 0;
+}
+
+static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
+       RUNTIME_PM_OPS(rk_hdptx_phy_runtime_suspend,
+                      rk_hdptx_phy_runtime_resume, NULL)
+};
+
+static const struct of_device_id rk_hdptx_phy_of_match[] = {
+       { .compatible = "rockchip,rk3588-hdptx-phy", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match);
+
+static struct platform_driver rk_hdptx_phy_driver = {
+       .probe  = rk_hdptx_phy_probe,
+       .driver = {
+               .name = "rockchip-hdptx-phy",
+               .pm = &rk_hdptx_phy_pm_ops,
+               .of_match_table = rk_hdptx_phy_of_match,
+       },
+};
+module_platform_driver(rk_hdptx_phy_driver);
+
+MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>");
+MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>");
+MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
+MODULE_LICENSE("GPL");
index 592d8067e848e280bb6185542c26123059bdbd17..f6756a609a9a0774ecb6e27cf96726891683636c 100644 (file)
@@ -274,7 +274,7 @@ static int exynos_mipi_video_phy_power_off(struct phy *phy)
 }
 
 static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
 
index 3f310b28bfff799cbe9d687bc6c1af3cc3941159..04171eed5b16fbd930a1b3a7a65ac96a4de5c12d 100644 (file)
@@ -715,7 +715,7 @@ static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy *phy_drd)
 }
 
 static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev);
 
index 68a174eca0ba8a01ae22199c7939b7fa26f53794..9de744cd6f39286d2b84f8421a26c6600c1360a0 100644 (file)
@@ -87,7 +87,7 @@ static const struct phy_ops samsung_usb2_phy_ops = {
 };
 
 static struct phy *samsung_usb2_phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct samsung_usb2_phy_driver *drv;
 
index 3f2086ed4fe4f9fc90b0bc221dc84ffb606906d4..21c201717d952934e1de893530f418bc92b4476b 100644 (file)
@@ -81,7 +81,7 @@ static int uniphier_u2phy_init(struct phy *phy)
 }
 
 static struct phy *uniphier_u2phy_xlate(struct device *dev,
-                                       struct of_phandle_args *args)
+                                       const struct of_phandle_args *args)
 {
        struct uniphier_u2phy_priv *priv = dev_get_drvdata(dev);
 
index e30305b77f0d168e27e069340c85d670095c7be3..063fc38788ed403894390f022fa1150b2f7c689b 100644 (file)
@@ -1074,7 +1074,7 @@ static int miphy28lp_get_addr(struct miphy28lp_phy *miphy_phy)
 }
 
 static struct phy *miphy28lp_xlate(struct device *dev,
-                                  struct of_phandle_args *args)
+                                  const struct of_phandle_args *args)
 {
        struct miphy28lp_dev *miphy_dev = dev_get_drvdata(dev);
        struct miphy28lp_phy *miphy_phy = NULL;
index 35a9831b51610cad2b0b3fe22b0c2d8aba58bf63..c661ab63505f9b1731c324296fa552dc748d7825 100644 (file)
@@ -183,7 +183,7 @@ static const struct phy_ops spear1310_miphy_ops = {
 };
 
 static struct phy *spear1310_miphy_xlate(struct device *dev,
-                                        struct of_phandle_args *args)
+                                        const struct of_phandle_args *args)
 {
        struct spear1310_miphy_priv *priv = dev_get_drvdata(dev);
 
index 34a1cf21015f59d89de002ae154e01173b25f6dc..85a60d64ebb7dbadda62d530dfb6d0179a11bc2b 100644 (file)
@@ -220,7 +220,7 @@ static SIMPLE_DEV_PM_OPS(spear1340_miphy_pm_ops, spear1340_miphy_suspend,
                         spear1340_miphy_resume);
 
 static struct phy *spear1340_miphy_xlate(struct device *dev,
-                                        struct of_phandle_args *args)
+                                        const struct of_phandle_args *args)
 {
        struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
 
index d5e7e44000b56ec0fe16703a52e47b05926ac866..9dbe60dcf3190d0e96b0fa915f784d1a91ec7701 100644 (file)
@@ -574,7 +574,7 @@ static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,
 }
 
 static struct phy *stm32_usbphyc_of_xlate(struct device *dev,
-                                         struct of_phandle_args *args)
+                                         const struct of_phandle_args *args)
 {
        struct stm32_usbphyc *usbphyc = dev_get_drvdata(dev);
        struct stm32_usbphyc_phy *usbphyc_phy = NULL;
index 142ebe0247cc00f82080303269835ad9565e584f..0dc86a7740e382f2dada87af3d1964bc92ddb52e 100644 (file)
@@ -22,7 +22,7 @@
 #include "xusb.h"
 
 static struct phy *tegra_xusb_pad_of_xlate(struct device *dev,
-                                          struct of_phandle_args *args)
+                                          const struct of_phandle_args *args)
 {
        struct tegra_xusb_pad *pad = dev_get_drvdata(dev);
        struct phy *phy = NULL;
index 3f1d43e8b7ad1fbcfd3399db0150c59eb6e96ad4..8b3b937de624838c8f57265dbf5ffe14f4b9d6c1 100644 (file)
@@ -495,7 +495,7 @@ static void serdes_am654_release(struct phy *x)
 }
 
 static struct phy *serdes_am654_xlate(struct device *dev,
-                                     struct of_phandle_args *args)
+                                     const struct of_phandle_args *args)
 {
        struct serdes_am654 *am654_phy;
        struct phy *phy;
index b7a9ef3f465440008933fa3c7a20c44599baa150..0fe577f0d6c1e66dbb3803e115f954546cd9687d 100644 (file)
@@ -119,7 +119,7 @@ static const struct phy_ops da8xx_usb20_phy_ops = {
 };
 
 static struct phy *da8xx_usb_phy_of_xlate(struct device *dev,
-                                        struct of_phandle_args *args)
+                                        const struct of_phandle_args *args)
 {
        struct da8xx_usb_phy *d_phy = dev_get_drvdata(dev);
 
index 0f4818adb440022d0d9b21a723e36ca062091268..b30bf740e2e0df81f1c03caa9624e08808147d03 100644 (file)
@@ -297,7 +297,7 @@ static const struct phy_ops phy_gmii_sel_ops = {
 };
 
 static struct phy *phy_gmii_sel_of_xlate(struct device *dev,
-                                        struct of_phandle_args *args)
+                                        const struct of_phandle_args *args)
 {
        struct phy_gmii_sel_priv *priv = dev_get_drvdata(dev);
        int phy_id = args->args[0];
@@ -494,11 +494,35 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)
        return 0;
 }
 
+static int phy_gmii_sel_resume_noirq(struct device *dev)
+{
+       struct phy_gmii_sel_priv *priv = dev_get_drvdata(dev);
+       struct phy_gmii_sel_phy_priv *if_phys = priv->if_phys;
+       int ret, i;
+
+       for (i = 0; i < priv->num_ports; i++) {
+               if (if_phys[i].phy_if_mode) {
+                       ret = phy_gmii_sel_mode(if_phys[i].if_phy,
+                                               PHY_MODE_ETHERNET, if_phys[i].phy_if_mode);
+                       if (ret) {
+                               dev_err(dev, "port%u: restore mode fail %d\n",
+                                       if_phys[i].if_phy->id, ret);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(phy_gmii_sel_pm_ops, NULL, phy_gmii_sel_resume_noirq);
+
 static struct platform_driver phy_gmii_sel_driver = {
        .probe          = phy_gmii_sel_probe,
        .driver         = {
                .name   = "phy-gmii-sel",
                .of_match_table = phy_gmii_sel_id_table,
+               .pm = pm_sleep_ptr(&phy_gmii_sel_pm_ops),
        },
 };
 module_platform_driver(phy_gmii_sel_driver);
index b4881cb344759de87a9ae6fbbb3a10c96fe55833..13cd614e12a1d3c8ad98de07a40f63091409d228 100644 (file)
 #include <linux/property.h>
 #include <linux/workqueue.h>
 
+#define TI_VENDOR_ID           0x0451
+#define TI_DEVICE_TUSB1210     0x1507
+#define TI_DEVICE_TUSB1211     0x1508
+
 #define TUSB1211_POWER_CONTROL                         0x3d
 #define TUSB1211_POWER_CONTROL_SET                     0x3e
 #define TUSB1211_POWER_CONTROL_CLEAR                   0x3f
@@ -52,7 +56,7 @@ enum tusb1210_chg_det_state {
 };
 
 struct tusb1210 {
-       struct ulpi *ulpi;
+       struct device *dev;
        struct phy *phy;
        struct gpio_desc *gpio_reset;
        struct gpio_desc *gpio_cs;
@@ -71,26 +75,27 @@ struct tusb1210 {
 
 static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)
 {
+       struct device *dev = tusb->dev;
        int ret;
 
-       ret = ulpi_write(tusb->ulpi, reg, val);
+       ret = ulpi_write(to_ulpi_dev(dev), reg, val);
        if (ret)
-               dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n",
-                       ret, val, reg);
+               dev_err(dev, "error %d writing val 0x%02x to reg 0x%02x\n", ret, val, reg);
 
        return ret;
 }
 
 static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val)
 {
+       struct device *dev = tusb->dev;
        int ret;
 
-       ret = ulpi_read(tusb->ulpi, reg);
+       ret = ulpi_read(to_ulpi_dev(dev), reg);
        if (ret >= 0) {
                *val = ret;
                ret = 0;
        } else {
-               dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg);
+               dev_err(dev, "error %d reading reg 0x%02x\n", ret, reg);
        }
 
        return ret;
@@ -178,7 +183,7 @@ static void tusb1210_reset(struct tusb1210 *tusb)
 static void tusb1210_chg_det_set_type(struct tusb1210 *tusb,
                                      enum power_supply_usb_type type)
 {
-       dev_dbg(&tusb->ulpi->dev, "charger type: %d\n", type);
+       dev_dbg(tusb->dev, "charger type: %d\n", type);
        tusb->chg_type = type;
        tusb->chg_det_retries = 0;
        power_supply_changed(tusb->psy);
@@ -189,7 +194,7 @@ static void tusb1210_chg_det_set_state(struct tusb1210 *tusb,
                                       int delay_ms)
 {
        if (delay_ms)
-               dev_dbg(&tusb->ulpi->dev, "chg_det new state %s in %d ms\n",
+               dev_dbg(tusb->dev, "chg_det new state %s in %d ms\n",
                        tusb1210_chg_det_states[new_state], delay_ms);
 
        tusb->chg_det_state = new_state;
@@ -253,7 +258,7 @@ static void tusb1210_chg_det_work(struct work_struct *work)
        int ret;
        u8 val;
 
-       dev_dbg(&tusb->ulpi->dev, "chg_det state %s vbus_present %d\n",
+       dev_dbg(tusb->dev, "chg_det state %s vbus_present %d\n",
                tusb1210_chg_det_states[tusb->chg_det_state], vbus_present);
 
        switch (tusb->chg_det_state) {
@@ -261,9 +266,9 @@ static void tusb1210_chg_det_work(struct work_struct *work)
                tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;
                tusb->chg_det_retries = 0;
                /* Power on USB controller for ulpi_read()/_write() */
-               ret = pm_runtime_resume_and_get(tusb->ulpi->dev.parent);
+               ret = pm_runtime_resume_and_get(tusb->dev->parent);
                if (ret < 0) {
-                       dev_err(&tusb->ulpi->dev, "error %d runtime-resuming\n", ret);
+                       dev_err(tusb->dev, "error %d runtime-resuming\n", ret);
                        /* Should never happen, skip charger detection */
                        tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);
                        return;
@@ -332,7 +337,7 @@ static void tusb1210_chg_det_work(struct work_struct *work)
 
                mutex_unlock(&tusb->phy->mutex);
 
-               pm_runtime_put(tusb->ulpi->dev.parent);
+               pm_runtime_put(tusb->dev->parent);
                tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);
                break;
        case TUSB1210_CHG_DET_CONNECTED:
@@ -428,13 +433,14 @@ static const struct power_supply_desc tusb1210_psy_desc = {
 static void tusb1210_probe_charger_detect(struct tusb1210 *tusb)
 {
        struct power_supply_config psy_cfg = { .drv_data = tusb };
-       struct device *dev = &tusb->ulpi->dev;
+       struct device *dev = tusb->dev;
+       struct ulpi *ulpi = to_ulpi_dev(dev);
        int ret;
 
        if (!device_property_read_bool(dev->parent, "linux,phy_charger_detect"))
                return;
 
-       if (tusb->ulpi->id.product != 0x1508) {
+       if (ulpi->id.product != TI_DEVICE_TUSB1211) {
                dev_err(dev, "error charger detection is only supported on the TUSB1211\n");
                return;
        }
@@ -485,25 +491,24 @@ static const struct phy_ops phy_ops = {
 
 static int tusb1210_probe(struct ulpi *ulpi)
 {
+       struct device *dev = &ulpi->dev;
        struct tusb1210 *tusb;
        u8 val, reg;
        int ret;
 
-       tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL);
+       tusb = devm_kzalloc(dev, sizeof(*tusb), GFP_KERNEL);
        if (!tusb)
                return -ENOMEM;
 
-       tusb->ulpi = ulpi;
+       tusb->dev = dev;
 
-       tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset",
-                                                  GPIOD_OUT_LOW);
+       tusb->gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
        if (IS_ERR(tusb->gpio_reset))
                return PTR_ERR(tusb->gpio_reset);
 
        gpiod_set_value_cansleep(tusb->gpio_reset, 1);
 
-       tusb->gpio_cs = devm_gpiod_get_optional(&ulpi->dev, "cs",
-                                               GPIOD_OUT_LOW);
+       tusb->gpio_cs = devm_gpiod_get_optional(dev, "cs", GPIOD_OUT_LOW);
        if (IS_ERR(tusb->gpio_cs))
                return PTR_ERR(tusb->gpio_cs);
 
@@ -519,15 +524,15 @@ static int tusb1210_probe(struct ulpi *ulpi)
                return ret;
 
        /* High speed output drive strength configuration */
-       if (!device_property_read_u8(&ulpi->dev, "ihstx", &val))
+       if (!device_property_read_u8(dev, "ihstx", &val))
                u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK);
 
        /* High speed output impedance configuration */
-       if (!device_property_read_u8(&ulpi->dev, "zhsdrv", &val))
+       if (!device_property_read_u8(dev, "zhsdrv", &val))
                u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK);
 
        /* DP/DM swap control */
-       if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val))
+       if (!device_property_read_u8(dev, "datapolarity", &val))
                u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK);
 
        ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg);
@@ -561,11 +566,9 @@ static void tusb1210_remove(struct ulpi *ulpi)
        tusb1210_remove_charger_detect(tusb);
 }
 
-#define TI_VENDOR_ID 0x0451
-
 static const struct ulpi_device_id tusb1210_ulpi_id[] = {
-       { TI_VENDOR_ID, 0x1507, },  /* TUSB1210 */
-       { TI_VENDOR_ID, 0x1508, },  /* TUSB1211 */
+       { TI_VENDOR_ID, TI_DEVICE_TUSB1210 },
+       { TI_VENDOR_ID, TI_DEVICE_TUSB1211 },
        { },
 };
 MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id);
index 2559c6594cea2bcdde2a06af52bcc40eebf246d0..f72c5257d712771b6aad09bb766732faffa54fd3 100644 (file)
@@ -768,7 +768,7 @@ static const unsigned int icm_matrix[NUM_LANES][CONTROLLERS_PER_LANE] = {
 
 /* Translate OF phandle and args to PHY instance. */
 static struct phy *xpsgtr_xlate(struct device *dev,
-                               struct of_phandle_args *args)
+                               const struct of_phandle_args *args)
 {
        struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
        struct xpsgtr_phy *gtr_phy;
index 7641848be4defd903691d61932521a07c02fdb79..96ef57a7d385c1abc45c6ea1fb2390c225dec0f6 100644 (file)
@@ -685,7 +685,7 @@ static const struct phy_ops sata_phy_ops = {
 };
 
 static struct phy *tegra_xusb_padctl_xlate(struct device *dev,
-                                          struct of_phandle_args *args)
+                                          const struct of_phandle_args *args)
 {
        struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
        unsigned int index = args->args[0];
index f6d607ef0e80146b31962d5842eee1eaa0be20fe..58be86e6fe83ba2a0357d62e00af502b88432b9e 100644 (file)
@@ -176,7 +176,7 @@ struct phy_provider {
        struct module           *owner;
        struct list_head        list;
        struct phy * (*of_xlate)(struct device *dev,
-               struct of_phandle_args *args);
+                                const struct of_phandle_args *args);
 };
 
 /**
@@ -265,7 +265,7 @@ void phy_put(struct device *dev, struct phy *phy);
 void devm_phy_put(struct device *dev, struct phy *phy);
 struct phy *of_phy_get(struct device_node *np, const char *con_id);
 struct phy *of_phy_simple_xlate(struct device *dev,
-       struct of_phandle_args *args);
+                               const struct of_phandle_args *args);
 struct phy *phy_create(struct device *dev, struct device_node *node,
                       const struct phy_ops *ops);
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
@@ -275,11 +275,11 @@ void devm_phy_destroy(struct device *dev, struct phy *phy);
 struct phy_provider *__of_phy_provider_register(struct device *dev,
        struct device_node *children, struct module *owner,
        struct phy * (*of_xlate)(struct device *dev,
-                                struct of_phandle_args *args));
+                                const struct of_phandle_args *args));
 struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
        struct device_node *children, struct module *owner,
        struct phy * (*of_xlate)(struct device *dev,
-                                struct of_phandle_args *args));
+                                const struct of_phandle_args *args));
 void of_phy_provider_unregister(struct phy_provider *phy_provider);
 void devm_of_phy_provider_unregister(struct device *dev,
        struct phy_provider *phy_provider);
@@ -479,7 +479,7 @@ static inline struct phy *of_phy_get(struct device_node *np, const char *con_id)
 }
 
 static inline struct phy *of_phy_simple_xlate(struct device *dev,
-       struct of_phandle_args *args)
+                                             const struct of_phandle_args *args)
 {
        return ERR_PTR(-ENOSYS);
 }
@@ -509,7 +509,7 @@ static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
 static inline struct phy_provider *__of_phy_provider_register(
        struct device *dev, struct device_node *children, struct module *owner,
        struct phy * (*of_xlate)(struct device *dev,
-                                struct of_phandle_args *args))
+                                const struct of_phandle_args *args))
 {
        return ERR_PTR(-ENOSYS);
 }
@@ -517,7 +517,7 @@ static inline struct phy_provider *__of_phy_provider_register(
 static inline struct phy_provider *__devm_of_phy_provider_register(struct device
        *dev, struct device_node *children, struct module *owner,
        struct phy * (*of_xlate)(struct device *dev,
-                                struct of_phandle_args *args))
+                                const struct of_phandle_args *args))
 {
        return ERR_PTR(-ENOSYS);
 }