Merge tag 'phy-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Aug 2021 13:35:24 +0000 (15:35 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Aug 2021 13:35:24 +0000 (15:35 +0200)
Vinod writes:

phy-for-5.15

  - Updates:
        - Yaml conversion for Freescale imx8mq usb phy, TI AM654 SERDES phy,
          Cadence torrent phy
        - Updates for Amlogic Meson8b-usb2 phy, Samsung ufs phy

  - New support:
        - UFS phy for Qualcomm SM6115
- PCIe & USB/DP phy for Qualcomm sc8180x
- USB3 PHY support for Qualcomm IPQ6018
- Renesas USB2.0 PHY for RZ/G2L

* tag 'phy-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (45 commits)
  phy: qcom-qmp: Add support for SM6115 UFS phy
  dt-bindings: phy: qcom,qmp: Add SM6115 UFS PHY bindings
  phy: qmp: Provide unique clock names for DP clocks
  phy: xilinx: zynqmp: skip PHY initialization and PLL lock for USB
  phy: amlogic: meson8b-usb2: don't log an error on -EPROBE_DEFER
  phy: amlogic: meson8b-usb2: Power off the PHY by putting it into reset mode
  phy: phy-mtk-mipi-dsi: convert to devm_platform_ioremap_resource
  phy: phy-mtk-mipi-dsi: remove dummy assignment of error number
  phy: phy-mtk-hdmi: convert to devm_platform_ioremap_resource
  phy: phy-mtk-ufs: use clock bulk to get clocks
  phy: phy-mtk-tphy: remove error log of ioremap failure
  phy: phy-mtk-tphy: print error log using child device
  phy: phy-mtk-tphy: support type switch by pericfg
  phy: phy-mtk-tphy: use clock bulk to get clocks
  dt-bindings: phy: mediatek: tphy: support type switch by pericfg
  phy: cadence-torrent: Check PIPE mode PHY status to be ready for operation
  phy: cadence-torrent: Add debug information for PHY configuration
  phy: cadence-torrent: Add separate functions for reusable code
  phy: cadence-torrent: Add PHY configuration for DP with 100MHz ref clock
  phy: cadence-torrent: Add PHY registers for DP in array format
  ...

29 files changed:
Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.txt [deleted file]
Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/phy/intel,keembay-phy-usb.yaml [moved from Documentation/devicetree/bindings/phy/intel,phy-keembay-usb.yaml with 93% similarity]
Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.txt [deleted file]
Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.yaml [new file with mode: 0644]
drivers/phy/amlogic/phy-meson8b-usb2.c
drivers/phy/cadence/phy-cadence-torrent.c
drivers/phy/mediatek/phy-mtk-hdmi.c
drivers/phy/mediatek/phy-mtk-mipi-dsi.c
drivers/phy/mediatek/phy-mtk-tphy.c
drivers/phy/mediatek/phy-mtk-ufs.c
drivers/phy/qualcomm/phy-qcom-qmp.c
drivers/phy/qualcomm/phy-qcom-qmp.h
drivers/phy/qualcomm/phy-qcom-usb-hs.c
drivers/phy/renesas/phy-rcar-gen3-usb2.c
drivers/phy/rockchip/phy-rockchip-inno-usb2.c
drivers/phy/samsung/Makefile
drivers/phy/samsung/phy-exynos7-ufs.c [moved from drivers/phy/samsung/phy-exynos7-ufs.h with 93% similarity]
drivers/phy/samsung/phy-exynosautov9-ufs.c [new file with mode: 0644]
drivers/phy/samsung/phy-samsung-ufs.c
drivers/phy/samsung/phy-samsung-ufs.h
drivers/phy/tegra/xusb.c
drivers/phy/ti/phy-twl4030-usb.c
drivers/phy/xilinx/phy-zynqmp.c

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.txt b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.txt
deleted file mode 100644 (file)
index 7c70f2a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-* Freescale i.MX8MQ USB3 PHY binding
-
-Required properties:
-- compatible:  Should be "fsl,imx8mq-usb-phy" or "fsl,imx8mp-usb-phy"
-- #phys-cells: must be 0 (see phy-bindings.txt in this directory)
-- reg:         The base address and length of the registers
-- clocks:      phandles to the clocks for each clock listed in clock-names
-- clock-names: must contain "phy"
-
-Optional properties:
-- vbus-supply: A phandle to the regulator for USB VBUS.
-
-Example:
-       usb3_phy0: phy@381f0040 {
-               compatible = "fsl,imx8mq-usb-phy";
-               reg = <0x381f0040 0x40>;
-               clocks = <&clk IMX8MQ_CLK_USB1_PHY_ROOT>;
-               clock-names = "phy";
-               #phy-cells = <0>;
-       };
diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
new file mode 100644 (file)
index 0000000..2936f35
--- /dev/null
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mq-usb-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MQ USB3 PHY binding
+
+maintainers:
+  - Li Jun <jun.li@nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mq-usb-phy
+      - fsl,imx8mp-usb-phy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 0
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: phy
+
+  vbus-supply:
+    description:
+      A phandle to the regulator for USB VBUS.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    usb3_phy0: phy@381f0040 {
+        compatible = "fsl,imx8mq-usb-phy";
+        reg = <0x381f0040 0x40>;
+        clocks = <&clk IMX8MQ_CLK_USB1_PHY_ROOT>;
+        clock-names = "phy";
+        #phy-cells = <0>;
+    };
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/phy/intel,phy-keembay-usb.yaml#
+$id: http://devicetree.org/schemas/phy/intel,keembay-phy-usb.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Intel Keem Bay USB PHY bindings
index ef9d9d4..9e6c0f4 100644 (file)
@@ -15,7 +15,7 @@ description: |
   controllers on MediaTek SoCs, includes USB2.0, USB3.0, PCIe and SATA.
 
   Layout differences of banks between T-PHY V1 (mt8173/mt2701) and
-  T-PHY V2 (mt2712) when works on USB mode:
+  T-PHY V2 (mt2712) / V3 (mt8195) when works on USB mode:
   -----------------------------------
   Version 1:
   port        offset    bank
@@ -34,7 +34,7 @@ description: |
   u2 port2    0x1800    U2PHY_COM
               ...
 
-  Version 2:
+  Version 2/3:
   port        offset    bank
   u2 port0    0x0000    MISC
               0x0100    FMREG
@@ -59,7 +59,8 @@ description: |
 
   SPLLC shared by u3 ports and FMREG shared by u2 ports on V1 are put back
   into each port; a new bank MISC for u2 ports and CHIP for u3 ports are
-  added on V2.
+  added on V2; the FMREG bank for slew rate calibration is not used anymore
+  and reserved on V3;
 
 properties:
   $nodename:
@@ -79,8 +80,11 @@ properties:
               - mediatek,mt2712-tphy
               - mediatek,mt7629-tphy
               - mediatek,mt8183-tphy
-              - mediatek,mt8195-tphy
           - const: mediatek,generic-tphy-v2
+      - items:
+          - enum:
+              - mediatek,mt8195-tphy
+          - const: mediatek,generic-tphy-v3
       - const: mediatek,mt2701-u3phy
         deprecated: true
       - const: mediatek,mt2712-u3phy
@@ -91,7 +95,7 @@ properties:
     description:
       Register shared by multiple ports, exclude port's private register.
       It is needed for T-PHY V1, such as mt2701 and mt8173, but not for
-      T-PHY V2, such as mt2712.
+      T-PHY V2/V3, such as mt2712.
     maxItems: 1
 
   "#address-cells":
@@ -197,6 +201,22 @@ patternProperties:
           Specify the flag to enable BC1.2 if support it
         type: boolean
 
+      mediatek,syscon-type:
+        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
+        description:
+          A phandle to syscon used to access the register of type switch,
+          the field should always be 3 cells long.
+        items:
+          items:
+            - description:
+                The first cell represents a phandle to syscon
+            - description:
+                The second cell represents the register offset
+            - description:
+                The third cell represents the index of config segment
+              enum: [0, 1, 2, 3]
+
     required:
       - reg
       - "#phy-cells"
index f0497b8..75be565 100644 (file)
@@ -18,6 +18,7 @@ properties:
   compatible:
     enum:
       - qcom,ipq6018-qmp-pcie-phy
+      - qcom,ipq6018-qmp-usb3-phy
       - qcom,ipq8074-qmp-pcie-phy
       - qcom,ipq8074-qmp-usb3-phy
       - qcom,msm8996-qmp-pcie-phy
@@ -27,6 +28,7 @@ properties:
       - qcom,msm8998-qmp-ufs-phy
       - qcom,msm8998-qmp-usb3-phy
       - qcom,sc7180-qmp-usb3-phy
+      - qcom,sc8180x-qmp-pcie-phy
       - qcom,sc8180x-qmp-ufs-phy
       - qcom,sc8180x-qmp-usb3-phy
       - qcom,sdm845-qhp-pcie-phy
@@ -34,6 +36,7 @@ properties:
       - qcom,sdm845-qmp-ufs-phy
       - qcom,sdm845-qmp-usb3-phy
       - qcom,sdm845-qmp-usb3-uni-phy
+      - qcom,sm6115-qmp-ufs-phy
       - qcom,sm8150-qmp-ufs-phy
       - qcom,sm8150-qmp-usb3-phy
       - qcom,sm8150-qmp-usb3-uni-phy
@@ -326,6 +329,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,sc8180x-qmp-pcie-phy
               - qcom,sdm845-qhp-pcie-phy
               - qcom,sdm845-qmp-pcie-phy
               - qcom,sdx55-qmp-pcie-phy
index 217aa6c..1d49cc3 100644 (file)
@@ -14,6 +14,7 @@ properties:
   compatible:
     enum:
       - qcom,sc7180-qmp-usb3-dp-phy
+      - qcom,sc8180x-qmp-usb3-dp-phy
       - qcom,sdm845-qmp-usb3-dp-phy
       - qcom,sm8250-qmp-usb3-dp-phy
   reg:
index d5dc5a3..3a6e116 100644 (file)
@@ -30,6 +30,11 @@ properties:
               - renesas,usb2-phy-r8a77995 # R-Car D3
           - const: renesas,rcar-gen3-usb2-phy
 
+      - items:
+          - enum:
+              - renesas,usb2-phy-r9a07g044 # RZ/G2{L,LC}
+          - const: renesas,rzg2l-usb2-phy  # RZ/G2L family
+
   reg:
     maxItems: 1
 
@@ -91,6 +96,16 @@ required:
   - clocks
   - '#phy-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,rzg2l-usb2-phy
+    then:
+      required:
+        - resets
+
 additionalProperties: false
 
 examples:
index 636cc50..f6ed1a0 100644 (file)
@@ -16,6 +16,7 @@ properties:
   compatible:
     enum:
       - samsung,exynos7-ufs-phy
+      - samsung,exynosautov9-ufs-phy
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.txt b/Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.txt
deleted file mode 100644 (file)
index 64b286d..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-TI AM654 SERDES
-
-Required properties:
- - compatible: Should be "ti,phy-am654-serdes"
- - reg : Address and length of the register set for the device.
- - #phy-cells: determine the number of cells that should be given in the
-       phandle while referencing this phy. Should be "2". The 1st cell
-       corresponds to the phy type (should be one of the types specified in
-       include/dt-bindings/phy/phy.h) and the 2nd cell should be the serdes
-       lane function.
-       If SERDES0 is referenced 2nd cell should be:
-               0 - USB3
-               1 - PCIe0 Lane0
-               2 - ICSS2 SGMII Lane0
-       If SERDES1 is referenced 2nd cell should be:
-               0 - PCIe1 Lane0
-               1 - PCIe0 Lane1
-               2 - ICSS2 SGMII Lane1
- - power-domains: As documented by the generic PM domain bindings in
-       Documentation/devicetree/bindings/power/power_domain.txt.
- - clocks: List of clock-specifiers representing the input to the SERDES.
-       Should have 3 items representing the left input clock, external
-       reference clock and right input clock in that order.
- - clock-output-names: List of clock names for each of the clock outputs of
-       SERDES. Should have 3 items for CMU reference clock,
-       left output clock and right output clock in that order.
- - assigned-clocks: As defined in
-       Documentation/devicetree/bindings/clock/clock-bindings.txt
- - assigned-clock-parents: As defined in
-       Documentation/devicetree/bindings/clock/clock-bindings.txt
- - #clock-cells: Should be <1> to choose between the 3 output clocks.
-       Defined in Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-   The following macros are defined in dt-bindings/phy/phy-am654-serdes.h
-   for selecting the correct reference clock. This can be used while
-   specifying the clocks created by SERDES.
-       => AM654_SERDES_CMU_REFCLK
-       => AM654_SERDES_LO_REFCLK
-       => AM654_SERDES_RO_REFCLK
-
- - mux-controls: Phandle to the multiplexer that is used to select the lane
-       function. See #phy-cells above to see the multiplex values.
-
-Example:
-
-Example for SERDES0 is given below. It has 3 clock inputs;
-left input reference clock as indicated by <&k3_clks 153 4>, external
-reference clock as indicated by <&k3_clks 153 1> and right input
-reference clock as indicated by <&serdes1 AM654_SERDES_LO_REFCLK>. (The
-right input of SERDES0 is connected to the left output of SERDES1).
-
-SERDES0 registers 3 clock outputs as indicated in clock-output-names. The
-first refers to the CMU reference clock, second refers to the left output
-reference clock and the third refers to the right output reference clock.
-
-The assigned-clocks and assigned-clock-parents is used here to set the
-parent of left input reference clock to MAINHSDIV_CLKOUT4 and parent of
-CMU reference clock to left input reference clock.
-
-serdes0: serdes@900000 {
-       compatible = "ti,phy-am654-serdes";
-       reg = <0x0 0x900000 0x0 0x2000>;
-       reg-names = "serdes";
-       #phy-cells = <2>;
-       power-domains = <&k3_pds 153>;
-       clocks = <&k3_clks 153 4>, <&k3_clks 153 1>,
-                       <&serdes1 AM654_SERDES_LO_REFCLK>;
-       clock-output-names = "serdes0_cmu_refclk", "serdes0_lo_refclk",
-                               "serdes0_ro_refclk";
-       assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
-       assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>;
-       ti,serdes-clk = <&serdes0_clk>;
-       mux-controls = <&serdes_mux 0>;
-       #clock-cells = <1>;
-};
-
-Example for PCIe consumer node using the SERDES PHY specifier is given below.
-&pcie0_rc {
-        num-lanes = <2>;
-        phys = <&serdes0 PHY_TYPE_PCIE 1>, <&serdes1 PHY_TYPE_PCIE 1>;
-        phy-names = "pcie-phy0", "pcie-phy1";
-};
diff --git a/Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.yaml b/Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.yaml
new file mode 100644 (file)
index 0000000..62dcb84
--- /dev/null
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/ti,phy-am654-serdes.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI AM654 SERDES binding
+
+description:
+  This binding describes the TI AM654 SERDES. AM654 SERDES can be configured
+  to be used with either PCIe or USB or SGMII.
+
+maintainers:
+  - Kishon Vijay Abraham I <kishon@ti.com>
+
+properties:
+  compatible:
+    enum:
+      - ti,phy-am654-serdes
+
+  reg:
+    maxItems: 1
+
+  reg-names:
+    items:
+      - const: serdes
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    maxItems: 3
+    description:
+      Three input clocks referring to left input reference clock, refclk and right input reference
+      clock.
+
+  assigned-clocks:
+    $ref: "/schemas/types.yaml#/definitions/phandle-array"
+  assigned-clock-parents:
+    $ref: "/schemas/types.yaml#/definitions/phandle-array"
+
+  '#phy-cells':
+    const: 2
+    description:
+      The 1st cell corresponds to the phy type (should be one of the types specified in
+      include/dt-bindings/phy/phy.h) and the 2nd cell should be the serdes lane function.
+
+  ti,serdes-clk:
+    description: Phandle to the SYSCON entry required for configuring SERDES clock selection.
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  '#clock-cells':
+    const: 1
+
+  mux-controls:
+    maxItems: 1
+    description: Phandle to the SYSCON entry required for configuring SERDES lane function.
+
+  clock-output-names:
+    oneOf:
+      - description: Clock output names for SERDES 0
+        items:
+          - const: serdes0_cmu_refclk
+          - const: serdes0_lo_refclk
+          - const: serdes0_ro_refclk
+      - description: Clock output names for SERDES 1
+        items:
+          - const: serdes1_cmu_refclk
+          - const: serdes1_lo_refclk
+          - const: serdes1_ro_refclk
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - assigned-clocks
+  - assigned-clock-parents
+  - ti,serdes-clk
+  - mux-controls
+  - clock-output-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/phy/phy-am654-serdes.h>
+
+    serdes0: serdes@900000 {
+      compatible = "ti,phy-am654-serdes";
+      reg = <0x900000 0x2000>;
+      reg-names = "serdes";
+      #phy-cells = <2>;
+      power-domains = <&k3_pds 153>;
+      clocks = <&k3_clks 153 4>, <&k3_clks 153 1>,
+               <&serdes1 AM654_SERDES_LO_REFCLK>;
+      clock-output-names = "serdes0_cmu_refclk", "serdes0_lo_refclk", "serdes0_ro_refclk";
+      assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+      assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>;
+      ti,serdes-clk = <&serdes0_clk>;
+      mux-controls = <&serdes_mux 0>;
+      #clock-cells = <1>;
+    };
index 03c061d..cf10bed 100644 (file)
@@ -219,6 +219,10 @@ static int phy_meson8b_usb2_power_off(struct phy *phy)
        clk_disable_unprepare(priv->clk_usb);
        clk_disable_unprepare(priv->clk_usb_general);
 
+       /* power off the PHY by putting it into reset mode */
+       regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
+                          REG_CTRL_POWER_ON_RESET);
+
        return 0;
 }
 
@@ -273,8 +277,8 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
 
        phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops);
        if (IS_ERR(phy)) {
-               dev_err(&pdev->dev, "failed to create PHY\n");
-               return PTR_ERR(phy);
+               return dev_err_probe(&pdev->dev, PTR_ERR(phy),
+                                    "failed to create PHY\n");
        }
 
        phy_set_drvdata(phy, priv);
index 0477e7b..415ace6 100644 (file)
 #include <linux/reset.h>
 #include <linux/regmap.h>
 
-#define REF_CLK_19_2MHz                19200000
-#define REF_CLK_25MHz          25000000
+#define REF_CLK_19_2MHZ                19200000
+#define REF_CLK_25MHZ          25000000
+#define REF_CLK_100MHZ         100000000
 
 #define MAX_NUM_LANES          4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE           3
+#define NUM_REF_CLK            3
 #define NUM_PHY_TYPE           6
 
 #define POLL_TIMEOUT_US                5000
 #define TORRENT_PHY_PCS_COMMON_OFFSET(block_offset)    \
                                (0xC000 << (block_offset))
 
+#define TORRENT_PHY_PCS_LANE_CDB_OFFSET(ln, block_offset, reg_offset)  \
+                               ((0xD000 << (block_offset)) +           \
+                               (((ln) << 8) << (reg_offset)))
+
 #define TORRENT_PHY_PMA_COMMON_OFFSET(block_offset)    \
                                (0xE000 << (block_offset))
 
 #define CMN_PLL0_FRACDIVH_M0           0x0092U
 #define CMN_PLL0_HIGH_THR_M0           0x0093U
 #define CMN_PLL0_DSM_DIAG_M0           0x0094U
+#define CMN_PLL0_DSM_FBH_OVRD_M0       0x0095U
 #define CMN_PLL0_SS_CTRL1_M0           0x0098U
 #define CMN_PLL0_SS_CTRL2_M0            0x0099U
 #define CMN_PLL0_SS_CTRL3_M0            0x009AU
 #define PHY_PIPE_USB3_GEN2_POST_CFG0   0x0022U
 #define PHY_PIPE_USB3_GEN2_POST_CFG1   0x0023U
 
+/* PHY PCS lane registers */
+#define PHY_PCS_ISO_LINK_CTRL          0x000BU
+
 /* PHY PMA common registers */
 #define PHY_PMA_CMN_CTRL1              0x0000U
 #define PHY_PMA_CMN_CTRL2              0x0001U
@@ -244,6 +254,9 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
                                REG_FIELD(PHY_RESET, 8, 8);
 
+static const struct reg_field phy_pcs_iso_link_ctrl_1 =
+                               REG_FIELD(PHY_PCS_ISO_LINK_CTRL, 1, 1);
+
 static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0);
 
 #define REFCLK_OUT_NUM_CMN_CONFIG      5
@@ -273,6 +286,12 @@ enum cdns_torrent_phy_type {
        TYPE_USB,
 };
 
+enum cdns_torrent_ref_clk {
+       CLK_19_2_MHZ,
+       CLK_25_MHZ,
+       CLK_100_MHZ
+};
+
 enum cdns_torrent_ssc_mode {
        NO_SSC,
        EXTERNAL_SSC,
@@ -296,7 +315,7 @@ struct cdns_torrent_phy {
        struct reset_control *apb_rst;
        struct device *dev;
        struct clk *clk;
-       unsigned long ref_clk_rate;
+       enum cdns_torrent_ref_clk ref_clk_rate;
        struct cdns_torrent_inst phys[MAX_NUM_LANES];
        int nsubnodes;
        const struct cdns_torrent_data *init_data;
@@ -306,12 +325,14 @@ struct cdns_torrent_phy {
        struct regmap *regmap_phy_pma_common_cdb;
        struct regmap *regmap_tx_lane_cdb[MAX_NUM_LANES];
        struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
+       struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES];
        struct regmap *regmap_dptx_phy_reg;
        struct regmap_field *phy_pll_cfg;
        struct regmap_field *phy_pma_cmn_ctrl_1;
        struct regmap_field *phy_pma_cmn_ctrl_2;
        struct regmap_field *phy_pma_pll_raw_ctrl;
        struct regmap_field *phy_reset_ctrl;
+       struct regmap_field *phy_pcs_iso_link_ctrl_1[MAX_NUM_LANES];
        struct clk *clks[CDNS_TORRENT_REFCLK_DRIVER + 1];
        struct clk_onecell_data clk_data;
 };
@@ -333,57 +354,6 @@ struct cdns_torrent_derived_refclk {
 #define to_cdns_torrent_derived_refclk(_hw)    \
                        container_of(_hw, struct cdns_torrent_derived_refclk, hw)
 
-static int cdns_torrent_phy_init(struct phy *phy);
-static int cdns_torrent_dp_init(struct phy *phy);
-static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
-                              u32 num_lanes);
-static
-int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy);
-static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
-                                   struct cdns_torrent_inst *inst);
-static
-void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy);
-static
-void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
-                                            u32 rate, bool ssc);
-static
-void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
-static
-void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
-                                          u32 rate, bool ssc);
-static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
-                                        unsigned int lane);
-static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
-                                        u32 rate, u32 num_lanes);
-static int cdns_torrent_dp_configure(struct phy *phy,
-                                    union phy_configure_opts *opts);
-static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
-                                          u32 num_lanes,
-                                          enum phy_powerstate powerstate);
-static int cdns_torrent_phy_on(struct phy *phy);
-static int cdns_torrent_phy_off(struct phy *phy);
-
-static const struct phy_ops cdns_torrent_phy_ops = {
-       .init           = cdns_torrent_phy_init,
-       .configure      = cdns_torrent_dp_configure,
-       .power_on       = cdns_torrent_phy_on,
-       .power_off      = cdns_torrent_phy_off,
-       .owner          = THIS_MODULE,
-};
-
-static int cdns_torrent_noop_phy_on(struct phy *phy)
-{
-       /* Give 5ms to 10ms delay for the PIPE clock to be stable */
-       usleep_range(5000, 10000);
-
-       return 0;
-}
-
-static const struct phy_ops noop_ops = {
-       .power_on       = cdns_torrent_noop_phy_on,
-       .owner          = THIS_MODULE,
-};
-
 struct cdns_reg_pairs {
        u32 val;
        u32 off;
@@ -403,12 +373,12 @@ struct cdns_torrent_data {
                                                [NUM_SSC_MODE];
        struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
                                              [NUM_SSC_MODE];
-       struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
-                                         [NUM_SSC_MODE];
-       struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
-                                           [NUM_SSC_MODE];
-       struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
-                                           [NUM_SSC_MODE];
+       struct cdns_torrent_vals *cmn_vals[NUM_REF_CLK][NUM_PHY_TYPE]
+                                         [NUM_PHY_TYPE][NUM_SSC_MODE];
+       struct cdns_torrent_vals *tx_ln_vals[NUM_REF_CLK][NUM_PHY_TYPE]
+                                           [NUM_PHY_TYPE][NUM_SSC_MODE];
+       struct cdns_torrent_vals *rx_ln_vals[NUM_REF_CLK][NUM_PHY_TYPE]
+                                           [NUM_PHY_TYPE][NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -497,6 +467,22 @@ static const struct regmap_config cdns_torrent_common_cdb_config = {
        .reg_read = cdns_regmap_read,
 };
 
+#define TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF(n) \
+{ \
+       .name = "torrent_phy_pcs_lane" n "_cdb", \
+       .reg_stride = 1, \
+       .fast_io = true, \
+       .reg_write = cdns_regmap_write, \
+       .reg_read = cdns_regmap_read, \
+}
+
+static const struct regmap_config cdns_torrent_phy_pcs_lane_cdb_config[] = {
+       TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("0"),
+       TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("1"),
+       TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("2"),
+       TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("3"),
+};
+
 static const struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = {
        .name = "torrent_phy_pcs_cmn_cdb",
        .reg_stride = 1,
@@ -615,444 +601,500 @@ static const struct coefficients vltg_coeff[4][4] = {
        }
 };
 
-/*
- * Enable or disable PLL for selected lanes.
- */
-static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy,
-                                     struct phy_configure_opts_dp *dp,
-                                     bool enable)
+static const char *cdns_torrent_get_phy_type(enum cdns_torrent_phy_type phy_type)
 {
-       u32 rd_val;
-       u32 ret;
-       struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
-
-       /*
-        * Used to determine, which bits to check for or enable in
-        * PHY_PMA_XCVR_PLLCLK_EN register.
-        */
-       u32 pll_bits;
-       /* Used to enable or disable lanes. */
-       u32 pll_val;
-
-       /* Select values of registers and mask, depending on enabled lane
-        * count.
-        */
-       switch (dp->lanes) {
-       /* lane 0 */
-       case (1):
-               pll_bits = 0x00000001;
-               break;
-       /* lanes 0-1 */
-       case (2):
-               pll_bits = 0x00000003;
-               break;
-       /* lanes 0-3, all */
+       switch (phy_type) {
+       case TYPE_DP:
+               return "DisplayPort";
+       case TYPE_PCIE:
+               return "PCIe";
+       case TYPE_SGMII:
+               return "SGMII";
+       case TYPE_QSGMII:
+               return "QSGMII";
+       case TYPE_USB:
+               return "USB";
        default:
-               pll_bits = 0x0000000F;
-               break;
+               return "None";
        }
-
-       if (enable)
-               pll_val = pll_bits;
-       else
-               pll_val = 0x00000000;
-
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_val);
-
-       /* Wait for acknowledgment from PHY. */
-       ret = regmap_read_poll_timeout(regmap,
-                                      PHY_PMA_XCVR_PLLCLK_EN_ACK,
-                                      rd_val,
-                                      (rd_val & pll_bits) == pll_val,
-                                      0, POLL_TIMEOUT_US);
-       ndelay(100);
-       return ret;
 }
 
 /*
- * Perform register operations related to setting link rate, once powerstate is
- * set and PLL disable request was processed.
+ * Set registers responsible for enabling and configuring SSC, with second and
+ * third register values provided by parameters.
  */
-static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy,
-                                         struct phy_configure_opts_dp *dp)
+static
+void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
+                                       u32 ctrl2_val, u32 ctrl3_val)
 {
-       u32 ret;
-       u32 read_val;
+       struct regmap *regmap = cdns_phy->regmap_common_cdb;
 
-       /* Disable the cmn_pll0_en before re-programming the new data rate. */
-       regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
+}
 
-       /*
-        * Wait for PLL ready de-assertion.
-        * For PLL0 - PHY_PMA_CMN_CTRL2[2] == 1
-        */
-       ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
-                                            read_val,
-                                            ((read_val >> 2) & 0x01) != 0,
-                                            0, POLL_TIMEOUT_US);
-       if (ret)
-               return ret;
-       ndelay(200);
+static
+void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
+                                            u32 rate, bool ssc)
+{
+       struct regmap *regmap = cdns_phy->regmap_common_cdb;
 
-       /* DP Rate Change - VCO Output settings. */
-       if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) {
-               /* PMA common configuration 19.2MHz */
-               cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate,
-                                                       dp->ssc);
-               cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-       } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) {
-               /* PMA common configuration 25MHz */
-               cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate,
-                                                     dp->ssc);
-               cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
+       /* Assumes 19.2 MHz refclock */
+       switch (rate) {
+       /* Setting VCO for 10.8GHz */
+       case 2700:
+       case 5400:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0119);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x4000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00BC);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0012);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0119);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x4000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00BC);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A, 0x006A);
+               break;
+       /* Setting VCO for 9.72GHz */
+       case 1620:
+       case 2430:
+       case 3240:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01FA);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x4000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0152);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01FA);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x4000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0152);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD, 0x0069);
+               break;
+       /* Setting VCO for 8.64GHz */
+       case 2160:
+       case 4320:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01C2);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x012C);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01C2);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x012C);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536, 0x0069);
+               break;
+       /* Setting VCO for 8.1GHz */
+       case 8100:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01A5);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xE000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x011A);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01A5);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xE000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x011A);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7, 0x006A);
+               break;
        }
-       cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
 
-       /* Enable the cmn_pll0_en. */
-       regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x3);
+       if (ssc) {
+               cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_PLLCNT_START, 0x025E);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_PLLCNT_START, 0x025E);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
+       } else {
+               cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_PLLCNT_START, 0x0260);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_PLLCNT_START, 0x0260);
+               /* Set reset register values to disable SSC */
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL2_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL3_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL2_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL3_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
+       }
 
-       /*
-        * Wait for PLL ready assertion.
-        * For PLL0 - PHY_PMA_CMN_CTRL2[0] == 1
-        */
-       ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
-                                            read_val,
-                                            (read_val & 0x01) != 0,
-                                            0, POLL_TIMEOUT_US);
-       return ret;
+       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x0099);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x0099);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x0099);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099);
 }
 
 /*
- * Verify, that parameters to configure PHY with are correct.
+ * Set registers responsible for enabling and configuring SSC, with second
+ * register value provided by a parameter.
  */
-static int cdns_torrent_dp_verify_config(struct cdns_torrent_inst *inst,
-                                        struct phy_configure_opts_dp *dp)
+static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy,
+                                            u32 ctrl2_val)
 {
-       u8 i;
-
-       /* If changing link rate was required, verify it's supported. */
-       if (dp->set_rate) {
-               switch (dp->link_rate) {
-               case 1620:
-               case 2160:
-               case 2430:
-               case 2700:
-               case 3240:
-               case 4320:
-               case 5400:
-               case 8100:
-                       /* valid bit rate */
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
+       struct regmap *regmap = cdns_phy->regmap_common_cdb;
 
-       /* Verify lane count. */
-       switch (dp->lanes) {
-       case 1:
-       case 2:
-       case 4:
-               /* valid lane count. */
-               break;
-       default:
-               return -EINVAL;
-       }
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
+}
 
-       /* Check against actual number of PHY's lanes. */
-       if (dp->lanes > inst->num_lanes)
-               return -EINVAL;
+static
+void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
+                                          u32 rate, bool ssc)
+{
+       struct regmap *regmap = cdns_phy->regmap_common_cdb;
 
-       /*
-        * If changing voltages is required, check swing and pre-emphasis
-        * levels, per-lane.
-        */
-       if (dp->set_voltages) {
-               /* Lane count verified previously. */
-               for (i = 0; i < dp->lanes; i++) {
-                       if (dp->voltage[i] > 3 || dp->pre[i] > 3)
-                               return -EINVAL;
+       /* Assumes 25 MHz refclock */
+       switch (rate) {
+       /* Setting VCO for 10.8GHz */
+       case 2700:
+       case 5400:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
+               break;
+       /* Setting VCO for 9.72GHz */
+       case 1620:
+       case 2430:
+       case 3240:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
+               break;
+       /* Setting VCO for 8.64GHz */
+       case 2160:
+       case 4320:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
+               break;
+       /* Setting VCO for 8.1GHz */
+       case 8100:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00D8);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0144);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00D8);
+               if (ssc)
+                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A);
+               break;
+       }
 
-                       /* Sum of voltage swing and pre-emphasis levels cannot
-                        * exceed 3.
-                        */
-                       if (dp->voltage[i] + dp->pre[i] > 3)
-                               return -EINVAL;
-               }
+       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+
+       if (ssc) {
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL0_VCOCAL_PLLCNT_START, 0x0315);
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL1_VCOCAL_PLLCNT_START, 0x0315);
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
+       } else {
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL0_VCOCAL_PLLCNT_START, 0x0317);
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL1_VCOCAL_PLLCNT_START, 0x0317);
+               /* Set reset register values to disable SSC */
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL2_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL3_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0000);
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL2_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL3_M0, 0x0000);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0000);
+               cdns_torrent_phy_write(regmap,
+                                      CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
        }
 
-       return 0;
+       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x00C7);
+       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x00C7);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x00C7);
+       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7);
 }
 
-/* Set power state A0 and PLL clock enable to 0 on enabled lanes. */
-static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy,
-                                      u32 num_lanes)
+static
+void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct cdns_torrent_phy *cdns_phy,
+                                           u32 rate, bool ssc)
 {
-       struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
-       u32 pwr_state = cdns_torrent_dp_read(regmap,
-                                            PHY_PMA_XCVR_POWER_STATE_REQ);
-       u32 pll_clk_en = cdns_torrent_dp_read(regmap,
-                                             PHY_PMA_XCVR_PLLCLK_EN);
-
-       /* Lane 0 is always enabled. */
-       pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
-                      PHY_POWER_STATE_LN_0);
-       pll_clk_en &= ~0x01U;
-
-       if (num_lanes > 1) {
-               /* lane 1 */
-               pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
-                              PHY_POWER_STATE_LN_1);
-               pll_clk_en &= ~(0x01U << 1);
-       }
+       struct regmap *regmap = cdns_phy->regmap_common_cdb;
 
-       if (num_lanes > 2) {
-               /* lanes 2 and 3 */
-               pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
-                              PHY_POWER_STATE_LN_2);
-               pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
-                              PHY_POWER_STATE_LN_3);
-               pll_clk_en &= ~(0x01U << 2);
-               pll_clk_en &= ~(0x01U << 3);
+       /* Assumes 100 MHz refclock */
+       switch (rate) {
+       /* Setting VCO for 10.8GHz */
+       case 2700:
+       case 5400:
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0028);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_FBH_OVRD_M0, 0x0022);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBH_OVRD_M0, 0x0022);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBL_OVRD_M0, 0x000C);
+               break;
+       /* Setting VCO for 9.72GHz */
+       case 1620:
+       case 2430:
+       case 3240:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0061);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0061);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x3333);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x3333);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0042);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0042);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+               break;
+       /* Setting VCO for 8.64GHz */
+       case 2160:
+       case 4320:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0056);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0056);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x6666);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x6666);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x003A);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x003A);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+               break;
+       /* Setting VCO for 8.1GHz */
+       case 8100:
+               cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0051);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0051);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0036);
+               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0036);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+               cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+               break;
        }
-
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, pwr_state);
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_clk_en);
 }
 
-/* Configure lane count as required. */
-static int cdns_torrent_dp_set_lanes(struct cdns_torrent_phy *cdns_phy,
-                                    struct phy_configure_opts_dp *dp)
+/*
+ * Enable or disable PLL for selected lanes.
+ */
+static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy,
+                                     struct phy_configure_opts_dp *dp,
+                                     bool enable)
 {
-       u32 value;
+       u32 rd_val;
        u32 ret;
        struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
-       u8 lane_mask = (1 << dp->lanes) - 1;
-
-       value = cdns_torrent_dp_read(regmap, PHY_RESET);
-       /* clear pma_tx_elec_idle_ln_* bits. */
-       value &= ~PMA_TX_ELEC_IDLE_MASK;
-       /* Assert pma_tx_elec_idle_ln_* for disabled lanes. */
-       value |= ((~lane_mask) << PMA_TX_ELEC_IDLE_SHIFT) &
-                PMA_TX_ELEC_IDLE_MASK;
-       cdns_torrent_dp_write(regmap, PHY_RESET, value);
-
-       /* reset the link by asserting phy_l00_reset_n low */
-       cdns_torrent_dp_write(regmap, PHY_RESET,
-                             value & (~PHY_L00_RESET_N_MASK));
 
        /*
-        * Assert lane reset on unused lanes and lane 0 so they remain in reset
-        * and powered down when re-enabling the link
+        * Used to determine, which bits to check for or enable in
+        * PHY_PMA_XCVR_PLLCLK_EN register.
         */
-       value = (value & 0x0000FFF0) | (0x0000000E & lane_mask);
-       cdns_torrent_dp_write(regmap, PHY_RESET, value);
+       u32 pll_bits;
+       /* Used to enable or disable lanes. */
+       u32 pll_val;
 
-       cdns_torrent_dp_set_a0_pll(cdns_phy, dp->lanes);
+       /* Select values of registers and mask, depending on enabled lane
+        * count.
+        */
+       switch (dp->lanes) {
+       /* lane 0 */
+       case (1):
+               pll_bits = 0x00000001;
+               break;
+       /* lanes 0-1 */
+       case (2):
+               pll_bits = 0x00000003;
+               break;
+       /* lanes 0-3, all */
+       default:
+               pll_bits = 0x0000000F;
+               break;
+       }
 
-       /* release phy_l0*_reset_n based on used laneCount */
-       value = (value & 0x0000FFF0) | (0x0000000F & lane_mask);
-       cdns_torrent_dp_write(regmap, PHY_RESET, value);
+       if (enable)
+               pll_val = pll_bits;
+       else
+               pll_val = 0x00000000;
 
-       /* Wait, until PHY gets ready after releasing PHY reset signal. */
-       ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
-       if (ret)
-               return ret;
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_val);
 
+       /* Wait for acknowledgment from PHY. */
+       ret = regmap_read_poll_timeout(regmap,
+                                      PHY_PMA_XCVR_PLLCLK_EN_ACK,
+                                      rd_val,
+                                      (rd_val & pll_bits) == pll_val,
+                                      0, POLL_TIMEOUT_US);
        ndelay(100);
-
-       /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
-
-       ret = cdns_torrent_dp_run(cdns_phy, dp->lanes);
-
        return ret;
 }
 
-/* Configure link rate as required. */
-static int cdns_torrent_dp_set_rate(struct cdns_torrent_phy *cdns_phy,
-                                   struct phy_configure_opts_dp *dp)
+static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
+                                          u32 num_lanes,
+                                          enum phy_powerstate powerstate)
 {
+       /* Register value for power state for a single byte. */
+       u32 value_part;
+       u32 value;
+       u32 mask;
+       u32 read_val;
        u32 ret;
+       struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
-       ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
-                                             POWERSTATE_A3);
-       if (ret)
-               return ret;
-       ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, false);
-       if (ret)
-               return ret;
-       ndelay(200);
-
-       ret = cdns_torrent_dp_configure_rate(cdns_phy, dp);
-       if (ret)
-               return ret;
-       ndelay(200);
-
-       ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, true);
-       if (ret)
-               return ret;
-       ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
-                                             POWERSTATE_A2);
-       if (ret)
-               return ret;
-       ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
-                                             POWERSTATE_A0);
-       if (ret)
-               return ret;
-       ndelay(900);
-
-       return ret;
-}
-
-/* Configure voltage swing and pre-emphasis for all enabled lanes. */
-static void cdns_torrent_dp_set_voltages(struct cdns_torrent_phy *cdns_phy,
-                                        struct phy_configure_opts_dp *dp)
-{
-       u8 lane;
-       u16 val;
-
-       for (lane = 0; lane < dp->lanes; lane++) {
-               val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
-                                           TX_DIAG_ACYA);
-               /*
-                * Write 1 to register bit TX_DIAG_ACYA[0] to freeze the
-                * current state of the analog TX driver.
-                */
-               val |= TX_DIAG_ACYA_HBDC_MASK;
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_DIAG_ACYA, val);
-
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_TXCC_CTRL, 0x08A4);
-               val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].diag_tx_drv;
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      DRV_DIAG_TX_DRV, val);
-               val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].mgnfs_mult;
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_TXCC_MGNFS_MULT_000,
-                                      val);
-               val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].cpost_mult;
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_TXCC_CPOST_MULT_00,
-                                      val);
-
-               val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
-                                           TX_DIAG_ACYA);
-               /*
-                * Write 0 to register bit TX_DIAG_ACYA[0] to allow the state of
-                * analog TX driver to reflect the new programmed one.
-                */
-               val &= ~TX_DIAG_ACYA_HBDC_MASK;
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_DIAG_ACYA, val);
-       }
-};
-
-static int cdns_torrent_dp_configure(struct phy *phy,
-                                    union phy_configure_opts *opts)
-{
-       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
-       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
-       int ret;
-
-       ret = cdns_torrent_dp_verify_config(inst, &opts->dp);
-       if (ret) {
-               dev_err(&phy->dev, "invalid params for phy configure\n");
-               return ret;
-       }
-
-       if (opts->dp.set_lanes) {
-               ret = cdns_torrent_dp_set_lanes(cdns_phy, &opts->dp);
-               if (ret) {
-                       dev_err(&phy->dev, "cdns_torrent_dp_set_lanes failed\n");
-                       return ret;
-               }
+       switch (powerstate) {
+       case (POWERSTATE_A0):
+               value_part = 0x01U;
+               break;
+       case (POWERSTATE_A2):
+               value_part = 0x04U;
+               break;
+       default:
+               /* Powerstate A3 */
+               value_part = 0x08U;
+               break;
        }
 
-       if (opts->dp.set_rate) {
-               ret = cdns_torrent_dp_set_rate(cdns_phy, &opts->dp);
-               if (ret) {
-                       dev_err(&phy->dev, "cdns_torrent_dp_set_rate failed\n");
-                       return ret;
-               }
+       /* Select values of registers and mask, depending on enabled
+        * lane count.
+        */
+       switch (num_lanes) {
+       /* lane 0 */
+       case (1):
+               value = value_part;
+               mask = 0x0000003FU;
+               break;
+       /* lanes 0-1 */
+       case (2):
+               value = (value_part
+                        | (value_part << 8));
+               mask = 0x00003F3FU;
+               break;
+       /* lanes 0-3, all */
+       default:
+               value = (value_part
+                        | (value_part << 8)
+                        | (value_part << 16)
+                        | (value_part << 24));
+               mask = 0x3F3F3F3FU;
+               break;
        }
 
-       if (opts->dp.set_voltages)
-               cdns_torrent_dp_set_voltages(cdns_phy, &opts->dp);
+       /* Set power state A<n>. */
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, value);
+       /* Wait, until PHY acknowledges power state completion. */
+       ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK,
+                                      read_val, (read_val & mask) == value, 0,
+                                      POLL_TIMEOUT_US);
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000);
+       ndelay(100);
 
        return ret;
 }
 
-static int cdns_torrent_dp_init(struct phy *phy)
+static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes)
 {
-       unsigned char lane_bits;
+       unsigned int read_val;
        int ret;
-       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
-       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
        struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
-       switch (cdns_phy->ref_clk_rate) {
-       case REF_CLK_19_2MHz:
-       case REF_CLK_25MHz:
-               /* Valid Ref Clock Rate */
-               break;
-       default:
-               dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
-               return -EINVAL;
-       }
-
-       cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */
-
-       /* PHY PMA registers configuration function */
-       cdns_torrent_dp_pma_cfg(cdns_phy, inst);
-
-       /*
-        * Set lines power state to A0
-        * Set lines pll clk enable to 0
-        */
-       cdns_torrent_dp_set_a0_pll(cdns_phy, inst->num_lanes);
-
        /*
-        * release phy_l0*_reset_n and pma_tx_elec_idle_ln_* based on
-        * used lanes
+        * waiting for ACK of pma_xcvr_pllclk_en_ln_*, only for the
+        * master lane
         */
-       lane_bits = (1 << inst->num_lanes) - 1;
-       cdns_torrent_dp_write(regmap, PHY_RESET,
-                             ((0xF & ~lane_bits) << 4) | (0xF & lane_bits));
-
-       /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
-
-       /* PHY PMA registers configuration functions */
-       /* Initialize PHY with max supported link rate, without SSC. */
-       if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
-               cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
-                                                       cdns_phy->max_bit_rate,
-                                                       false);
-       else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
-               cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
-                                                     cdns_phy->max_bit_rate,
-                                                     false);
-       cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate,
-                                    inst->num_lanes);
-
-       /* take out of reset */
-       regmap_field_write(cdns_phy->phy_reset_ctrl, 0x1);
+       ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_PLLCLK_EN_ACK,
+                                      read_val, read_val & 1,
+                                      0, POLL_TIMEOUT_US);
+       if (ret == -ETIMEDOUT) {
+               dev_err(cdns_phy->dev,
+                       "timeout waiting for link PLL clock enable ack\n");
+               return ret;
+       }
 
-       cdns_torrent_phy_on(phy);
+       ndelay(100);
 
-       ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
+       ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
+                                             POWERSTATE_A2);
        if (ret)
                return ret;
 
-       ret = cdns_torrent_dp_run(cdns_phy, inst->num_lanes);
+       ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
+                                             POWERSTATE_A0);
 
        return ret;
 }
 
-static
-int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
+static int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
 {
        unsigned int reg;
        int ret;
@@ -1069,599 +1111,508 @@ int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
        return 0;
 }
 
-static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
-                                   struct cdns_torrent_inst *inst)
+static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
+                                        u32 rate, u32 num_lanes)
 {
+       unsigned int clk_sel_val = 0;
+       unsigned int hsclk_div_val = 0;
        unsigned int i;
 
-       if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
-               /* PMA common configuration 19.2MHz */
-               cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-       else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
-               /* PMA common configuration 25MHz */
-               cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
-
-       /* PMA lane configuration to deal with multi-link operation */
-       for (i = 0; i < inst->num_lanes; i++)
-               cdns_torrent_dp_pma_lane_cfg(cdns_phy, i);
-}
+       switch (rate) {
+       case 1620:
+               clk_sel_val = 0x0f01;
+               hsclk_div_val = 2;
+               break;
+       case 2160:
+       case 2430:
+       case 2700:
+               clk_sel_val = 0x0701;
+               hsclk_div_val = 1;
+               break;
+       case 3240:
+               clk_sel_val = 0x0b00;
+               hsclk_div_val = 2;
+               break;
+       case 4320:
+       case 5400:
+               clk_sel_val = 0x0301;
+               hsclk_div_val = 0;
+               break;
+       case 8100:
+               clk_sel_val = 0x0200;
+               hsclk_div_val = 0;
+               break;
+       }
 
-static
-void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy)
-{
-       struct regmap *regmap = cdns_phy->regmap_common_cdb;
+       cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
+                              CMN_PDIAG_PLL0_CLK_SEL_M0, clk_sel_val);
+       cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
+                              CMN_PDIAG_PLL1_CLK_SEL_M0, clk_sel_val);
 
-       /* refclock registers - assumes 19.2 MHz refclock */
-       cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0014);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0027);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00A1);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0027);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00A1);
-       cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x0060);
-       cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x0060);
-       cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0014);
-       cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x0018);
-       cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0005);
-       cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x0018);
-       cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0005);
-       cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x0240);
-       cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0005);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000B);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x0137);
-
-       /* PLL registers */
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00C0);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00C0);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0260);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0260);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
+       /* PMA lane configuration to deal with multi-link operation */
+       for (i = 0; i < num_lanes; i++)
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[i],
+                                      XCVR_DIAG_HSCLK_DIV, hsclk_div_val);
 }
 
 /*
- * Set registers responsible for enabling and configuring SSC, with second and
- * third register values provided by parameters.
+ * Perform register operations related to setting link rate, once powerstate is
+ * set and PLL disable request was processed.
  */
-static
-void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
-                                       u32 ctrl2_val, u32 ctrl3_val)
+static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy,
+                                         struct phy_configure_opts_dp *dp)
 {
-       struct regmap *regmap = cdns_phy->regmap_common_cdb;
+       u32 read_val, ret;
 
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
+       /* Disable the cmn_pll0_en before re-programming the new data rate. */
+       regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0);
+
+       /*
+        * Wait for PLL ready de-assertion.
+        * For PLL0 - PHY_PMA_CMN_CTRL2[2] == 1
+        */
+       ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
+                                            read_val,
+                                            ((read_val >> 2) & 0x01) != 0,
+                                            0, POLL_TIMEOUT_US);
+       if (ret)
+               return ret;
+       ndelay(200);
+
+       /* DP Rate Change - VCO Output settings. */
+       if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
+               /* PMA common configuration 19.2MHz */
+               cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, dp->ssc);
+       else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
+               /* PMA common configuration 25MHz */
+               cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, dp->ssc);
+       else if (cdns_phy->ref_clk_rate == CLK_100_MHZ)
+               /* PMA common configuration 100MHz */
+               cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(cdns_phy, dp->link_rate, dp->ssc);
+
+       cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
+
+       /* Enable the cmn_pll0_en. */
+       regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x3);
+
+       /*
+        * Wait for PLL ready assertion.
+        * For PLL0 - PHY_PMA_CMN_CTRL2[0] == 1
+        */
+       ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
+                                            read_val,
+                                            (read_val & 0x01) != 0,
+                                            0, POLL_TIMEOUT_US);
+       return ret;
 }
 
-static
-void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
-                                            u32 rate, bool ssc)
+/*
+ * Verify, that parameters to configure PHY with are correct.
+ */
+static int cdns_torrent_dp_verify_config(struct cdns_torrent_inst *inst,
+                                        struct phy_configure_opts_dp *dp)
 {
-       struct regmap *regmap = cdns_phy->regmap_common_cdb;
+       u8 i;
 
-       /* Assumes 19.2 MHz refclock */
-       switch (rate) {
-       /* Setting VCO for 10.8GHz */
-       case 2700:
-       case 5400:
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_INTDIV_M0, 0x0119);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVL_M0, 0x4000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_HIGH_THR_M0, 0x00BC);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL0_CTRL_M0, 0x0012);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_INTDIV_M0, 0x0119);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVL_M0, 0x4000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_HIGH_THR_M0, 0x00BC);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A,
-                                                          0x006A);
-               break;
-       /* Setting VCO for 9.72GHz */
-       case 1620:
-       case 2430:
-       case 3240:
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_INTDIV_M0, 0x01FA);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVL_M0, 0x4000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_HIGH_THR_M0, 0x0152);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_INTDIV_M0, 0x01FA);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVL_M0, 0x4000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_HIGH_THR_M0, 0x0152);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD,
-                                                          0x0069);
-               break;
-       /* Setting VCO for 8.64GHz */
-       case 2160:
-       case 4320:
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_INTDIV_M0, 0x01C2);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVL_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_HIGH_THR_M0, 0x012C);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_INTDIV_M0, 0x01C2);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVL_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_HIGH_THR_M0, 0x012C);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536,
-                                                          0x0069);
-               break;
-       /* Setting VCO for 8.1GHz */
-       case 8100:
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_INTDIV_M0, 0x01A5);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVL_M0, 0xE000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_HIGH_THR_M0, 0x011A);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_INTDIV_M0, 0x01A5);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVL_M0, 0xE000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_HIGH_THR_M0, 0x011A);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7,
-                                                          0x006A);
+       /* If changing link rate was required, verify it's supported. */
+       if (dp->set_rate) {
+               switch (dp->link_rate) {
+               case 1620:
+               case 2160:
+               case 2430:
+               case 2700:
+               case 3240:
+               case 4320:
+               case 5400:
+               case 8100:
+                       /* valid bit rate */
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /* Verify lane count. */
+       switch (dp->lanes) {
+       case 1:
+       case 2:
+       case 4:
+               /* valid lane count. */
                break;
+       default:
+               return -EINVAL;
        }
 
-       if (ssc) {
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_VCOCAL_PLLCNT_START, 0x025E);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_VCOCAL_PLLCNT_START, 0x025E);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
-       } else {
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_VCOCAL_PLLCNT_START, 0x0260);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_VCOCAL_PLLCNT_START, 0x0260);
-               /* Set reset register values to disable SSC */
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_SS_CTRL1_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_SS_CTRL2_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_SS_CTRL3_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_SS_CTRL4_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_SS_CTRL1_M0, 0x0002);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_SS_CTRL2_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_SS_CTRL3_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_SS_CTRL4_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
+       /* Check against actual number of PHY's lanes. */
+       if (dp->lanes > inst->num_lanes)
+               return -EINVAL;
+
+       /*
+        * If changing voltages is required, check swing and pre-emphasis
+        * levels, per-lane.
+        */
+       if (dp->set_voltages) {
+               /* Lane count verified previously. */
+               for (i = 0; i < dp->lanes; i++) {
+                       if (dp->voltage[i] > 3 || dp->pre[i] > 3)
+                               return -EINVAL;
+
+                       /* Sum of voltage swing and pre-emphasis levels cannot
+                        * exceed 3.
+                        */
+                       if (dp->voltage[i] + dp->pre[i] > 3)
+                               return -EINVAL;
+               }
        }
 
-       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x0099);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x0099);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x0099);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099);
+       return 0;
 }
 
-static
-void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
+/* Set power state A0 and PLL clock enable to 0 on enabled lanes. */
+static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy,
+                                      u32 num_lanes)
 {
-       struct regmap *regmap = cdns_phy->regmap_common_cdb;
+       struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
+       u32 pwr_state = cdns_torrent_dp_read(regmap,
+                                            PHY_PMA_XCVR_POWER_STATE_REQ);
+       u32 pll_clk_en = cdns_torrent_dp_read(regmap,
+                                             PHY_PMA_XCVR_PLLCLK_EN);
+
+       /* Lane 0 is always enabled. */
+       pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
+                      PHY_POWER_STATE_LN_0);
+       pll_clk_en &= ~0x01U;
 
-       /* refclock registers - assumes 25 MHz refclock */
-       cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0019);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0032);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00D1);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0032);
-       cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00D1);
-       cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x007D);
-       cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x007D);
-       cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0019);
-       cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x001E);
-       cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0006);
-       cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x001E);
-       cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0006);
-       cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x02EE);
-       cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0006);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000E);
-       cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x012B);
-
-       /* PLL registers */
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00FA);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00FA);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0317);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0317);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
+       if (num_lanes > 1) {
+               /* lane 1 */
+               pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
+                              PHY_POWER_STATE_LN_1);
+               pll_clk_en &= ~(0x01U << 1);
+       }
+
+       if (num_lanes > 2) {
+               /* lanes 2 and 3 */
+               pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
+                              PHY_POWER_STATE_LN_2);
+               pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
+                              PHY_POWER_STATE_LN_3);
+               pll_clk_en &= ~(0x01U << 2);
+               pll_clk_en &= ~(0x01U << 3);
+       }
+
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, pwr_state);
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_clk_en);
 }
 
-/*
- * Set registers responsible for enabling and configuring SSC, with second
- * register value provided by a parameter.
- */
-static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy,
-                                            u32 ctrl2_val)
+/* Configure lane count as required. */
+static int cdns_torrent_dp_set_lanes(struct cdns_torrent_phy *cdns_phy,
+                                    struct phy_configure_opts_dp *dp)
 {
-       struct regmap *regmap = cdns_phy->regmap_common_cdb;
+       u32 value;
+       u32 ret;
+       struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
+       u8 lane_mask = (1 << dp->lanes) - 1;
 
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
+       value = cdns_torrent_dp_read(regmap, PHY_RESET);
+       /* clear pma_tx_elec_idle_ln_* bits. */
+       value &= ~PMA_TX_ELEC_IDLE_MASK;
+       /* Assert pma_tx_elec_idle_ln_* for disabled lanes. */
+       value |= ((~lane_mask) << PMA_TX_ELEC_IDLE_SHIFT) &
+                PMA_TX_ELEC_IDLE_MASK;
+       cdns_torrent_dp_write(regmap, PHY_RESET, value);
+
+       /* reset the link by asserting phy_l00_reset_n low */
+       cdns_torrent_dp_write(regmap, PHY_RESET,
+                             value & (~PHY_L00_RESET_N_MASK));
+
+       /*
+        * Assert lane reset on unused lanes and lane 0 so they remain in reset
+        * and powered down when re-enabling the link
+        */
+       value = (value & 0x0000FFF0) | (0x0000000E & lane_mask);
+       cdns_torrent_dp_write(regmap, PHY_RESET, value);
+
+       cdns_torrent_dp_set_a0_pll(cdns_phy, dp->lanes);
+
+       /* release phy_l0*_reset_n based on used laneCount */
+       value = (value & 0x0000FFF0) | (0x0000000F & lane_mask);
+       cdns_torrent_dp_write(regmap, PHY_RESET, value);
+
+       /* Wait, until PHY gets ready after releasing PHY reset signal. */
+       ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
+       if (ret)
+               return ret;
+
+       ndelay(100);
+
+       /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
+
+       ret = cdns_torrent_dp_run(cdns_phy, dp->lanes);
+
+       return ret;
 }
 
-static
-void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
-                                          u32 rate, bool ssc)
+/* Configure link rate as required. */
+static int cdns_torrent_dp_set_rate(struct cdns_torrent_phy *cdns_phy,
+                                   struct phy_configure_opts_dp *dp)
 {
-       struct regmap *regmap = cdns_phy->regmap_common_cdb;
+       u32 ret;
 
-       /* Assumes 25 MHz refclock */
-       switch (rate) {
-       /* Setting VCO for 10.8GHz */
-       case 2700:
-       case 5400:
-               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
-               break;
-       /* Setting VCO for 9.72GHz */
-       case 1620:
-       case 2430:
-       case 3240:
-               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
-               break;
-       /* Setting VCO for 8.64GHz */
-       case 2160:
-       case 4320:
-               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
-               break;
-       /* Setting VCO for 8.1GHz */
-       case 8100:
-               cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00D8);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0144);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00D8);
-               if (ssc)
-                       cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A);
-               break;
+       ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
+                                             POWERSTATE_A3);
+       if (ret)
+               return ret;
+       ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, false);
+       if (ret)
+               return ret;
+       ndelay(200);
+
+       ret = cdns_torrent_dp_configure_rate(cdns_phy, dp);
+       if (ret)
+               return ret;
+       ndelay(200);
+
+       ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, true);
+       if (ret)
+               return ret;
+       ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
+                                             POWERSTATE_A2);
+       if (ret)
+               return ret;
+       ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
+                                             POWERSTATE_A0);
+       if (ret)
+               return ret;
+       ndelay(900);
+
+       return ret;
+}
+
+/* Configure voltage swing and pre-emphasis for all enabled lanes. */
+static void cdns_torrent_dp_set_voltages(struct cdns_torrent_phy *cdns_phy,
+                                        struct phy_configure_opts_dp *dp)
+{
+       u8 lane;
+       u16 val;
+
+       for (lane = 0; lane < dp->lanes; lane++) {
+               val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
+                                           TX_DIAG_ACYA);
+               /*
+                * Write 1 to register bit TX_DIAG_ACYA[0] to freeze the
+                * current state of the analog TX driver.
+                */
+               val |= TX_DIAG_ACYA_HBDC_MASK;
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
+                                      TX_DIAG_ACYA, val);
+
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
+                                      TX_TXCC_CTRL, 0x08A4);
+               val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].diag_tx_drv;
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
+                                      DRV_DIAG_TX_DRV, val);
+               val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].mgnfs_mult;
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
+                                      TX_TXCC_MGNFS_MULT_000,
+                                      val);
+               val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].cpost_mult;
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
+                                      TX_TXCC_CPOST_MULT_00,
+                                      val);
+
+               val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
+                                           TX_DIAG_ACYA);
+               /*
+                * Write 0 to register bit TX_DIAG_ACYA[0] to allow the state of
+                * analog TX driver to reflect the new programmed one.
+                */
+               val &= ~TX_DIAG_ACYA_HBDC_MASK;
+               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
+                                      TX_DIAG_ACYA, val);
        }
+};
 
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
-       cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+static int cdns_torrent_dp_configure(struct phy *phy,
+                                    union phy_configure_opts *opts)
+{
+       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
+       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+       int ret;
 
-       if (ssc) {
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_VCOCAL_PLLCNT_START, 0x0315);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_VCOCAL_PLLCNT_START, 0x0315);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
-       } else {
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_VCOCAL_PLLCNT_START, 0x0317);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_VCOCAL_PLLCNT_START, 0x0317);
-               /* Set reset register values to disable SSC */
-               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL2_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL3_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0002);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL2_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL3_M0, 0x0000);
-               cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0000);
-               cdns_torrent_phy_write(regmap,
-                                      CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
+       ret = cdns_torrent_dp_verify_config(inst, &opts->dp);
+       if (ret) {
+               dev_err(&phy->dev, "invalid params for phy configure\n");
+               return ret;
        }
 
-       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x00C7);
-       cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x00C7);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x00C7);
-       cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7);
+       if (opts->dp.set_lanes) {
+               ret = cdns_torrent_dp_set_lanes(cdns_phy, &opts->dp);
+               if (ret) {
+                       dev_err(&phy->dev, "cdns_torrent_dp_set_lanes failed\n");
+                       return ret;
+               }
+       }
+
+       if (opts->dp.set_rate) {
+               ret = cdns_torrent_dp_set_rate(cdns_phy, &opts->dp);
+               if (ret) {
+                       dev_err(&phy->dev, "cdns_torrent_dp_set_rate failed\n");
+                       return ret;
+               }
+       }
+
+       if (opts->dp.set_voltages)
+               cdns_torrent_dp_set_voltages(cdns_phy, &opts->dp);
+
+       return ret;
 }
 
-static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
-                                        u32 rate, u32 num_lanes)
+static int cdns_torrent_phy_on(struct phy *phy)
 {
-       unsigned int clk_sel_val = 0;
-       unsigned int hsclk_div_val = 0;
-       unsigned int i;
+       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
+       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+       u32 read_val;
+       int ret;
 
-       /* 16'h0000 for single DP link configuration */
-       regmap_field_write(cdns_phy->phy_pll_cfg, 0x0);
+       if (cdns_phy->nsubnodes == 1) {
+               /* Take the PHY lane group out of reset */
+               reset_control_deassert(inst->lnk_rst);
 
-       switch (rate) {
-       case 1620:
-               clk_sel_val = 0x0f01;
-               hsclk_div_val = 2;
-               break;
-       case 2160:
-       case 2430:
-       case 2700:
-               clk_sel_val = 0x0701;
-               hsclk_div_val = 1;
-               break;
-       case 3240:
-               clk_sel_val = 0x0b00;
-               hsclk_div_val = 2;
-               break;
-       case 4320:
-       case 5400:
-               clk_sel_val = 0x0301;
-               hsclk_div_val = 0;
-               break;
-       case 8100:
-               clk_sel_val = 0x0200;
-               hsclk_div_val = 0;
-               break;
+               /* Take the PHY out of reset */
+               ret = reset_control_deassert(cdns_phy->phy_rst);
+               if (ret)
+                       return ret;
        }
 
-       cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
-                              CMN_PDIAG_PLL0_CLK_SEL_M0, clk_sel_val);
-       cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
-                              CMN_PDIAG_PLL1_CLK_SEL_M0, clk_sel_val);
+       /*
+        * Wait for cmn_ready assertion
+        * PHY_PMA_CMN_CTRL1[0] == 1
+        */
+       ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_1,
+                                            read_val, read_val, 1000,
+                                            PLL_LOCK_TIMEOUT);
+       if (ret) {
+               dev_err(cdns_phy->dev, "Timeout waiting for CMN ready\n");
+               return ret;
+       }
 
-       /* PMA lane configuration to deal with multi-link operation */
-       for (i = 0; i < num_lanes; i++)
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[i],
-                                      XCVR_DIAG_HSCLK_DIV, hsclk_div_val);
+       if (inst->phy_type == TYPE_PCIE || inst->phy_type == TYPE_USB) {
+               ret = regmap_field_read_poll_timeout(cdns_phy->phy_pcs_iso_link_ctrl_1[inst->mlane],
+                                                    read_val, !read_val, 1000,
+                                                    PLL_LOCK_TIMEOUT);
+               if (ret == -ETIMEDOUT) {
+                       dev_err(cdns_phy->dev, "Timeout waiting for PHY status ready\n");
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
-static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
-                                        unsigned int lane)
+static int cdns_torrent_phy_off(struct phy *phy)
 {
-       /* Per lane, refclock-dependent receiver detection setting */
-       if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_RCVDET_ST_TMR, 0x0780);
-       else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
-               cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                                      TX_RCVDET_ST_TMR, 0x09C4);
-
-       /* Writing Tx/Rx Power State Controllers registers */
-       cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                              TX_PSC_A0, 0x00FB);
-       cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                              TX_PSC_A2, 0x04AA);
-       cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                              TX_PSC_A3, 0x04AA);
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_PSC_A0, 0x0000);
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_PSC_A2, 0x0000);
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_PSC_A3, 0x0000);
-
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_PSC_CAL, 0x0000);
-
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_REE_GCSM1_CTRL, 0x0000);
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_REE_GCSM2_CTRL, 0x0000);
-       cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
-                              RX_REE_PERGCSM_CTRL, 0x0000);
-
-       cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                              XCVR_DIAG_BIDI_CTRL, 0x000F);
-       cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                              XCVR_DIAG_PLLDRC_CTRL, 0x0001);
-       cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
-                              XCVR_DIAG_HSCLK_SEL, 0x0000);
+       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
+       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+       int ret;
+
+       if (cdns_phy->nsubnodes != 1)
+               return 0;
+
+       ret = reset_control_assert(cdns_phy->phy_rst);
+       if (ret)
+               return ret;
+
+       return reset_control_assert(inst->lnk_rst);
 }
 
-static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
-                                          u32 num_lanes,
-                                          enum phy_powerstate powerstate)
+static void cdns_torrent_dp_common_init(struct cdns_torrent_phy *cdns_phy,
+                                       struct cdns_torrent_inst *inst)
 {
-       /* Register value for power state for a single byte. */
-       u32 value_part;
-       u32 value;
-       u32 mask;
-       u32 read_val;
-       u32 ret;
        struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
+       unsigned char lane_bits;
 
-       switch (powerstate) {
-       case (POWERSTATE_A0):
-               value_part = 0x01U;
-               break;
-       case (POWERSTATE_A2):
-               value_part = 0x04U;
-               break;
-       default:
-               /* Powerstate A3 */
-               value_part = 0x08U;
-               break;
-       }
+       cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */
 
-       /* Select values of registers and mask, depending on enabled
-        * lane count.
+       /*
+        * Set lines power state to A0
+        * Set lines pll clk enable to 0
         */
-       switch (num_lanes) {
-       /* lane 0 */
-       case (1):
-               value = value_part;
-               mask = 0x0000003FU;
-               break;
-       /* lanes 0-1 */
-       case (2):
-               value = (value_part
-                        | (value_part << 8));
-               mask = 0x00003F3FU;
-               break;
-       /* lanes 0-3, all */
-       default:
-               value = (value_part
-                        | (value_part << 8)
-                        | (value_part << 16)
-                        | (value_part << 24));
-               mask = 0x3F3F3F3FU;
-               break;
-       }
+       cdns_torrent_dp_set_a0_pll(cdns_phy, inst->num_lanes);
+
+       /*
+        * release phy_l0*_reset_n and pma_tx_elec_idle_ln_* based on
+        * used lanes
+        */
+       lane_bits = (1 << inst->num_lanes) - 1;
+       cdns_torrent_dp_write(regmap, PHY_RESET,
+                             ((0xF & ~lane_bits) << 4) | (0xF & lane_bits));
+
+       /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
+       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
+
+       /*
+        * PHY PMA registers configuration functions
+        * Initialize PHY with max supported link rate, without SSC.
+        */
+       if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
+               cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
+                                                       cdns_phy->max_bit_rate,
+                                                       false);
+       else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
+               cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
+                                                     cdns_phy->max_bit_rate,
+                                                     false);
+       else if (cdns_phy->ref_clk_rate == CLK_100_MHZ)
+               cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(cdns_phy,
+                                                      cdns_phy->max_bit_rate,
+                                                      false);
 
-       /* Set power state A<n>. */
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, value);
-       /* Wait, until PHY acknowledges power state completion. */
-       ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK,
-                                      read_val, (read_val & mask) == value, 0,
-                                      POLL_TIMEOUT_US);
-       cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000);
-       ndelay(100);
+       cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate,
+                                    inst->num_lanes);
 
-       return ret;
+       /* take out of reset */
+       regmap_field_write(cdns_phy->phy_reset_ctrl, 0x1);
 }
 
-static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes)
+static int cdns_torrent_dp_start(struct cdns_torrent_phy *cdns_phy,
+                                struct cdns_torrent_inst *inst,
+                                struct phy *phy)
 {
-       unsigned int read_val;
        int ret;
-       struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
-
-       /*
-        * waiting for ACK of pma_xcvr_pllclk_en_ln_*, only for the
-        * master lane
-        */
-       ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_PLLCLK_EN_ACK,
-                                      read_val, read_val & 1,
-                                      0, POLL_TIMEOUT_US);
-       if (ret == -ETIMEDOUT) {
-               dev_err(cdns_phy->dev,
-                       "timeout waiting for link PLL clock enable ack\n");
-               return ret;
-       }
 
-       ndelay(100);
+       cdns_torrent_phy_on(phy);
 
-       ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
-                                             POWERSTATE_A2);
+       ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
        if (ret)
                return ret;
 
-       ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
-                                             POWERSTATE_A0);
+       ret = cdns_torrent_dp_run(cdns_phy, inst->num_lanes);
 
        return ret;
 }
 
+static int cdns_torrent_dp_init(struct phy *phy)
+{
+       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
+       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+
+       switch (cdns_phy->ref_clk_rate) {
+       case CLK_19_2_MHZ:
+       case CLK_25_MHZ:
+       case CLK_100_MHZ:
+               /* Valid Ref Clock Rate */
+               break;
+       default:
+               dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
+               return -EINVAL;
+       }
+
+       cdns_torrent_dp_common_init(cdns_phy, inst);
+
+       return cdns_torrent_dp_start(cdns_phy, inst, phy);
+}
+
 static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw)
 {
        struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
@@ -1764,56 +1715,6 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
        return 0;
 }
 
-static int cdns_torrent_phy_on(struct phy *phy)
-{
-       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
-       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
-       u32 read_val;
-       int ret;
-
-       if (cdns_phy->nsubnodes == 1) {
-               /* Take the PHY lane group out of reset */
-               reset_control_deassert(inst->lnk_rst);
-
-               /* Take the PHY out of reset */
-               ret = reset_control_deassert(cdns_phy->phy_rst);
-               if (ret)
-                       return ret;
-       }
-
-       /*
-        * Wait for cmn_ready assertion
-        * PHY_PMA_CMN_CTRL1[0] == 1
-        */
-       ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_1,
-                                            read_val, read_val, 1000,
-                                            PLL_LOCK_TIMEOUT);
-       if (ret) {
-               dev_err(cdns_phy->dev, "Timeout waiting for CMN ready\n");
-               return ret;
-       }
-
-       mdelay(10);
-
-       return 0;
-}
-
-static int cdns_torrent_phy_off(struct phy *phy)
-{
-       struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
-       struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
-       int ret;
-
-       if (cdns_phy->nsubnodes != 1)
-               return 0;
-
-       ret = reset_control_assert(cdns_phy->phy_rst);
-       if (ret)
-               return ret;
-
-       return reset_control_assert(inst->lnk_rst);
-}
-
 static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
                                       u32 block_offset,
                                       u8 reg_offset_shift,
@@ -1854,6 +1755,7 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy)
        struct device *dev = cdns_phy->dev;
        struct regmap_field *field;
        struct regmap *regmap;
+       int i;
 
        regmap = cdns_phy->regmap_phy_pcs_common_cdb;
        field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg);
@@ -1887,6 +1789,16 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy)
        }
        cdns_phy->phy_pma_pll_raw_ctrl = field;
 
+       for (i = 0; i < MAX_NUM_LANES; i++) {
+               regmap = cdns_phy->regmap_phy_pcs_lane_cdb[i];
+               field = devm_regmap_field_alloc(dev, regmap, phy_pcs_iso_link_ctrl_1);
+               if (IS_ERR(field)) {
+                       dev_err(dev, "PHY_PCS_ISO_LINK_CTRL reg field init for ln %d failed\n", i);
+                       return PTR_ERR(field);
+               }
+               cdns_phy->phy_pcs_iso_link_ctrl_1[i] = field;
+       }
+
        return 0;
 }
 
@@ -1947,6 +1859,17 @@ static int cdns_torrent_regmap_init(struct cdns_torrent_phy *cdns_phy)
                        return PTR_ERR(regmap);
                }
                cdns_phy->regmap_rx_lane_cdb[i] = regmap;
+
+               block_offset = TORRENT_PHY_PCS_LANE_CDB_OFFSET(i, block_offset_shift,
+                                                              reg_offset_shift);
+               regmap = cdns_regmap_init(dev, sd_base, block_offset,
+                                         reg_offset_shift,
+                                         &cdns_torrent_phy_pcs_lane_cdb_config[i]);
+               if (IS_ERR(regmap)) {
+                       dev_err(dev, "Failed to init PHY PCS lane CDB regmap\n");
+                       return PTR_ERR(regmap);
+               }
+               cdns_phy->regmap_phy_pcs_lane_cdb[i] = regmap;
        }
 
        block_offset = TORRENT_COMMON_CDB_OFFSET;
@@ -1987,6 +1910,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
        struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
        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_clk = cdns_phy->ref_clk_rate;
        struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
        struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
        enum cdns_torrent_phy_type phy_type = inst->phy_type;
@@ -2000,9 +1924,6 @@ static int cdns_torrent_phy_init(struct phy *phy)
        if (cdns_phy->nsubnodes > 1)
                return 0;
 
-       if (phy_type == TYPE_DP)
-               return cdns_torrent_dp_init(phy);
-
        /**
         * Spread spectrum generation is not required or supported
         * for SGMII/QSGMII
@@ -2052,7 +1973,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
        }
 
        /* PMA common registers configurations */
-       cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc];
+       cmn_vals = init_data->cmn_vals[ref_clk][phy_type][TYPE_NONE][ssc];
        if (cmn_vals) {
                reg_pairs = cmn_vals->reg_pairs;
                num_regs = cmn_vals->num_regs;
@@ -2063,7 +1984,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
        }
 
        /* PMA TX lane registers configurations */
-       tx_ln_vals = init_data->tx_ln_vals[phy_type][TYPE_NONE][ssc];
+       tx_ln_vals = init_data->tx_ln_vals[ref_clk][phy_type][TYPE_NONE][ssc];
        if (tx_ln_vals) {
                reg_pairs = tx_ln_vals->reg_pairs;
                num_regs = tx_ln_vals->num_regs;
@@ -2076,7 +1997,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
        }
 
        /* PMA RX lane registers configurations */
-       rx_ln_vals = init_data->rx_ln_vals[phy_type][TYPE_NONE][ssc];
+       rx_ln_vals = init_data->rx_ln_vals[ref_clk][phy_type][TYPE_NONE][ssc];
        if (rx_ln_vals) {
                reg_pairs = rx_ln_vals->reg_pairs;
                num_regs = rx_ln_vals->num_regs;
@@ -2088,14 +2009,39 @@ static int cdns_torrent_phy_init(struct phy *phy)
                }
        }
 
+       if (phy_type == TYPE_DP)
+               return cdns_torrent_dp_init(phy);
+
+       return 0;
+}
+
+static const struct phy_ops cdns_torrent_phy_ops = {
+       .init           = cdns_torrent_phy_init,
+       .configure      = cdns_torrent_dp_configure,
+       .power_on       = cdns_torrent_phy_on,
+       .power_off      = cdns_torrent_phy_off,
+       .owner          = THIS_MODULE,
+};
+
+static int cdns_torrent_noop_phy_on(struct phy *phy)
+{
+       /* Give 5ms to 10ms delay for the PIPE clock to be stable */
+       usleep_range(5000, 10000);
+
        return 0;
 }
 
+static const struct phy_ops noop_ops = {
+       .power_on       = cdns_torrent_noop_phy_on,
+       .owner          = THIS_MODULE,
+};
+
 static
 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_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, tmp_phy_type;
        struct cdns_torrent_vals *pcs_cmn_vals;
@@ -2184,7 +2130,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
                }
 
                /* PMA common registers configurations */
-               cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
+               cmn_vals = init_data->cmn_vals[ref_clk][phy_t1][phy_t2][ssc];
                if (cmn_vals) {
                        reg_pairs = cmn_vals->reg_pairs;
                        num_regs = cmn_vals->num_regs;
@@ -2195,7 +2141,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
                }
 
                /* PMA TX lane registers configurations */
-               tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc];
+               tx_ln_vals = init_data->tx_ln_vals[ref_clk][phy_t1][phy_t2][ssc];
                if (tx_ln_vals) {
                        reg_pairs = tx_ln_vals->reg_pairs;
                        num_regs = tx_ln_vals->num_regs;
@@ -2208,7 +2154,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
                }
 
                /* PMA RX lane registers configurations */
-               rx_ln_vals = init_data->rx_ln_vals[phy_t1][phy_t2][ssc];
+               rx_ln_vals = init_data->rx_ln_vals[ref_clk][phy_t1][phy_t2][ssc];
                if (rx_ln_vals) {
                        reg_pairs = rx_ln_vals->reg_pairs;
                        num_regs = rx_ln_vals->num_regs;
@@ -2286,6 +2232,7 @@ 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_clk_rate;
        int ret;
 
        cdns_phy->clk = devm_clk_get(dev, "refclk");
@@ -2300,13 +2247,29 @@ static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
                return ret;
        }
 
-       cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
-       if (!(cdns_phy->ref_clk_rate)) {
+       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;
        }
 
+       switch (ref_clk_rate) {
+       case REF_CLK_19_2MHZ:
+               cdns_phy->ref_clk_rate = CLK_19_2_MHZ;
+               break;
+       case REF_CLK_25MHZ:
+               cdns_phy->ref_clk_rate = CLK_25_MHZ;
+               break;
+       case REF_CLK_100MHZ:
+               cdns_phy->ref_clk_rate = CLK_100_MHZ;
+               break;
+       default:
+               dev_err(cdns_phy->dev, "Invalid Ref Clock Rate\n");
+               clk_disable_unprepare(cdns_phy->clk);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -2505,10 +2468,9 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
                                init_dp_regmap++;
                        }
 
-                       dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n",
-                                cdns_phy->phys[node].num_lanes,
-                                cdns_phy->max_bit_rate / 1000,
-                                cdns_phy->max_bit_rate % 1000);
+                       dev_dbg(dev, "DP max bit rate %d.%03d Gbps\n",
+                               cdns_phy->max_bit_rate / 1000,
+                               cdns_phy->max_bit_rate % 1000);
 
                        gphy->attrs.bus_width = cdns_phy->phys[node].num_lanes;
                        gphy->attrs.max_link_rate = cdns_phy->max_bit_rate;
@@ -2518,60 +2480,271 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
                cdns_phy->phys[node].phy = gphy;
                phy_set_drvdata(gphy, &cdns_phy->phys[node]);
 
-               node++;
-       }
-       cdns_phy->nsubnodes = node;
+               node++;
+       }
+       cdns_phy->nsubnodes = node;
+
+       if (total_num_lanes > MAX_NUM_LANES) {
+               dev_err(dev, "Invalid lane configuration\n");
+               ret = -EINVAL;
+               goto put_lnk_rst;
+       }
+
+       if (cdns_phy->nsubnodes > 1 && !already_configured) {
+               ret = cdns_torrent_phy_configure_multilink(cdns_phy);
+               if (ret)
+                       goto put_lnk_rst;
+       }
+
+       phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+       if (IS_ERR(phy_provider)) {
+               ret = PTR_ERR(phy_provider);
+               goto put_lnk_rst;
+       }
+
+       if (cdns_phy->nsubnodes > 1)
+               dev_dbg(dev, "Multi-link: %s (%d lanes) & %s (%d lanes)",
+                       cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type),
+                       cdns_phy->phys[0].num_lanes,
+                       cdns_torrent_get_phy_type(cdns_phy->phys[1].phy_type),
+                       cdns_phy->phys[1].num_lanes);
+       else
+               dev_dbg(dev, "Single link: %s (%d lanes)",
+                       cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type),
+                       cdns_phy->phys[0].num_lanes);
+
+       return 0;
+
+put_child:
+       node++;
+put_lnk_rst:
+       for (i = 0; i < node; i++)
+               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->clk);
+clk_cleanup:
+       cdns_torrent_clk_cleanup(cdns_phy);
+       return ret;
+}
+
+static int cdns_torrent_phy_remove(struct platform_device *pdev)
+{
+       struct cdns_torrent_phy *cdns_phy = platform_get_drvdata(pdev);
+       int i;
+
+       reset_control_assert(cdns_phy->phy_rst);
+       reset_control_assert(cdns_phy->apb_rst);
+       for (i = 0; i < cdns_phy->nsubnodes; i++) {
+               reset_control_assert(cdns_phy->phys[i].lnk_rst);
+               reset_control_put(cdns_phy->phys[i].lnk_rst);
+       }
+
+       clk_disable_unprepare(cdns_phy->clk);
+       cdns_torrent_clk_cleanup(cdns_phy);
+
+       return 0;
+}
+
+/* Single DisplayPort(DP) link configuration */
+static struct cdns_reg_pairs sl_dp_link_cmn_regs[] = {
+       {0x0000, PHY_PLL_CFG},
+};
+
+static struct cdns_reg_pairs sl_dp_xcvr_diag_ln_regs[] = {
+       {0x0000, XCVR_DIAG_HSCLK_SEL},
+       {0x0001, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals sl_dp_link_cmn_vals = {
+       .reg_pairs = sl_dp_link_cmn_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals sl_dp_xcvr_diag_ln_vals = {
+       .reg_pairs = sl_dp_xcvr_diag_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_xcvr_diag_ln_regs),
+};
+
+/* Single DP, 19.2 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs sl_dp_19_2_no_ssc_cmn_regs[] = {
+       {0x0014, CMN_SSM_BIAS_TMR},
+       {0x0027, CMN_PLLSM0_PLLPRE_TMR},
+       {0x00A1, CMN_PLLSM0_PLLLOCK_TMR},
+       {0x0027, CMN_PLLSM1_PLLPRE_TMR},
+       {0x00A1, CMN_PLLSM1_PLLLOCK_TMR},
+       {0x0060, CMN_BGCAL_INIT_TMR},
+       {0x0060, 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},
+       {0x0240, CMN_RXCAL_INIT_TMR},
+       {0x0005, CMN_RXCAL_ITER_TMR},
+       {0x0002, CMN_SD_CAL_INIT_TMR},
+       {0x0002, CMN_SD_CAL_ITER_TMR},
+       {0x000B, CMN_SD_CAL_REFTIM_START},
+       {0x0137, CMN_SD_CAL_PLLCNT_START},
+       {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0},
+       {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0},
+       {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0},
+       {0x0004, CMN_PLL0_DSM_DIAG_M0},
+       {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0},
+       {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0},
+       {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0},
+       {0x0004, CMN_PLL1_DSM_DIAG_M0},
+       {0x00C0, CMN_PLL0_VCOCAL_INIT_TMR},
+       {0x0004, CMN_PLL0_VCOCAL_ITER_TMR},
+       {0x00C0, CMN_PLL1_VCOCAL_INIT_TMR},
+       {0x0004, CMN_PLL1_VCOCAL_ITER_TMR},
+       {0x0260, CMN_PLL0_VCOCAL_REFTIM_START},
+       {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+       {0x0260, CMN_PLL1_VCOCAL_REFTIM_START},
+       {0x0003, CMN_PLL1_VCOCAL_TCTRL}
+};
+
+static struct cdns_reg_pairs sl_dp_19_2_no_ssc_tx_ln_regs[] = {
+       {0x0780, TX_RCVDET_ST_TMR},
+       {0x00FB, TX_PSC_A0},
+       {0x04AA, TX_PSC_A2},
+       {0x04AA, TX_PSC_A3},
+       {0x000F, XCVR_DIAG_BIDI_CTRL}
+};
+
+static struct cdns_reg_pairs sl_dp_19_2_no_ssc_rx_ln_regs[] = {
+       {0x0000, RX_PSC_A0},
+       {0x0000, RX_PSC_A2},
+       {0x0000, RX_PSC_A3},
+       {0x0000, RX_PSC_CAL},
+       {0x0000, RX_REE_GCSM1_CTRL},
+       {0x0000, RX_REE_GCSM2_CTRL},
+       {0x0000, RX_REE_PERGCSM_CTRL}
+};
+
+static struct cdns_torrent_vals sl_dp_19_2_no_ssc_cmn_vals = {
+       .reg_pairs = sl_dp_19_2_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_19_2_no_ssc_cmn_regs),
+};
+
+static struct cdns_torrent_vals sl_dp_19_2_no_ssc_tx_ln_vals = {
+       .reg_pairs = sl_dp_19_2_no_ssc_tx_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_19_2_no_ssc_tx_ln_regs),
+};
+
+static struct cdns_torrent_vals sl_dp_19_2_no_ssc_rx_ln_vals = {
+       .reg_pairs = sl_dp_19_2_no_ssc_rx_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_19_2_no_ssc_rx_ln_regs),
+};
+
+/* Single DP, 25 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs sl_dp_25_no_ssc_cmn_regs[] = {
+       {0x0019, CMN_SSM_BIAS_TMR},
+       {0x0032, CMN_PLLSM0_PLLPRE_TMR},
+       {0x00D1, CMN_PLLSM0_PLLLOCK_TMR},
+       {0x0032, CMN_PLLSM1_PLLPRE_TMR},
+       {0x00D1, CMN_PLLSM1_PLLLOCK_TMR},
+       {0x007D, CMN_BGCAL_INIT_TMR},
+       {0x007D, CMN_BGCAL_ITER_TMR},
+       {0x0019, CMN_IBCAL_INIT_TMR},
+       {0x001E, CMN_TXPUCAL_INIT_TMR},
+       {0x0006, CMN_TXPUCAL_ITER_TMR},
+       {0x001E, CMN_TXPDCAL_INIT_TMR},
+       {0x0006, CMN_TXPDCAL_ITER_TMR},
+       {0x02EE, CMN_RXCAL_INIT_TMR},
+       {0x0006, CMN_RXCAL_ITER_TMR},
+       {0x0002, CMN_SD_CAL_INIT_TMR},
+       {0x0002, CMN_SD_CAL_ITER_TMR},
+       {0x000E, CMN_SD_CAL_REFTIM_START},
+       {0x012B, CMN_SD_CAL_PLLCNT_START},
+       {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0},
+       {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0},
+       {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0},
+       {0x0004, CMN_PLL0_DSM_DIAG_M0},
+       {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0},
+       {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0},
+       {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0},
+       {0x0004, CMN_PLL1_DSM_DIAG_M0},
+       {0x00FA, CMN_PLL0_VCOCAL_INIT_TMR},
+       {0x0004, CMN_PLL0_VCOCAL_ITER_TMR},
+       {0x00FA, CMN_PLL1_VCOCAL_INIT_TMR},
+       {0x0004, CMN_PLL1_VCOCAL_ITER_TMR},
+       {0x0317, CMN_PLL0_VCOCAL_REFTIM_START},
+       {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+       {0x0317, CMN_PLL1_VCOCAL_REFTIM_START},
+       {0x0003, CMN_PLL1_VCOCAL_TCTRL}
+};
+
+static struct cdns_reg_pairs sl_dp_25_no_ssc_tx_ln_regs[] = {
+       {0x09C4, TX_RCVDET_ST_TMR},
+       {0x00FB, TX_PSC_A0},
+       {0x04AA, TX_PSC_A2},
+       {0x04AA, TX_PSC_A3},
+       {0x000F, XCVR_DIAG_BIDI_CTRL}
+};
+
+static struct cdns_reg_pairs sl_dp_25_no_ssc_rx_ln_regs[] = {
+       {0x0000, RX_PSC_A0},
+       {0x0000, RX_PSC_A2},
+       {0x0000, RX_PSC_A3},
+       {0x0000, RX_PSC_CAL},
+       {0x0000, RX_REE_GCSM1_CTRL},
+       {0x0000, RX_REE_GCSM2_CTRL},
+       {0x0000, RX_REE_PERGCSM_CTRL}
+};
 
-       if (total_num_lanes > MAX_NUM_LANES) {
-               dev_err(dev, "Invalid lane configuration\n");
-               ret = -EINVAL;
-               goto put_lnk_rst;
-       }
+static struct cdns_torrent_vals sl_dp_25_no_ssc_cmn_vals = {
+       .reg_pairs = sl_dp_25_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_25_no_ssc_cmn_regs),
+};
 
-       if (cdns_phy->nsubnodes > 1 && !already_configured) {
-               ret = cdns_torrent_phy_configure_multilink(cdns_phy);
-               if (ret)
-                       goto put_lnk_rst;
-       }
+static struct cdns_torrent_vals sl_dp_25_no_ssc_tx_ln_vals = {
+       .reg_pairs = sl_dp_25_no_ssc_tx_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_25_no_ssc_tx_ln_regs),
+};
 
-       phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-       if (IS_ERR(phy_provider)) {
-               ret = PTR_ERR(phy_provider);
-               goto put_lnk_rst;
-       }
+static struct cdns_torrent_vals sl_dp_25_no_ssc_rx_ln_vals = {
+       .reg_pairs = sl_dp_25_no_ssc_rx_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_25_no_ssc_rx_ln_regs),
+};
 
-       return 0;
+/* Single DP, 100 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs sl_dp_100_no_ssc_cmn_regs[] = {
+       {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+       {0x0003, CMN_PLL1_VCOCAL_TCTRL}
+};
 
-put_child:
-       node++;
-put_lnk_rst:
-       for (i = 0; i < node; i++)
-               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->clk);
-clk_cleanup:
-       cdns_torrent_clk_cleanup(cdns_phy);
-       return ret;
-}
+static struct cdns_reg_pairs sl_dp_100_no_ssc_tx_ln_regs[] = {
+       {0x00FB, TX_PSC_A0},
+       {0x04AA, TX_PSC_A2},
+       {0x04AA, TX_PSC_A3},
+       {0x000F, XCVR_DIAG_BIDI_CTRL}
+};
 
-static int cdns_torrent_phy_remove(struct platform_device *pdev)
-{
-       struct cdns_torrent_phy *cdns_phy = platform_get_drvdata(pdev);
-       int i;
+static struct cdns_reg_pairs sl_dp_100_no_ssc_rx_ln_regs[] = {
+       {0x0000, RX_PSC_A0},
+       {0x0000, RX_PSC_A2},
+       {0x0000, RX_PSC_A3},
+       {0x0000, RX_PSC_CAL},
+       {0x0000, RX_REE_GCSM1_CTRL},
+       {0x0000, RX_REE_GCSM2_CTRL},
+       {0x0000, RX_REE_PERGCSM_CTRL}
+};
 
-       reset_control_assert(cdns_phy->phy_rst);
-       reset_control_assert(cdns_phy->apb_rst);
-       for (i = 0; i < cdns_phy->nsubnodes; i++) {
-               reset_control_assert(cdns_phy->phys[i].lnk_rst);
-               reset_control_put(cdns_phy->phys[i].lnk_rst);
-       }
+static struct cdns_torrent_vals sl_dp_100_no_ssc_cmn_vals = {
+       .reg_pairs = sl_dp_100_no_ssc_cmn_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_100_no_ssc_cmn_regs),
+};
 
-       clk_disable_unprepare(cdns_phy->clk);
-       cdns_torrent_clk_cleanup(cdns_phy);
+static struct cdns_torrent_vals sl_dp_100_no_ssc_tx_ln_vals = {
+       .reg_pairs = sl_dp_100_no_ssc_tx_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_100_no_ssc_tx_ln_regs),
+};
 
-       return 0;
-}
+static struct cdns_torrent_vals sl_dp_100_no_ssc_rx_ln_vals = {
+       .reg_pairs = sl_dp_100_no_ssc_rx_ln_regs,
+       .num_regs = ARRAY_SIZE(sl_dp_100_no_ssc_rx_ln_regs),
+};
 
 /* USB and SGMII/QSGMII link configuration */
 static struct cdns_reg_pairs usb_sgmii_link_cmn_regs[] = {
@@ -3311,6 +3484,11 @@ static const struct cdns_torrent_data cdns_map_torrent = {
        .block_offset_shift = 0x2,
        .reg_offset_shift = 0x2,
        .link_cmn_vals = {
+               [TYPE_DP] = {
+                       [TYPE_NONE] = {
+                               [NO_SSC] = &sl_dp_link_cmn_vals,
+                       },
+               },
                [TYPE_PCIE] = {
                        [TYPE_NONE] = {
                                [NO_SSC] = NULL,
@@ -3387,6 +3565,11 @@ static const struct cdns_torrent_data cdns_map_torrent = {
                },
        },
        .xcvr_diag_vals = {
+               [TYPE_DP] = {
+                       [TYPE_NONE] = {
+                               [NO_SSC] = &sl_dp_xcvr_diag_ln_vals,
+                       },
+               },
                [TYPE_PCIE] = {
                        [TYPE_NONE] = {
                                [NO_SSC] = NULL,
@@ -3487,230 +3670,293 @@ static const struct cdns_torrent_data cdns_map_torrent = {
                },
        },
        .cmn_vals = {
-               [TYPE_PCIE] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_SGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_QSGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
-                       },
-               },
-               [TYPE_SGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sl_sgmii_100_no_ssc_cmn_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sgmii_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+               [CLK_19_2_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_19_2_no_ssc_cmn_vals,
+                               },
                        },
                },
-               [TYPE_QSGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sl_qsgmii_100_no_ssc_cmn_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+               [CLK_25_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_25_no_ssc_cmn_vals,
+                               },
                        },
                },
-               [TYPE_USB] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+               [CLK_100_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_100_no_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_PCIE] = {
-                               [NO_SSC] = &usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_SGMII] = {
-                               [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_QSGMII] = {
-                               [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
-                       },
-               },
-       },
-       .tx_ln_vals = {
-               [TYPE_PCIE] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_SGMII] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_sgmii_100_no_ssc_cmn_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_QSGMII] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_qsgmii_100_no_ssc_cmn_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_USB] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+                               },
                        },
                },
-               [TYPE_SGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+       },
+       .tx_ln_vals = {
+               [CLK_19_2_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_19_2_no_ssc_tx_ln_vals,
+                               },
                        },
                },
-               [TYPE_QSGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+               [CLK_25_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_25_no_ssc_tx_ln_vals,
+                               },
                        },
                },
-               [TYPE_USB] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+               [CLK_100_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_100_no_ssc_tx_ln_vals,
+                               },
                        },
                        [TYPE_PCIE] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_SGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_QSGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                       },
-               },
-       },
-       .rx_ln_vals = {
-               [TYPE_PCIE] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
                        },
                        [TYPE_SGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+                               },
                        },
                        [TYPE_QSGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+                               },
                        },
                        [TYPE_USB] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
                        },
                },
-               [TYPE_SGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+       },
+       .rx_ln_vals = {
+               [CLK_19_2_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_19_2_no_ssc_rx_ln_vals,
+                               },
                        },
                },
-               [TYPE_QSGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+               [CLK_25_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_25_no_ssc_rx_ln_vals,
+                               },
                        },
                },
-               [TYPE_USB] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+               [CLK_100_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_100_no_ssc_rx_ln_vals,
+                               },
                        },
                        [TYPE_PCIE] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
                        },
                        [TYPE_SGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                               },
                        },
                        [TYPE_QSGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                               },
+                       },
+                       [TYPE_USB] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
                        },
                },
        },
@@ -3720,6 +3966,11 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
        .block_offset_shift = 0x0,
        .reg_offset_shift = 0x1,
        .link_cmn_vals = {
+               [TYPE_DP] = {
+                       [TYPE_NONE] = {
+                               [NO_SSC] = &sl_dp_link_cmn_vals,
+                       },
+               },
                [TYPE_PCIE] = {
                        [TYPE_NONE] = {
                                [NO_SSC] = NULL,
@@ -3796,6 +4047,11 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
                },
        },
        .xcvr_diag_vals = {
+               [TYPE_DP] = {
+                       [TYPE_NONE] = {
+                               [NO_SSC] = &sl_dp_xcvr_diag_ln_vals,
+                       },
+               },
                [TYPE_PCIE] = {
                        [TYPE_NONE] = {
                                [NO_SSC] = NULL,
@@ -3896,230 +4152,293 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
                },
        },
        .cmn_vals = {
-               [TYPE_PCIE] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_SGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_QSGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
-                       },
-               },
-               [TYPE_SGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sl_sgmii_100_no_ssc_cmn_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sgmii_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+               [CLK_19_2_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_19_2_no_ssc_cmn_vals,
+                               },
                        },
                },
-               [TYPE_QSGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sl_qsgmii_100_no_ssc_cmn_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+               [CLK_25_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_25_no_ssc_cmn_vals,
+                               },
                        },
                },
-               [TYPE_USB] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+               [CLK_100_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_100_no_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_PCIE] = {
-                               [NO_SSC] = &usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_SGMII] = {
-                               [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
-                       },
-                       [TYPE_QSGMII] = {
-                               [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
-                               [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
-                       },
-               },
-       },
-       .tx_ln_vals = {
-               [TYPE_PCIE] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_SGMII] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_sgmii_100_no_ssc_cmn_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_QSGMII] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_qsgmii_100_no_ssc_cmn_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+                               },
                        },
                        [TYPE_USB] = {
-                               [NO_SSC] = NULL,
-                               [EXTERNAL_SSC] = NULL,
-                               [INTERNAL_SSC] = NULL,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+                                       [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
+                               },
                        },
                },
-               [TYPE_SGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+       },
+       .tx_ln_vals = {
+               [CLK_19_2_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_19_2_no_ssc_tx_ln_vals,
+                               },
                        },
                },
-               [TYPE_QSGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+               [CLK_25_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_25_no_ssc_tx_ln_vals,
+                               },
                        },
                },
-               [TYPE_USB] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+               [CLK_100_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_100_no_ssc_tx_ln_vals,
+                               },
                        },
                        [TYPE_PCIE] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_SGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                       },
-                       [TYPE_QSGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
-                       },
-               },
-       },
-       .rx_ln_vals = {
-               [TYPE_PCIE] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = NULL,
+                                       [EXTERNAL_SSC] = NULL,
+                                       [INTERNAL_SSC] = NULL,
+                               },
                        },
                        [TYPE_SGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+                               },
                        },
                        [TYPE_QSGMII] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+                               },
                        },
                        [TYPE_USB] = {
-                               [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals,
+                               },
                        },
                },
-               [TYPE_SGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+       },
+       .rx_ln_vals = {
+               [CLK_19_2_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_19_2_no_ssc_rx_ln_vals,
+                               },
                        },
                },
-               [TYPE_QSGMII] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_PCIE] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                       },
-                       [TYPE_USB] = {
-                               [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+               [CLK_25_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_25_no_ssc_rx_ln_vals,
+                               },
                        },
                },
-               [TYPE_USB] = {
-                       [TYPE_NONE] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+               [CLK_100_MHZ] = {
+                       [TYPE_DP] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sl_dp_100_no_ssc_rx_ln_vals,
+                               },
                        },
                        [TYPE_PCIE] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals,
+                               },
                        },
                        [TYPE_SGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals,
+                               },
                        },
                        [TYPE_QSGMII] = {
-                               [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
-                               [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_USB] = {
+                                       [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals,
+                               },
+                       },
+                       [TYPE_USB] = {
+                               [TYPE_NONE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_PCIE] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_SGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
+                               [TYPE_QSGMII] = {
+                                       [NO_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                                       [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals,
+                               },
                        },
                },
        },
index 8ad8f71..5fb4217 100644 (file)
@@ -100,7 +100,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct mtk_hdmi_phy *hdmi_phy;
-       struct resource *mem;
        struct clk *ref_clk;
        const char *ref_clk_name;
        struct clk_init_data clk_init = {
@@ -116,11 +115,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
        if (!hdmi_phy)
                return -ENOMEM;
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hdmi_phy->regs = devm_ioremap_resource(dev, mem);
-       if (IS_ERR(hdmi_phy->regs)) {
+       hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(hdmi_phy->regs))
                return PTR_ERR(hdmi_phy->regs);
-       }
 
        ref_clk = devm_clk_get(dev, "pll_ref");
        if (IS_ERR(ref_clk)) {
index 01cf316..28ad940 100644 (file)
@@ -130,7 +130,6 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct mtk_mipi_tx *mipi_tx;
-       struct resource *mem;
        const char *ref_clk_name;
        struct clk *ref_clk;
        struct clk_init_data clk_init = {
@@ -148,11 +147,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
        mipi_tx->driver_data = of_device_get_match_data(dev);
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       mipi_tx->regs = devm_ioremap_resource(dev, mem);
-       if (IS_ERR(mipi_tx->regs)) {
+       mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(mipi_tx->regs))
                return PTR_ERR(mipi_tx->regs);
-       }
 
        ref_clk = devm_clk_get(dev, NULL);
        if (IS_ERR(ref_clk)) {
@@ -203,10 +200,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
        phy_set_drvdata(phy, mipi_tx);
 
        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-       if (IS_ERR(phy_provider)) {
-               ret = PTR_ERR(phy_provider);
-               return ret;
-       }
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
 
        mipi_tx->dev = dev;
 
index 731c483..cdcef86 100644 (file)
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 /* version V1 sub-banks offset base address */
 /* banks shared by multiple phys */
@@ -27,7 +29,8 @@
 #define SSUSB_SIFSLV_V1_U3PHYD         0x000
 #define SSUSB_SIFSLV_V1_U3PHYA         0x200
 
-/* version V2 sub-banks offset base address */
+/* version V2/V3 sub-banks offset base address */
+/* V3: U2FREQ is not used anymore, but reserved */
 /* u2 phy banks */
 #define SSUSB_SIFSLV_V2_MISC           0x000
 #define SSUSB_SIFSLV_V2_U2FREQ         0x100
@@ -40,6 +43,8 @@
 
 #define U3P_USBPHYACR0         0x000
 #define PA0_RG_U2PLL_FORCE_ON          BIT(15)
+#define PA0_USB20_PLL_PREDIV           GENMASK(7, 6)
+#define PA0_USB20_PLL_PREDIV_VAL(x)    ((0x3 & (x)) << 6)
 #define PA0_RG_USB20_INTR_EN           BIT(5)
 
 #define U3P_USBPHYACR1         0x004
@@ -51,6 +56,8 @@
 #define PA1_RG_TERM_SEL_VAL(x) ((0x7 & (x)) << 8)
 
 #define U3P_USBPHYACR2         0x008
+#define PA2_RG_U2PLL_BW                        GENMASK(21, 19)
+#define PA2_RG_U2PLL_BW_VAL(x)         ((0x7 & (x)) << 19)
 #define PA2_RG_SIF_U2PLL_FORCE_EN      BIT(18)
 
 #define U3P_USBPHYACR5         0x014
 #define P2C_USB20_GPIO_MODE            BIT(8)
 #define P2C_U2_GPIO_CTR_MSK    (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
 
+#define U3P_U2PHYA_RESV                0x030
+#define P2R_RG_U2PLL_FBDIV_26M         0x1bb13b
+#define P2R_RG_U2PLL_FBDIV_48M         0x3c0000
+
+#define U3P_U2PHYA_RESV1       0x044
+#define P2R_RG_U2PLL_REFCLK_SEL        BIT(5)
+#define P2R_RG_U2PLL_FRA_EN            BIT(3)
+
 #define U3D_U2PHYDCR0          0x060
 #define P2C_RG_SIF_U2PLL_FORCE_ON      BIT(24)
 
 #define RG_CDR_BIRLTD0_GEN3_MSK                GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)     (0x1f & (x))
 
+/* PHY switch between pcie/usb3/sgmii/sata */
+#define USB_PHY_SWITCH_CTRL    0x0
+#define RG_PHY_SW_TYPE         GENMASK(3, 0)
+#define RG_PHY_SW_PCIE         0x0
+#define RG_PHY_SW_USB3         0x1
+#define RG_PHY_SW_SGMII                0x2
+#define RG_PHY_SW_SATA         0x3
+
+#define TPHY_CLKS_CNT  2
+
 enum mtk_phy_version {
        MTK_PHY_V1 = 1,
        MTK_PHY_V2,
+       MTK_PHY_V3,
 };
 
 struct mtk_phy_pdata {
        /* avoid RX sensitivity level degradation only for mt8173 */
        bool avoid_rx_sen_degradation;
+       /*
+        * workaround only for mt8195, HW fix it for others of V3,
+        * u2phy should use integer mode instead of fractional mode of
+        * 48M PLL, fix it by switching PLL to 26M from default 48M
+        */
+       bool sw_pll_48m_to_26m;
        enum mtk_phy_version version;
 };
 
@@ -298,10 +330,12 @@ struct mtk_phy_instance {
                struct u2phy_banks u2_banks;
                struct u3phy_banks u3_banks;
        };
-       struct clk *ref_clk;    /* reference clock of (digital) phy */
-       struct clk *da_ref_clk; /* reference clock of analog phy */
+       struct clk_bulk_data clks[TPHY_CLKS_CNT];
        u32 index;
-       u8 type;
+       u32 type;
+       struct regmap *type_sw;
+       u32 type_sw_reg;
+       u32 type_sw_index;
        int eye_src;
        int eye_vrt;
        int eye_term;
@@ -330,6 +364,10 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy,
        int fm_out;
        u32 tmp;
 
+       /* HW V3 doesn't support slew rate cal anymore */
+       if (tphy->pdata->version == MTK_PHY_V3)
+               return;
+
        /* use force value */
        if (instance->eye_src)
                return;
@@ -450,6 +488,33 @@ static void u3_phy_instance_init(struct mtk_tphy *tphy,
        dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
 }
 
+static void u2_phy_pll_26m_set(struct mtk_tphy *tphy,
+       struct mtk_phy_instance *instance)
+{
+       struct u2phy_banks *u2_banks = &instance->u2_banks;
+       void __iomem *com = u2_banks->com;
+       u32 tmp;
+
+       if (!tphy->pdata->sw_pll_48m_to_26m)
+               return;
+
+       tmp = readl(com + U3P_USBPHYACR0);
+       tmp &= ~PA0_USB20_PLL_PREDIV;
+       tmp |= PA0_USB20_PLL_PREDIV_VAL(0);
+       writel(tmp, com + U3P_USBPHYACR0);
+
+       tmp = readl(com + U3P_USBPHYACR2);
+       tmp &= ~PA2_RG_U2PLL_BW;
+       tmp |= PA2_RG_U2PLL_BW_VAL(3);
+       writel(tmp, com + U3P_USBPHYACR2);
+
+       writel(P2R_RG_U2PLL_FBDIV_26M, com + U3P_U2PHYA_RESV);
+
+       tmp = readl(com + U3P_U2PHYA_RESV1);
+       tmp |= P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL;
+       writel(tmp, com + U3P_U2PHYA_RESV1);
+}
+
 static void u2_phy_instance_init(struct mtk_tphy *tphy,
        struct mtk_phy_instance *instance)
 {
@@ -509,6 +574,9 @@ static void u2_phy_instance_init(struct mtk_tphy *tphy,
        tmp |= PA6_RG_U2_SQTH_VAL(2);
        writel(tmp, com + U3P_USBPHYACR6);
 
+       /* Workaround only for mt8195, HW fix it for others (V3) */
+       u2_phy_pll_26m_set(tphy, instance);
+
        dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
 }
 
@@ -878,7 +946,7 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
                writel(tmp, com + U3P_U2PHYBC12C);
        }
 
-       if (instance->eye_src) {
+       if (tphy->pdata->version < MTK_PHY_V3 && instance->eye_src) {
                tmp = readl(com + U3P_USBPHYACR5);
                tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
                tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(instance->eye_src);
@@ -914,24 +982,73 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
        }
 }
 
-static int mtk_phy_init(struct phy *phy)
+/* type switch for usb3/pcie/sgmii/sata */
+static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+                              struct device_node *dn)
 {
-       struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-       struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+       struct of_phandle_args args;
        int ret;
 
-       ret = clk_prepare_enable(instance->ref_clk);
-       if (ret) {
-               dev_err(tphy->dev, "failed to enable ref_clk\n");
+       /* type switch function is optional */
+       if (!of_property_read_bool(dn, "mediatek,syscon-type"))
+               return 0;
+
+       ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
+                                              2, 0, &args);
+       if (ret)
                return ret;
+
+       instance->type_sw_reg = args.args[0];
+       instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
+       instance->type_sw = syscon_node_to_regmap(args.np);
+       of_node_put(args.np);
+       dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
+                instance->type_sw_reg, instance->type_sw_index);
+
+       return PTR_ERR_OR_ZERO(instance->type_sw);
+}
+
+static int phy_type_set(struct mtk_phy_instance *instance)
+{
+       int type;
+       u32 mask;
+
+       if (!instance->type_sw)
+               return 0;
+
+       switch (instance->type) {
+       case PHY_TYPE_USB3:
+               type = RG_PHY_SW_USB3;
+               break;
+       case PHY_TYPE_PCIE:
+               type = RG_PHY_SW_PCIE;
+               break;
+       case PHY_TYPE_SGMII:
+               type = RG_PHY_SW_SGMII;
+               break;
+       case PHY_TYPE_SATA:
+               type = RG_PHY_SW_SATA;
+               break;
+       case PHY_TYPE_USB2:
+       default:
+               return 0;
        }
 
-       ret = clk_prepare_enable(instance->da_ref_clk);
-       if (ret) {
-               dev_err(tphy->dev, "failed to enable da_ref\n");
-               clk_disable_unprepare(instance->ref_clk);
+       mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+       regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
+
+       return 0;
+}
+
+static int mtk_phy_init(struct phy *phy)
+{
+       struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+       struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+       int ret;
+
+       ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, instance->clks);
+       if (ret)
                return ret;
-       }
 
        switch (instance->type) {
        case PHY_TYPE_USB2:
@@ -947,10 +1064,12 @@ static int mtk_phy_init(struct phy *phy)
        case PHY_TYPE_SATA:
                sata_phy_instance_init(tphy, instance);
                break;
+       case PHY_TYPE_SGMII:
+               /* nothing to do, only used to set type */
+               break;
        default:
                dev_err(tphy->dev, "incompatible PHY type\n");
-               clk_disable_unprepare(instance->ref_clk);
-               clk_disable_unprepare(instance->da_ref_clk);
+               clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
                return -EINVAL;
        }
 
@@ -993,8 +1112,7 @@ static int mtk_phy_exit(struct phy *phy)
        if (instance->type == PHY_TYPE_USB2)
                u2_phy_instance_exit(tphy, instance);
 
-       clk_disable_unprepare(instance->ref_clk);
-       clk_disable_unprepare(instance->da_ref_clk);
+       clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
        return 0;
 }
 
@@ -1037,21 +1155,27 @@ static struct phy *mtk_phy_xlate(struct device *dev,
        if (!(instance->type == PHY_TYPE_USB2 ||
              instance->type == PHY_TYPE_USB3 ||
              instance->type == PHY_TYPE_PCIE ||
-             instance->type == PHY_TYPE_SATA)) {
+             instance->type == PHY_TYPE_SATA ||
+             instance->type == PHY_TYPE_SGMII)) {
                dev_err(dev, "unsupported device type: %d\n", instance->type);
                return ERR_PTR(-EINVAL);
        }
 
-       if (tphy->pdata->version == MTK_PHY_V1) {
+       switch (tphy->pdata->version) {
+       case MTK_PHY_V1:
                phy_v1_banks_init(tphy, instance);
-       } else if (tphy->pdata->version == MTK_PHY_V2) {
+               break;
+       case MTK_PHY_V2:
+       case MTK_PHY_V3:
                phy_v2_banks_init(tphy, instance);
-       } else {
+               break;
+       default:
                dev_err(dev, "phy version is not supported\n");
                return ERR_PTR(-EINVAL);
        }
 
        phy_parse_property(tphy, instance);
+       phy_type_set(instance);
 
        return instance->phy;
 }
@@ -1075,17 +1199,28 @@ static const struct mtk_phy_pdata tphy_v2_pdata = {
        .version = MTK_PHY_V2,
 };
 
+static const struct mtk_phy_pdata tphy_v3_pdata = {
+       .version = MTK_PHY_V3,
+};
+
 static const struct mtk_phy_pdata mt8173_pdata = {
        .avoid_rx_sen_degradation = true,
        .version = MTK_PHY_V1,
 };
 
+static const struct mtk_phy_pdata mt8195_pdata = {
+       .sw_pll_48m_to_26m = true,
+       .version = MTK_PHY_V3,
+};
+
 static const struct of_device_id mtk_tphy_id_table[] = {
        { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
        { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
        { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
+       { .compatible = "mediatek,mt8195-tphy", .data = &mt8195_pdata },
        { .compatible = "mediatek,generic-tphy-v1", .data = &tphy_v1_pdata },
        { .compatible = "mediatek,generic-tphy-v2", .data = &tphy_v2_pdata },
+       { .compatible = "mediatek,generic-tphy-v3", .data = &tphy_v3_pdata },
        { },
 };
 MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
@@ -1129,16 +1264,21 @@ static int mtk_tphy_probe(struct platform_device *pdev)
                }
        }
 
-       tphy->src_ref_clk = U3P_REF_CLK;
-       tphy->src_coef = U3P_SLEW_RATE_COEF;
-       /* update parameters of slew rate calibrate if exist */
-       device_property_read_u32(dev, "mediatek,src-ref-clk-mhz",
-               &tphy->src_ref_clk);
-       device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef);
+       if (tphy->pdata->version < MTK_PHY_V3) {
+               tphy->src_ref_clk = U3P_REF_CLK;
+               tphy->src_coef = U3P_SLEW_RATE_COEF;
+               /* update parameters of slew rate calibrate if exist */
+               device_property_read_u32(dev, "mediatek,src-ref-clk-mhz",
+                                        &tphy->src_ref_clk);
+               device_property_read_u32(dev, "mediatek,src-coef",
+                                        &tphy->src_coef);
+       }
 
        port = 0;
        for_each_child_of_node(np, child_np) {
                struct mtk_phy_instance *instance;
+               struct clk_bulk_data *clks;
+               struct device *subdev;
                struct phy *phy;
 
                instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1156,16 +1296,16 @@ static int mtk_tphy_probe(struct platform_device *pdev)
                        goto put_child;
                }
 
+               subdev = &phy->dev;
                retval = of_address_to_resource(child_np, 0, &res);
                if (retval) {
-                       dev_err(dev, "failed to get address resource(id-%d)\n",
+                       dev_err(subdev, "failed to get address resource(id-%d)\n",
                                port);
                        goto put_child;
                }
 
-               instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+               instance->port_base = devm_ioremap_resource(subdev, &res);
                if (IS_ERR(instance->port_base)) {
-                       dev_err(dev, "failed to remap phy regs\n");
                        retval = PTR_ERR(instance->port_base);
                        goto put_child;
                }
@@ -1175,20 +1315,16 @@ static int mtk_tphy_probe(struct platform_device *pdev)
                phy_set_drvdata(phy, instance);
                port++;
 
-               instance->ref_clk = devm_clk_get_optional(&phy->dev, "ref");
-               if (IS_ERR(instance->ref_clk)) {
-                       dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
-                       retval = PTR_ERR(instance->ref_clk);
+               clks = instance->clks;
+               clks[0].id = "ref";     /* digital (& analog) clock */
+               clks[1].id = "da_ref";  /* analog clock */
+               retval = devm_clk_bulk_get_optional(subdev, TPHY_CLKS_CNT, clks);
+               if (retval)
                        goto put_child;
-               }
 
-               instance->da_ref_clk =
-                       devm_clk_get_optional(&phy->dev, "da_ref");
-               if (IS_ERR(instance->da_ref_clk)) {
-                       dev_err(dev, "failed to get da_ref_clk(id-%d)\n", port);
-                       retval = PTR_ERR(instance->da_ref_clk);
+               retval = phy_type_syscon_get(instance, child_np);
+               if (retval)
                        goto put_child;
-               }
        }
 
        provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
index 769b00b..a6af069 100644 (file)
 #define FRC_CDR_ISO_EN              BIT(19)
 #define CDR_ISO_EN                  BIT(20)
 
+#define UFSPHY_CLKS_CNT    2
+
 struct ufs_mtk_phy {
        struct device *dev;
        void __iomem *mmio;
-       struct clk *mp_clk;
-       struct clk *unipro_clk;
+       struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
 };
 
 static inline u32 mphy_readl(struct ufs_mtk_phy *phy, u32 reg)
@@ -74,20 +75,11 @@ static struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy)
 static int ufs_mtk_phy_clk_init(struct ufs_mtk_phy *phy)
 {
        struct device *dev = phy->dev;
+       struct clk_bulk_data *clks = phy->clks;
 
-       phy->unipro_clk = devm_clk_get(dev, "unipro");
-       if (IS_ERR(phy->unipro_clk)) {
-               dev_err(dev, "failed to get clock: unipro");
-               return PTR_ERR(phy->unipro_clk);
-       }
-
-       phy->mp_clk = devm_clk_get(dev, "mp");
-       if (IS_ERR(phy->mp_clk)) {
-               dev_err(dev, "failed to get clock: mp");
-               return PTR_ERR(phy->mp_clk);
-       }
-
-       return 0;
+       clks[0].id = "unipro";
+       clks[1].id = "mp";
+       return devm_clk_bulk_get(dev, UFSPHY_CLKS_CNT, clks);
 }
 
 static void ufs_mtk_phy_set_active(struct ufs_mtk_phy *phy)
@@ -150,26 +142,13 @@ static int ufs_mtk_phy_power_on(struct phy *generic_phy)
        struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
        int ret;
 
-       ret = clk_prepare_enable(phy->unipro_clk);
-       if (ret) {
-               dev_err(phy->dev, "unipro_clk enable failed %d\n", ret);
-               goto out;
-       }
-
-       ret = clk_prepare_enable(phy->mp_clk);
-       if (ret) {
-               dev_err(phy->dev, "mp_clk enable failed %d\n", ret);
-               goto out_unprepare_unipro_clk;
-       }
+       ret = clk_bulk_prepare_enable(UFSPHY_CLKS_CNT, phy->clks);
+       if (ret)
+               return ret;
 
        ufs_mtk_phy_set_active(phy);
 
        return 0;
-
-out_unprepare_unipro_clk:
-       clk_disable_unprepare(phy->unipro_clk);
-out:
-       return ret;
 }
 
 static int ufs_mtk_phy_power_off(struct phy *generic_phy)
@@ -178,8 +157,7 @@ static int ufs_mtk_phy_power_off(struct phy *generic_phy)
 
        ufs_mtk_phy_set_deep_hibern(phy);
 
-       clk_disable_unprepare(phy->unipro_clk);
-       clk_disable_unprepare(phy->mp_clk);
+       clk_bulk_disable_unprepare(UFSPHY_CLKS_CNT, phy->clks);
 
        return 0;
 }
index cfe3594..f140321 100644 (file)
@@ -234,6 +234,11 @@ static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
        [QPHY_PCS_READY_STATUS]         = 0x160,
 };
 
+static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
+       [QPHY_START_CTRL]               = 0x00,
+       [QPHY_PCS_READY_STATUS]         = 0x168,
+};
+
 static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
        [QPHY_SW_RESET]                 = 0x00,
        [QPHY_START_CTRL]               = 0x44,
@@ -1329,6 +1334,97 @@ 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 sm6115_ufsphy_serdes_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
+       QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
+       QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
+       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_TIMER1, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
+       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_VCO_TUNE1_MODE0, 0x28),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
+       QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
+       QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
+       QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
+
+       /* Rate B */
+       QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
+       QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
+       QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
+       QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
+       QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
+       QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
+       QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
+       QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
+       QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
+       QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
+       QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
+       QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
+       QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
+       QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
+       QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
+};
+
 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
        QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
@@ -2035,6 +2131,113 @@ static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
 };
 
+static const struct qmp_phy_init_tbl sc8180x_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),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
+};
+
+static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_tx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
+       QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x5),
+};
+
+static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_rx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x07),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x6e),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6e),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x4a),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x37),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x39),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x39),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xdb),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x75),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0xc0),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x05),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
+       QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
+};
+
+static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x01),
+};
+
+static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
+       QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+};
+
 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),
@@ -3289,6 +3492,31 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
        .no_pcs_sw_reset        = true,
 };
 
+static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
+       .type                   = PHY_TYPE_UFS,
+       .nlanes                 = 1,
+
+       .serdes_tbl             = sm6115_ufsphy_serdes_tbl,
+       .serdes_tbl_num         = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
+       .tx_tbl                 = sm6115_ufsphy_tx_tbl,
+       .tx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
+       .rx_tbl                 = sm6115_ufsphy_rx_tbl,
+       .rx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
+       .pcs_tbl                = sm6115_ufsphy_pcs_tbl,
+       .pcs_tbl_num            = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
+       .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                   = sm6115_ufsphy_regs_layout,
+
+       .start_ctrl             = SERDES_START,
+       .pwrdn_ctrl             = SW_PWRDN,
+
+       .is_dual_lane_phy       = false,
+       .no_pcs_sw_reset        = true,
+};
+
 static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
        .type                   = PHY_TYPE_PCIE,
        .nlanes                 = 1,
@@ -3399,6 +3627,76 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
        .is_dual_lane_phy       = true,
 };
 
+static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
+       .type = PHY_TYPE_PCIE,
+       .nlanes = 1,
+
+       .serdes_tbl             = sc8180x_qmp_pcie_serdes_tbl,
+       .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
+       .tx_tbl                 = sc8180x_qmp_pcie_tx_tbl,
+       .tx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl),
+       .rx_tbl                 = sc8180x_qmp_pcie_rx_tbl,
+       .rx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_rx_tbl),
+       .pcs_tbl                = sc8180x_qmp_pcie_pcs_tbl,
+       .pcs_tbl_num            = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_tbl),
+       .pcs_misc_tbl           = sc8180x_qmp_pcie_pcs_misc_tbl,
+       .pcs_misc_tbl_num       = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_misc_tbl),
+       .clk_list               = sdm845_pciephy_clk_l,
+       .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
+       .reset_list             = sdm845_pciephy_reset_l,
+       .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
+       .vreg_list              = qmp_phy_vreg_l,
+       .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
+       .regs                   = sm8250_pcie_regs_layout,
+
+       .start_ctrl             = PCS_START | SERDES_START,
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+
+       .has_pwrdn_delay        = true,
+       .pwrdn_delay_min        = 995,          /* us */
+       .pwrdn_delay_max        = 1005,         /* us */
+};
+
+static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
+       .type                   = PHY_TYPE_DP,
+       .nlanes                 = 1,
+
+       .serdes_tbl             = qmp_v4_dp_serdes_tbl,
+       .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
+       .tx_tbl                 = qmp_v4_dp_tx_tbl,
+       .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
+
+       .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
+       .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
+       .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
+       .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
+       .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
+       .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
+       .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
+       .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
+
+       .clk_list               = qmp_v3_phy_clk_l,
+       .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
+       .reset_list             = sc7180_usb3phy_reset_l,
+       .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
+       .vreg_list              = qmp_phy_vreg_l,
+       .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
+       .regs                   = qmp_v3_usb3phy_regs_layout,
+
+       .has_phy_dp_com_ctrl    = true,
+       .is_dual_lane_phy       = true,
+
+       .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
+       .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
+       .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
+       .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
+};
+
+static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
+       .usb_cfg                = &sm8150_usb3phy_cfg,
+       .dp_cfg                 = &sc8180x_dpphy_cfg,
+};
+
 static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
        .type                   = PHY_TYPE_USB3,
        .nlanes                 = 1,
@@ -5018,6 +5316,7 @@ static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
 {
        struct clk_init_data init = { };
        struct qmp_phy_dp_clks *dp_clks;
+       char name[64];
        int ret;
 
        dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
@@ -5027,15 +5326,17 @@ static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
        dp_clks->qphy = qphy;
        qphy->dp_clks = dp_clks;
 
+       snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
        init.ops = &qcom_qmp_dp_link_clk_ops;
-       init.name = "qmp_dp_phy_pll_link_clk";
+       init.name = name;
        dp_clks->dp_link_hw.init = &init;
        ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
        if (ret)
                return ret;
 
+       snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
        init.ops = &qcom_qmp_dp_pixel_clk_ops;
-       init.name = "qmp_dp_phy_pll_vco_div_clk";
+       init.name = name;
        dp_clks->dp_pixel_hw.init = &init;
        ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
        if (ret)
@@ -5226,18 +5527,27 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
                .compatible = "qcom,ipq6018-qmp-pcie-phy",
                .data = &ipq6018_pciephy_cfg,
        }, {
+               .compatible = "qcom,ipq6018-qmp-usb3-phy",
+               .data = &ipq8074_usb3phy_cfg,
+       }, {
                .compatible = "qcom,sc7180-qmp-usb3-phy",
                .data = &sc7180_usb3phy_cfg,
        }, {
                .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
                /* It's a combo phy */
        }, {
+               .compatible = "qcom,sc8180x-qmp-pcie-phy",
+               .data = &sc8180x_pciephy_cfg,
+       }, {
                .compatible = "qcom,sc8180x-qmp-ufs-phy",
                .data = &sm8150_ufsphy_cfg,
        }, {
                .compatible = "qcom,sc8180x-qmp-usb3-phy",
                .data = &sm8150_usb3phy_cfg,
        }, {
+               .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
+               /* It's a combo phy */
+       }, {
                .compatible = "qcom,sdm845-qhp-pcie-phy",
                .data = &sdm845_qhp_pciephy_cfg,
        }, {
@@ -5256,6 +5566,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
                .compatible = "qcom,msm8998-qmp-usb3-phy",
                .data = &msm8998_usb3phy_cfg,
        }, {
+               .compatible = "qcom,sm6115-qmp-ufs-phy",
+               .data = &sm6115_ufsphy_cfg,
+       }, {
                .compatible = "qcom,sm8150-qmp-ufs-phy",
                .data = &sm8150_ufsphy_cfg,
        }, {
@@ -5314,6 +5627,10 @@ static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
                .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
                .data = &sm8250_usb3dpphy_cfg,
        },
+       {
+               .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
+               .data = &sc8180x_usb3dpphy_cfg,
+       },
        { }
 };
 
index 6592b58..bebeac2 100644 (file)
 #define QSERDES_COM_VCO_TUNE2_MODE0                    0x130
 #define QSERDES_COM_VCO_TUNE1_MODE1                    0x134
 #define QSERDES_COM_VCO_TUNE2_MODE1                    0x138
+#define QSERDES_COM_VCO_TUNE_INITVAL1                  0x13c
+#define QSERDES_COM_VCO_TUNE_INITVAL2                  0x140
 #define QSERDES_COM_VCO_TUNE_TIMER1                    0x144
 #define QSERDES_COM_VCO_TUNE_TIMER2                    0x148
 #define QSERDES_COM_BG_CTRL                            0x170
 /* Only for QMP V2 PHY - RX registers */
 #define QSERDES_RX_UCDR_SO_GAIN_HALF                   0x010
 #define QSERDES_RX_UCDR_SO_GAIN                                0x01c
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_HALF               0x030
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER            0x034
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_EIGHTH             0x038
+#define QSERDES_RX_UCDR_SVS_SO_GAIN                    0x03c
 #define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN               0x040
 #define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE       0x048
 #define QSERDES_RX_RX_TERM_BW                          0x090
 #define QPHY_POWER_DOWN_CONTROL                                0x04
 #define QPHY_TXDEEMPH_M6DB_V0                          0x24
 #define QPHY_TXDEEMPH_M3P5DB_V0                                0x28
+#define QPHY_TX_LARGE_AMP_DRV_LVL                      0x34
+#define QPHY_TX_LARGE_AMP_POST_EMP_LVL                 0x38
+#define QPHY_TX_SMALL_AMP_DRV_LVL                      0x3c
+#define QPHY_TX_SMALL_AMP_POST_EMP_LVL                 0x40
 #define QPHY_ENDPOINT_REFCLK_DRIVE                     0x54
 #define QPHY_RX_IDLE_DTCT_CNTRL                                0x58
 #define QPHY_POWER_STATE_CONFIG1                       0x60
 #define QPHY_LOCK_DETECT_CONFIG3                       0x88
 #define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK               0xa0
 #define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK                 0xa4
+#define QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP            0xcc
+#define QPHY_RX_SYM_RESYNC_CTRL                                0x13c
+#define QPHY_RX_MIN_HIBERN8_TIME                       0x140
+#define QPHY_RX_SIGDET_CTRL2                           0x148
+#define QPHY_RX_PWM_GEAR_BAND                          0x154
 #define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB          0x1A8
 #define QPHY_OSC_DTCT_ACTIONS                          0x1AC
 #define QPHY_RX_SIGDET_LVL                             0x1D8
 #define QSERDES_V3_COM_SSC_PER2                                0x020
 #define QSERDES_V3_COM_SSC_STEP_SIZE1                  0x024
 #define QSERDES_V3_COM_SSC_STEP_SIZE2                  0x028
+#define QSERDES_V3_COM_POST_DIV                                0x02c
+#define QSERDES_V3_COM_POST_DIV_MUX                    0x030
 #define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN             0x034
 # define QSERDES_V3_COM_BIAS_EN                                0x0001
 # define QSERDES_V3_COM_BIAS_EN_MUX                    0x0002
 #define QSERDES_V3_COM_CLK_ENABLE1                     0x038
 #define QSERDES_V3_COM_SYS_CLK_CTRL                    0x03c
 #define QSERDES_V3_COM_SYSCLK_BUF_ENABLE               0x040
+#define QSERDES_V3_COM_PLL_EN                          0x044
 #define QSERDES_V3_COM_PLL_IVCO                                0x048
 #define QSERDES_V3_COM_LOCK_CMP1_MODE0                 0x098
 #define QSERDES_V3_COM_LOCK_CMP2_MODE0                 0x09c
index 5c6c176..53e46c2 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/**
+/*
  * Copyright (C) 2016 Linaro Ltd
  */
 #include <linux/module.h>
index fbc5523..9de617c 100644 (file)
@@ -64,6 +64,7 @@
 /* VBCTRL */
 #define USB2_VBCTRL_OCCLREN            BIT(16)
 #define USB2_VBCTRL_DRVVBUSSEL         BIT(8)
+#define USB2_VBCTRL_VBOUT              BIT(0)
 
 /* LINECTRL1 */
 #define USB2_LINECTRL1_DPRPD_EN                BIT(19)
 #define USB2_ADPCTRL_IDPULLUP          BIT(5)  /* 1 = ID sampling is enabled */
 #define USB2_ADPCTRL_DRVVBUS           BIT(4)
 
+/*  RZ/G2L specific */
+#define USB2_OBINT_IDCHG_EN            BIT(0)
+#define USB2_LINECTRL1_USB2_IDMON      BIT(0)
+
 #define NUM_OF_PHYS                    4
 enum rcar_gen3_phy_index {
        PHY_INDEX_BOTH_HC,
@@ -112,9 +117,16 @@ struct rcar_gen3_chan {
        struct mutex lock;      /* protects rphys[...].powered */
        enum usb_dr_mode dr_mode;
        int irq;
+       u32 obint_enable_bits;
        bool extcon_host;
        bool is_otg_channel;
        bool uses_otg_pins;
+       bool soc_no_adp_ctrl;
+};
+
+struct rcar_gen3_phy_drv_data {
+       const struct phy_ops *phy_usb2_ops;
+       bool no_adp_ctrl;
 };
 
 /*
@@ -172,14 +184,22 @@ static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
 static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 {
        void __iomem *usb2_base = ch->base;
-       u32 val = readl(usb2_base + USB2_ADPCTRL);
+       u32 vbus_ctrl_reg = USB2_ADPCTRL;
+       u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS;
+       u32 val;
 
        dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
+       if (ch->soc_no_adp_ctrl) {
+               vbus_ctrl_reg = USB2_VBCTRL;
+               vbus_ctrl_val = USB2_VBCTRL_VBOUT;
+       }
+
+       val = readl(usb2_base + vbus_ctrl_reg);
        if (vbus)
-               val |= USB2_ADPCTRL_DRVVBUS;
+               val |= vbus_ctrl_val;
        else
-               val &= ~USB2_ADPCTRL_DRVVBUS;
-       writel(val, usb2_base + USB2_ADPCTRL);
+               val &= ~vbus_ctrl_val;
+       writel(val, usb2_base + vbus_ctrl_reg);
 }
 
 static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
@@ -188,9 +208,9 @@ static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
        u32 val = readl(usb2_base + USB2_OBINTEN);
 
        if (ch->uses_otg_pins && enable)
-               val |= USB2_OBINT_BITS;
+               val |= ch->obint_enable_bits;
        else
-               val &= ~USB2_OBINT_BITS;
+               val &= ~ch->obint_enable_bits;
        writel(val, usb2_base + USB2_OBINTEN);
 }
 
@@ -252,6 +272,9 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
        if (!ch->uses_otg_pins)
                return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
 
+       if (ch->soc_no_adp_ctrl)
+               return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON);
+
        return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
 }
 
@@ -376,16 +399,17 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
              USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD;
        writel(val, usb2_base + USB2_LINECTRL1);
 
-       val = readl(usb2_base + USB2_VBCTRL);
-       val &= ~USB2_VBCTRL_OCCLREN;
-       writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
-       val = readl(usb2_base + USB2_ADPCTRL);
-       writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
-
+       if (!ch->soc_no_adp_ctrl) {
+               val = readl(usb2_base + USB2_VBCTRL);
+               val &= ~USB2_VBCTRL_OCCLREN;
+               writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+               val = readl(usb2_base + USB2_ADPCTRL);
+               writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+       }
        msleep(20);
 
        writel(0xffffffff, usb2_base + USB2_OBINTSTA);
-       writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
+       writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN);
 
        rcar_gen3_device_recognition(ch);
 }
@@ -397,9 +421,9 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
        u32 status = readl(usb2_base + USB2_OBINTSTA);
        irqreturn_t ret = IRQ_NONE;
 
-       if (status & USB2_OBINT_BITS) {
+       if (status & ch->obint_enable_bits) {
                dev_vdbg(ch->dev, "%s: %08x\n", __func__, status);
-               writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+               writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA);
                rcar_gen3_device_recognition(ch);
                ret = IRQ_HANDLED;
        }
@@ -535,26 +559,45 @@ static const struct phy_ops rz_g1c_phy_usb2_ops = {
        .owner          = THIS_MODULE,
 };
 
+static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = {
+       .phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
+       .no_adp_ctrl = false,
+};
+
+static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = {
+       .phy_usb2_ops = &rz_g1c_phy_usb2_ops,
+       .no_adp_ctrl = false,
+};
+
+static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = {
+       .phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
+       .no_adp_ctrl = true,
+};
+
 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
        {
                .compatible = "renesas,usb2-phy-r8a77470",
-               .data = &rz_g1c_phy_usb2_ops,
+               .data = &rz_g1c_phy_usb2_data,
        },
        {
                .compatible = "renesas,usb2-phy-r8a7795",
-               .data = &rcar_gen3_phy_usb2_ops,
+               .data = &rcar_gen3_phy_usb2_data,
        },
        {
                .compatible = "renesas,usb2-phy-r8a7796",
-               .data = &rcar_gen3_phy_usb2_ops,
+               .data = &rcar_gen3_phy_usb2_data,
        },
        {
                .compatible = "renesas,usb2-phy-r8a77965",
-               .data = &rcar_gen3_phy_usb2_ops,
+               .data = &rcar_gen3_phy_usb2_data,
+       },
+       {
+               .compatible = "renesas,rzg2l-usb2-phy",
+               .data = &rz_g2l_phy_usb2_data,
        },
        {
                .compatible = "renesas,rcar-gen3-usb2-phy",
-               .data = &rcar_gen3_phy_usb2_ops,
+               .data = &rcar_gen3_phy_usb2_data,
        },
        { /* sentinel */ },
 };
@@ -608,10 +651,10 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
 
 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 {
+       const struct rcar_gen3_phy_drv_data *phy_data;
        struct device *dev = &pdev->dev;
        struct rcar_gen3_chan *channel;
        struct phy_provider *provider;
-       const struct phy_ops *phy_usb2_ops;
        int ret = 0, i;
 
        if (!dev->of_node) {
@@ -627,6 +670,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
        if (IS_ERR(channel->base))
                return PTR_ERR(channel->base);
 
+       channel->obint_enable_bits = USB2_OBINT_BITS;
        /* get irq number here and request_irq for OTG in phy_init */
        channel->irq = platform_get_irq_optional(pdev, 0);
        channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
@@ -653,16 +697,21 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
         * And then, phy-core will manage runtime pm for this device.
         */
        pm_runtime_enable(dev);
-       phy_usb2_ops = of_device_get_match_data(dev);
-       if (!phy_usb2_ops) {
+
+       phy_data = of_device_get_match_data(dev);
+       if (!phy_data) {
                ret = -EINVAL;
                goto error;
        }
 
+       channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl;
+       if (phy_data->no_adp_ctrl)
+               channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
+
        mutex_init(&channel->lock);
        for (i = 0; i < NUM_OF_PHYS; i++) {
                channel->rphys[i].phy = devm_phy_create(dev, NULL,
-                                                       phy_usb2_ops);
+                                                       phy_data->phy_usb2_ops);
                if (IS_ERR(channel->rphys[i].phy)) {
                        dev_err(dev, "Failed to create USB2 PHY\n");
                        ret = PTR_ERR(channel->rphys[i].phy);
index beacac1..4f569d9 100644 (file)
@@ -1180,8 +1180,10 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 next_child:
                /* to prevent out of boundary */
-               if (++index >= rphy->phy_cfg->num_ports)
+               if (++index >= rphy->phy_cfg->num_ports) {
+                       of_node_put(child_np);
                        break;
+               }
        }
 
        provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
index 3959100..65e4cc5 100644 (file)
@@ -2,7 +2,10 @@
 obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)      += phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)    += phy-exynos-mipi-video.o
 obj-$(CONFIG_PHY_EXYNOS_PCIE)          += phy-exynos-pcie.o
-obj-$(CONFIG_PHY_SAMSUNG_UFS)          += phy-samsung-ufs.o
+obj-$(CONFIG_PHY_SAMSUNG_UFS)          += phy-exynos-ufs.o
+phy-exynos-ufs-y                       += phy-samsung-ufs.o
+phy-exynos-ufs-y                       += phy-exynos7-ufs.o
+phy-exynos-ufs-y                       += phy-exynosautov9-ufs.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)         += phy-exynos-usb2.o
 phy-exynos-usb2-y                      += phy-samsung-usb2.o
 phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2)  += phy-exynos4210-usb2.o
similarity index 93%
rename from drivers/phy/samsung/phy-exynos7-ufs.h
rename to drivers/phy/samsung/phy-exynos7-ufs.c
index 5189231..7c9008e 100644 (file)
@@ -1,11 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * UFS PHY driver data for Samsung EXYNOS7 SoC
  *
  * Copyright (C) 2020 Samsung Electronics Co., Ltd.
  */
-#ifndef _PHY_EXYNOS7_UFS_H_
-#define _PHY_EXYNOS7_UFS_H_
 
 #include "phy-samsung-ufs.h"
 
@@ -68,7 +66,7 @@ static const struct samsung_ufs_phy_cfg *exynos7_ufs_phy_cfgs[CFG_TAG_MAX] = {
        [CFG_POST_PWR_HS]       = exynos7_post_pwr_hs_cfg,
 };
 
-static struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
+const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
        .cfg = exynos7_ufs_phy_cfgs,
        .isol = {
                .offset = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL,
@@ -77,5 +75,3 @@ static struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
        },
        .has_symbol_clk = 1,
 };
-
-#endif /* _PHY_EXYNOS7_UFS_H_ */
diff --git a/drivers/phy/samsung/phy-exynosautov9-ufs.c b/drivers/phy/samsung/phy-exynosautov9-ufs.c
new file mode 100644 (file)
index 0000000..36398a1
--- /dev/null
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UFS PHY driver data for Samsung EXYNOSAUTO v9 SoC
+ *
+ * Copyright (C) 2021 Samsung Electronics Co., Ltd.
+ */
+
+#include "phy-samsung-ufs.h"
+
+#define EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL           0x728
+#define EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_MASK      0x1
+#define EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_EN                BIT(0)
+
+#define PHY_TRSV_REG_CFG_AUTOV9(o, v, d) \
+       PHY_TRSV_REG_CFG_OFFSET(o, v, d, 0x50)
+
+/* Calibration for phy initialization */
+static const struct samsung_ufs_phy_cfg exynosautov9_pre_init_cfg[] = {
+       PHY_COMN_REG_CFG(0x023, 0x80, PWR_MODE_ANY),
+       PHY_COMN_REG_CFG(0x01d, 0x10, PWR_MODE_ANY),
+
+       PHY_TRSV_REG_CFG_AUTOV9(0x044, 0xb5, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x04d, 0x43, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x05b, 0x20, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x05e, 0xc0, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x038, 0x12, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x059, 0x58, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x06c, 0x18, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x06d, 0x02, PWR_MODE_ANY),
+
+       PHY_COMN_REG_CFG(0x023, 0xc0, PWR_MODE_ANY),
+       PHY_COMN_REG_CFG(0x023, 0x00, PWR_MODE_ANY),
+
+       PHY_TRSV_REG_CFG(0x042, 0x5d, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG(0x043, 0x80, PWR_MODE_ANY),
+
+       END_UFS_PHY_CFG,
+};
+
+/* Calibration for HS mode series A/B */
+static const struct samsung_ufs_phy_cfg exynosautov9_pre_pwr_hs_cfg[] = {
+       PHY_TRSV_REG_CFG(0x032, 0xbc, PWR_MODE_HS_ANY),
+       PHY_TRSV_REG_CFG(0x03c, 0x7f, PWR_MODE_HS_ANY),
+       PHY_TRSV_REG_CFG(0x048, 0xc0, PWR_MODE_HS_ANY),
+
+       PHY_TRSV_REG_CFG(0x04a, 0x00, PWR_MODE_HS_G3_SER_B),
+       PHY_TRSV_REG_CFG(0x04b, 0x10, PWR_MODE_HS_G1_SER_B |
+                                     PWR_MODE_HS_G3_SER_B),
+       PHY_TRSV_REG_CFG(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
+
+       END_UFS_PHY_CFG,
+};
+
+static const struct samsung_ufs_phy_cfg *exynosautov9_ufs_phy_cfgs[CFG_TAG_MAX] = {
+       [CFG_PRE_INIT]          = exynosautov9_pre_init_cfg,
+       [CFG_PRE_PWR_HS]        = exynosautov9_pre_pwr_hs_cfg,
+};
+
+const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = {
+       .cfg = exynosautov9_ufs_phy_cfgs,
+       .isol = {
+               .offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL,
+               .mask = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_MASK,
+               .en = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_EN,
+       },
+       .has_symbol_clk = 0,
+};
index dd9ab15..602ddef 100644 (file)
@@ -347,6 +347,9 @@ static const struct of_device_id samsung_ufs_phy_match[] = {
        {
                .compatible = "samsung,exynos7-ufs-phy",
                .data = &exynos7_ufs_phy,
+       }, {
+               .compatible = "samsung,exynosautov9-ufs-phy",
+               .data = &exynosautov9_ufs_phy,
        },
        {},
 };
index 5de7871..91a0e9f 100644 (file)
@@ -10,6 +10,9 @@
 #ifndef _PHY_SAMSUNG_UFS_
 #define _PHY_SAMSUNG_UFS_
 
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+
 #define PHY_COMN_BLK   1
 #define PHY_TRSV_BLK   2
 #define END_UFS_PHY_CFG { 0 }
        .id = PHY_COMN_BLK,     \
 }
 
-#define PHY_TRSV_REG_CFG(o, v, d) {    \
+#define PHY_TRSV_REG_CFG_OFFSET(o, v, d, c) {  \
        .off_0 = PHY_APB_ADDR((o)),     \
-       .off_1 = PHY_APB_ADDR((o) + PHY_TRSV_CH_OFFSET),        \
+       .off_1 = PHY_APB_ADDR((o) + (c)),       \
        .val = (v),             \
        .desc = (d),            \
        .id = PHY_TRSV_BLK,     \
 }
 
+#define PHY_TRSV_REG_CFG(o, v, d)      \
+       PHY_TRSV_REG_CFG_OFFSET(o, v, d, PHY_TRSV_CH_OFFSET)
+
 /* UFS PHY registers */
 #define PHY_PLL_LOCK_STATUS    0x1e
 #define PHY_CDR_LOCK_STATUS    0x5e
@@ -134,6 +140,7 @@ static inline void samsung_ufs_phy_ctrl_isol(
                           phy->isol->mask, isol ? 0 : phy->isol->en);
 }
 
-#include "phy-exynos7-ufs.h"
+extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy;
+extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy;
 
 #endif /* _PHY_SAMSUNG_UFS_ */
index 0aadac6..963de59 100644 (file)
@@ -1273,7 +1273,7 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev)
        return err;
 }
 
-static int tegra_xusb_padctl_suspend_noirq(struct device *dev)
+static __maybe_unused int tegra_xusb_padctl_suspend_noirq(struct device *dev)
 {
        struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
 
@@ -1283,7 +1283,7 @@ static int tegra_xusb_padctl_suspend_noirq(struct device *dev)
        return 0;
 }
 
-static int tegra_xusb_padctl_resume_noirq(struct device *dev)
+static __maybe_unused int tegra_xusb_padctl_resume_noirq(struct device *dev)
 {
        struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
 
index 5771e24..ac71017 100644 (file)
@@ -162,6 +162,8 @@ struct twl4030_usb {
        atomic_t                connected;
        bool                    vbus_supplied;
        bool                    musb_mailbox_pending;
+       unsigned long           runtime_suspended:1;
+       unsigned long           needs_resume:1;
 
        struct delayed_work     id_workaround_work;
 };
@@ -384,6 +386,9 @@ static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
        WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
 }
 
+static int twl4030_usb_runtime_suspend(struct device *dev);
+static int twl4030_usb_runtime_resume(struct device *dev);
+
 static int __maybe_unused twl4030_usb_suspend(struct device *dev)
 {
        struct twl4030_usb *twl = dev_get_drvdata(dev);
@@ -395,6 +400,10 @@ static int __maybe_unused twl4030_usb_suspend(struct device *dev)
         */
        dev_dbg(twl->dev, "%s\n", __func__);
        disable_irq(twl->irq);
+       if (!twl->runtime_suspended && !atomic_read(&twl->connected)) {
+               twl4030_usb_runtime_suspend(dev);
+               twl->needs_resume = 1;
+       }
 
        return 0;
 }
@@ -405,9 +414,13 @@ static int __maybe_unused twl4030_usb_resume(struct device *dev)
 
        dev_dbg(twl->dev, "%s\n", __func__);
        enable_irq(twl->irq);
+       if (twl->needs_resume)
+               twl4030_usb_runtime_resume(dev);
        /* check whether cable status changed */
        twl4030_usb_irq(0, twl);
 
+       twl->runtime_suspended = 0;
+
        return 0;
 }
 
@@ -422,6 +435,8 @@ static int __maybe_unused twl4030_usb_runtime_suspend(struct device *dev)
        regulator_disable(twl->usb1v8);
        regulator_disable(twl->usb3v1);
 
+       twl->runtime_suspended = 1;
+
        return 0;
 }
 
index 3565215..f478d8a 100644 (file)
@@ -626,6 +626,9 @@ static int xpsgtr_phy_power_on(struct phy *phy)
        struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy);
        int ret = 0;
 
+       /* Skip initialization if not required. */
+       if (!xpsgtr_phy_init_required(gtr_phy))
+               return ret;
        /*
         * Wait for the PLL to lock. For DP, only wait on DP0 to avoid
         * cumulating waits for both lanes. The user is expected to initialize