summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/phy/allwinner,suniv-f1c100s-usb-phy.yaml83
-rw-r--r--Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml5
-rw-r--r--Documentation/devicetree/bindings/phy/amlogic,meson-gxl-usb2-phy.yaml56
-rw-r--r--Documentation/devicetree/bindings/phy/mediatek,tphy.yaml1
-rw-r--r--Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt21
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt779
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.yaml654
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra186-xusb-padctl.yaml544
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml632
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra210-xusb-padctl.yaml786
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-ufs-phy.yaml3
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-usb3-phy.yaml3
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,pcie2-phy.yaml86
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml160
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml89
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml52
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml5
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml4
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml79
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml52
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt65
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.yaml67
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml33
-rw-r--r--Documentation/devicetree/bindings/phy/qcom-pcie2-phy.txt42
-rw-r--r--Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml1
-rw-r--r--Documentation/driver-api/phy/phy.rst24
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_memac.c9
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_main.c5
-rw-r--r--drivers/pci/controller/pci-tegra.c5
-rw-r--r--drivers/phy/allwinner/phy-sun4i-usb.c59
-rw-r--r--drivers/phy/mediatek/phy-mtk-io.h4
-rw-r--r--drivers/phy/phy-can-transceiver.c4
-rw-r--r--drivers/phy/phy-core.c51
-rw-r--r--drivers/phy/qualcomm/Kconfig68
-rw-r--r--drivers/phy/qualcomm/Makefile14
-rw-r--r--drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c259
-rw-r--r--drivers/phy/qualcomm/phy-qcom-pcie2.c6
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-combo.c750
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c6
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcie.c588
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h15
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h23
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v2.h25
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v3.h3
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v5.h5
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h31
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h31
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-v2.h19
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5.h4
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6.h16
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h18
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h82
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com.h2
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-ln-shrd-v6.h32
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h30
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_5nm.h5
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6.h77
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h45
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-ufs.c688
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-usb.c83
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp.h23
-rw-r--r--drivers/phy/qualcomm/phy-qcom-snps-eusb2.c441
-rw-r--r--drivers/phy/renesas/r8a779f0-ether-serdes.c65
-rw-r--r--drivers/phy/rockchip/phy-rockchip-typec.c7
-rw-r--r--drivers/phy/tegra/xusb.c17
-rw-r--r--drivers/phy/ti/phy-j721e-wiz.c66
-rw-r--r--drivers/usb/host/ehci-exynos.c23
-rw-r--r--drivers/usb/host/ohci-exynos.c23
-rw-r--r--include/linux/phy/phy.h16
69 files changed, 6574 insertions, 1495 deletions
diff --git a/Documentation/devicetree/bindings/phy/allwinner,suniv-f1c100s-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,suniv-f1c100s-usb-phy.yaml
new file mode 100644
index 000000000000..948839499235
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/allwinner,suniv-f1c100s-usb-phy.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/allwinner,suniv-f1c100s-usb-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner F1C100s USB PHY
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <mripard@kernel.org>
+
+properties:
+ "#phy-cells":
+ const: 1
+
+ compatible:
+ const: allwinner,suniv-f1c100s-usb-phy
+
+ reg:
+ maxItems: 1
+ description: PHY Control registers
+
+ reg-names:
+ const: phy_ctrl
+
+ clocks:
+ maxItems: 1
+ description: USB OTG PHY bus clock
+
+ clock-names:
+ const: usb0_phy
+
+ resets:
+ maxItems: 1
+ description: USB OTG reset
+
+ reset-names:
+ const: usb0_reset
+
+ usb0_id_det-gpios:
+ maxItems: 1
+ description: GPIO to the USB OTG ID pin
+
+ usb0_vbus_det-gpios:
+ maxItems: 1
+ description: GPIO to the USB OTG VBUS detect pin
+
+ usb0_vbus_power-supply:
+ description: Power supply to detect the USB OTG VBUS
+
+ usb0_vbus-supply:
+ description: Regulator controlling USB OTG VBUS
+
+required:
+ - "#phy-cells"
+ - compatible
+ - clocks
+ - clock-names
+ - reg
+ - reg-names
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/clock/suniv-ccu-f1c100s.h>
+ #include <dt-bindings/reset/suniv-ccu-f1c100s.h>
+
+ phy@1c13400 {
+ compatible = "allwinner,suniv-f1c100s-usb-phy";
+ reg = <0x01c13400 0x10>;
+ reg-names = "phy_ctrl";
+ clocks = <&ccu CLK_USB_PHY0>;
+ clock-names = "usb0_phy";
+ resets = <&ccu RST_USB_PHY0>;
+ reset-names = "usb0_reset";
+ #phy-cells = <1>;
+ usb0_id_det-gpios = <&pio 4 2 GPIO_ACTIVE_HIGH>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
index 129d26e99776..3314711292d6 100644
--- a/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
@@ -35,6 +35,11 @@ properties:
"#phy-cells":
const: 1
+ phy-supply:
+ description:
+ Phandle to a regulator that provides power to the PHY. This
+ regulator will be managed during the PHY power on/off sequence.
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-gxl-usb2-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson-gxl-usb2-phy.yaml
new file mode 100644
index 000000000000..c2f5c9d2fce6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/amlogic,meson-gxl-usb2-phy.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/amlogic,meson-gxl-usb2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Meson GXL USB2 PHY
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+
+properties:
+ compatible:
+ const: amlogic,meson-gxl-usb2-phy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: phy
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ items:
+ - const: phy
+
+ "#phy-cells":
+ const: 0
+
+ phy-supply: true
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ phy@78000 {
+ compatible = "amlogic,meson-gxl-usb2-phy";
+ reg = <0x78000 0x20>;
+ clocks = <&xtal>;
+ clock-names = "phy";
+ resets = <&phy_reset>;
+ reset-names = "phy";
+ #phy-cells = <0>;
+ phy-supply = <&usb2_supply>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 5613cc5106e3..230a17f24966 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -79,6 +79,7 @@ properties:
- enum:
- mediatek,mt2712-tphy
- mediatek,mt7629-tphy
+ - mediatek,mt7986-tphy
- mediatek,mt8183-tphy
- mediatek,mt8186-tphy
- mediatek,mt8192-tphy
diff --git a/Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt b/Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt
deleted file mode 100644
index b84a02ebffdf..000000000000
--- a/Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-* Amlogic Meson GXL and GXM USB2 PHY binding
-
-Required properties:
-- compatible: Should be "amlogic,meson-gxl-usb2-phy"
-- reg: The base address and length of the registers
-- #phys-cells: must be 0 (see phy-bindings.txt in this directory)
-
-Optional properties:
-- clocks: a phandle to the clock of this PHY
-- clock-names: must be "phy"
-- resets: a phandle to the reset line of this PHY
-- reset-names: must be "phy"
-- phy-supply: see phy-bindings.txt in this directory
-
-
-Example:
- usb2_phy0: phy@78000 {
- compatible = "amlogic,meson-gxl-usb2-phy";
- #phy-cells = <0>;
- reg = <0x0 0x78000 0x0 0x20>;
- };
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
deleted file mode 100644
index b62397d2bb0c..000000000000
--- a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
+++ /dev/null
@@ -1,779 +0,0 @@
-Device tree binding for NVIDIA Tegra XUSB pad controller
-========================================================
-
-The Tegra XUSB pad controller manages a set of I/O lanes (with differential
-signals) which connect directly to pins/pads on the SoC package. Each lane
-is controlled by a HW block referred to as a "pad" in the Tegra hardware
-documentation. Each such "pad" may control either one or multiple lanes,
-and thus contains any logic common to all its lanes. Each lane can be
-separately configured and powered up.
-
-Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or
-super-speed USB. Other lanes are for various types of low-speed, full-speed
-or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller
-contains a software-configurable mux that sits between the I/O controller
-ports (e.g. PCIe) and the lanes.
-
-In addition to per-lane configuration, USB 3.0 ports may require additional
-settings on a per-board basis.
-
-Pads will be represented as children of the top-level XUSB pad controller
-device tree node. Each lane exposed by the pad will be represented by its
-own subnode and can be referenced by users of the lane using the standard
-PHY bindings, as described by the phy-bindings.txt file in this directory.
-
-The Tegra hardware documentation refers to the connection between the XUSB
-pad controller and the XUSB controller as "ports". This is confusing since
-"port" is typically used to denote the physical USB receptacle. The device
-tree binding in this document uses the term "port" to refer to the logical
-abstraction of the signals that are routed to a USB receptacle (i.e. a PHY
-for the USB signal, the VBUS power supply, the USB 2.0 companion port for
-USB 3.0 receptacles, ...).
-
-Required properties:
---------------------
-- compatible: Must be:
- - Tegra124: "nvidia,tegra124-xusb-padctl"
- - Tegra132: "nvidia,tegra132-xusb-padctl", "nvidia,tegra124-xusb-padctl"
- - Tegra210: "nvidia,tegra210-xusb-padctl"
- - Tegra186: "nvidia,tegra186-xusb-padctl"
- - Tegra194: "nvidia,tegra194-xusb-padctl"
-- reg: Physical base address and length of the controller's registers.
-- resets: Must contain an entry for each entry in reset-names.
-- reset-names: Must include the following entries:
- - "padctl"
-
-For Tegra124:
-- avdd-pll-utmip-supply: UTMI PLL power supply. Must supply 1.8 V.
-- avdd-pll-erefe-supply: PLLE reference PLL power supply. Must supply 1.05 V.
-- avdd-pex-pll-supply: PCIe/USB3 PLL power supply. Must supply 1.05 V.
-- hvdd-pex-pll-e-supply: High-voltage PLLE power supply. Must supply 3.3 V.
-
-For Tegra210:
-- avdd-pll-utmip-supply: UTMI PLL power supply. Must supply 1.8 V.
-- avdd-pll-uerefe-supply: PLLE reference PLL power supply. Must supply 1.05 V.
-- dvdd-pex-pll-supply: PCIe/USB3 PLL power supply. Must supply 1.05 V.
-- hvdd-pex-pll-e-supply: High-voltage PLLE power supply. Must supply 1.8 V.
-- nvidia,pmc: phandle and specifier referring to the Tegra210 PMC node.
-
-For Tegra186:
-- avdd-pll-erefeut-supply: UPHY brick and reference clock as well as UTMI PHY
- power supply. Must supply 1.8 V.
-- avdd-usb-supply: USB I/Os, VBUS, ID, REXT, D+/D- power supply. Must supply
- 3.3 V.
-- vclamp-usb-supply: Bias rail for USB pad. Must supply 1.8 V.
-- vddio-hsic-supply: HSIC PHY power supply. Must supply 1.2 V.
-
-For Tegra194:
-- avdd-usb-supply: USB I/Os, VBUS, ID, REXT, D+/D- power supply. Must supply
- 3.3 V.
-- vclamp-usb-supply: Bias rail for USB pad. Must supply 1.8 V.
-
-Pad nodes:
-==========
-
-A required child node named "pads" contains a list of subnodes, one for each
-of the pads exposed by the XUSB pad controller. Each pad may need additional
-resources that can be referenced in its pad node.
-
-The "status" property is used to enable or disable the use of a pad. If set
-to "disabled", the pad will not be used on the given board. In order to use
-the pad and any of its lanes, this property must be set to "okay".
-
-For Tegra124 and Tegra132, the following pads exist: usb2, ulpi, hsic, pcie
-and sata. No extra resources are required for operation of these pads.
-
-For Tegra210, the following pads exist: usb2, hsic, pcie and sata. Below is
-a description of the properties of each pad.
-
-UTMI pad:
----------
-
-Required properties:
-- clocks: Must contain an entry for each entry in clock-names.
-- clock-names: Must contain the following entries:
- - "trk": phandle and specifier referring to the USB2 tracking clock
-
-HSIC pad:
----------
-
-Required properties:
-- clocks: Must contain an entry for each entry in clock-names.
-- clock-names: Must contain the following entries:
- - "trk": phandle and specifier referring to the HSIC tracking clock
-
-PCIe pad:
----------
-
-Required properties:
-- clocks: Must contain an entry for each entry in clock-names.
-- clock-names: Must contain the following entries:
- - "pll": phandle and specifier referring to the PLLE
-- resets: Must contain an entry for each entry in reset-names.
-- reset-names: Must contain the following entries:
- - "phy": reset for the PCIe UPHY block
-
-SATA pad:
----------
-
-Required properties:
-- resets: Must contain an entry for each entry in reset-names.
-- reset-names: Must contain the following entries:
- - "phy": reset for the SATA UPHY block
-
-
-PHY nodes:
-==========
-
-Each pad node has a child named "lanes" that contains one or more children of
-its own, each representing one of the lanes controlled by the pad.
-
-Required properties:
---------------------
-- status: Defines the operation status of the PHY. Valid values are:
- - "disabled": the PHY is disabled
- - "okay": the PHY is enabled
-- #phy-cells: Should be 0. Since each lane represents a single PHY, there is
- no need for an additional specifier.
-- nvidia,function: The output function of the PHY. See below for a list of
- valid functions per SoC generation.
-
-For Tegra124 and Tegra132, the list of valid PHY nodes is given below:
-- usb2: usb2-0, usb2-1, usb2-2
- - functions: "snps", "xusb", "uart"
-- ulpi: ulpi-0
- - functions: "snps", "xusb"
-- hsic: hsic-0, hsic-1
- - functions: "snps", "xusb"
-- pcie: pcie-0, pcie-1, pcie-2, pcie-3, pcie-4
- - functions: "pcie", "usb3-ss"
-- sata: sata-0
- - functions: "usb3-ss", "sata"
-
-For Tegra210, the list of valid PHY nodes is given below:
-- usb2: usb2-0, usb2-1, usb2-2, usb2-3
- - functions: "snps", "xusb", "uart"
-- hsic: hsic-0, hsic-1
- - functions: "snps", "xusb"
-- pcie: pcie-0, pcie-1, pcie-2, pcie-3, pcie-4, pcie-5, pcie-6
- - functions: "pcie-x1", "usb3-ss", "pcie-x4"
-- sata: sata-0
- - functions: "usb3-ss", "sata"
-
-For Tegra194, the list of valid PHY nodes is given below:
-- usb2: usb2-0, usb2-1, usb2-2, usb2-3
- - functions: "xusb"
-- usb3: usb3-0, usb3-1, usb3-2, usb3-3
- - functions: "xusb"
-
-Port nodes:
-===========
-
-A required child node named "ports" contains a list of all the ports exposed
-by the XUSB pad controller. Per-port configuration is only required for USB.
-
-USB2 ports:
------------
-
-Required properties:
-- status: Defines the operation status of the port. Valid values are:
- - "disabled": the port is disabled
- - "okay": the port is enabled
-- mode: A string that determines the mode in which to run the port. Valid
- values are:
- - "host": for USB host mode
- - "device": for USB device mode
- - "otg": for USB OTG mode
-
-Required properties for OTG/Peripheral capable USB2 ports:
-- usb-role-switch: Boolean property to indicate that the port support OTG or
- peripheral mode. If present, the port supports switching between USB host
- and peripheral roles. Connector should be added as subnode.
- See usb/usb-conn-gpio.txt.
-
-Optional properties:
-- nvidia,internal: A boolean property whose presence determines that a port
- is internal. In the absence of this property the port is considered to be
- external.
-- vbus-supply: phandle to a regulator supplying the VBUS voltage.
-
-ULPI ports:
------------
-
-Optional properties:
-- status: Defines the operation status of the port. Valid values are:
- - "disabled": the port is disabled
- - "okay": the port is enabled
-- nvidia,internal: A boolean property whose presence determines that a port
- is internal. In the absence of this property the port is considered to be
- external.
-- vbus-supply: phandle to a regulator supplying the VBUS voltage.
-
-HSIC ports:
------------
-
-Required properties:
-- status: Defines the operation status of the port. Valid values are:
- - "disabled": the port is disabled
- - "okay": the port is enabled
-
-Optional properties:
-- vbus-supply: phandle to a regulator supplying the VBUS voltage.
-
-Super-speed USB ports:
-----------------------
-
-Required properties:
-- status: Defines the operation status of the port. Valid values are:
- - "disabled": the port is disabled
- - "okay": the port is enabled
-- nvidia,usb2-companion: A single cell that specifies the physical port number
- to map this super-speed USB port to. The range of valid port numbers varies
- with the SoC generation:
- - 0-2: for Tegra124 and Tegra132
- - 0-3: for Tegra210
-
-Optional properties:
-- nvidia,internal: A boolean property whose presence determines that a port
- is internal. In the absence of this property the port is considered to be
- external.
-
-- maximum-speed: Only for Tegra194. A string property that specifies maximum
- supported speed of a usb3 port. Valid values are:
- - "super-speed-plus": default, the usb3 port supports USB 3.1 Gen 2 speed.
- - "super-speed": the usb3 port supports USB 3.1 Gen 1 speed only.
-
-For Tegra124 and Tegra132, the XUSB pad controller exposes the following
-ports:
-- 3x USB2: usb2-0, usb2-1, usb2-2
-- 1x ULPI: ulpi-0
-- 2x HSIC: hsic-0, hsic-1
-- 2x super-speed USB: usb3-0, usb3-1
-
-For Tegra210, the XUSB pad controller exposes the following ports:
-- 4x USB2: usb2-0, usb2-1, usb2-2, usb2-3
-- 2x HSIC: hsic-0, hsic-1
-- 4x super-speed USB: usb3-0, usb3-1, usb3-2, usb3-3
-
-For Tegra194, the XUSB pad controller exposes the following ports:
-- 4x USB2: usb2-0, usb2-1, usb2-2, usb2-3
-- 4x super-speed USB: usb3-0, usb3-1, usb3-2, usb3-3
-
-Examples:
-=========
-
-Tegra124 and Tegra132:
-----------------------
-
-SoC include:
-
- padctl@7009f000 {
- /* for Tegra124 */
- compatible = "nvidia,tegra124-xusb-padctl";
- /* for Tegra132 */
- compatible = "nvidia,tegra132-xusb-padctl",
- "nvidia,tegra124-xusb-padctl";
- reg = <0x0 0x7009f000 0x0 0x1000>;
- resets = <&tegra_car 142>;
- reset-names = "padctl";
-
- pads {
- usb2 {
- status = "disabled";
-
- lanes {
- usb2-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- usb2-1 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- usb2-2 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- ulpi {
- status = "disabled";
-
- lanes {
- ulpi-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- hsic {
- status = "disabled";
-
- lanes {
- hsic-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- hsic-1 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- pcie {
- status = "disabled";
-
- lanes {
- pcie-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-1 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-2 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-3 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-4 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- sata {
- status = "disabled";
-
- lanes {
- sata-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
- };
-
- ports {
- usb2-0 {
- status = "disabled";
- };
-
- usb2-1 {
- status = "disabled";
- };
-
- usb2-2 {
- status = "disabled";
- };
-
- ulpi-0 {
- status = "disabled";
- };
-
- hsic-0 {
- status = "disabled";
- };
-
- hsic-1 {
- status = "disabled";
- };
-
- usb3-0 {
- status = "disabled";
- };
-
- usb3-1 {
- status = "disabled";
- };
- };
- };
-
-Board file:
-
- padctl@7009f000 {
- status = "okay";
-
- pads {
- usb2 {
- status = "okay";
-
- lanes {
- usb2-0 {
- nvidia,function = "xusb";
- status = "okay";
- };
-
- usb2-1 {
- nvidia,function = "xusb";
- status = "okay";
- };
-
- usb2-2 {
- nvidia,function = "xusb";
- status = "okay";
- };
- };
- };
-
- pcie {
- status = "okay";
-
- lanes {
- pcie-0 {
- nvidia,function = "usb3-ss";
- status = "okay";
- };
-
- pcie-2 {
- nvidia,function = "pcie";
- status = "okay";
- };
-
- pcie-4 {
- nvidia,function = "pcie";
- status = "okay";
- };
- };
- };
-
- sata {
- status = "okay";
-
- lanes {
- sata-0 {
- nvidia,function = "sata";
- status = "okay";
- };
- };
- };
- };
-
- ports {
- /* Micro A/B */
- usb2-0 {
- status = "okay";
- mode = "otg";
- };
-
- /* Mini PCIe */
- usb2-1 {
- status = "okay";
- mode = "host";
- };
-
- /* USB3 */
- usb2-2 {
- status = "okay";
- mode = "host";
-
- vbus-supply = <&vdd_usb3_vbus>;
- };
-
- usb3-0 {
- nvidia,port = <2>;
- status = "okay";
- };
- };
- };
-
-Tegra210:
----------
-
-SoC include:
-
- padctl@7009f000 {
- compatible = "nvidia,tegra210-xusb-padctl";
- reg = <0x0 0x7009f000 0x0 0x1000>;
- resets = <&tegra_car 142>;
- reset-names = "padctl";
-
- status = "disabled";
-
- pads {
- usb2 {
- clocks = <&tegra_car TEGRA210_CLK_USB2_TRK>;
- clock-names = "trk";
- status = "disabled";
-
- lanes {
- usb2-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- usb2-1 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- usb2-2 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- usb2-3 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- hsic {
- clocks = <&tegra_car TEGRA210_CLK_HSIC_TRK>;
- clock-names = "trk";
- status = "disabled";
-
- lanes {
- hsic-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- hsic-1 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- pcie {
- clocks = <&tegra_car TEGRA210_CLK_PLL_E>;
- clock-names = "pll";
- resets = <&tegra_car 205>;
- reset-names = "phy";
- status = "disabled";
-
- lanes {
- pcie-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-1 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-2 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-3 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-4 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-5 {
- status = "disabled";
- #phy-cells = <0>;
- };
-
- pcie-6 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
-
- sata {
- clocks = <&tegra_car TEGRA210_CLK_PLL_E>;
- clock-names = "pll";
- resets = <&tegra_car 204>;
- reset-names = "phy";
- status = "disabled";
-
- lanes {
- sata-0 {
- status = "disabled";
- #phy-cells = <0>;
- };
- };
- };
- };
-
- ports {
- usb2-0 {
- status = "disabled";
- };
-
- usb2-1 {
- status = "disabled";
- };
-
- usb2-2 {
- status = "disabled";
- };
-
- usb2-3 {
- status = "disabled";
- };
-
- hsic-0 {
- status = "disabled";
- };
-
- hsic-1 {
- status = "disabled";
- };
-
- usb3-0 {
- status = "disabled";
- };
-
- usb3-1 {
- status = "disabled";
- };
-
- usb3-2 {
- status = "disabled";
- };
-
- usb3-3 {
- status = "disabled";
- };
- };
- };
-
-Board file:
-
- padctl@7009f000 {
- status = "okay";
-
- pads {
- usb2 {
- status = "okay";
-
- lanes {
- usb2-0 {
- nvidia,function = "xusb";
- status = "okay";
- };
-
- usb2-1 {
- nvidia,function = "xusb";
- status = "okay";
- };
-
- usb2-2 {
- nvidia,function = "xusb";
- status = "okay";
- };
-
- usb2-3 {
- nvidia,function = "xusb";
- status = "okay";
- };
- };
- };
-
- pcie {
- status = "okay";
-
- lanes {
- pcie-0 {
- nvidia,function = "pcie-x1";
- status = "okay";
- };
-
- pcie-1 {
- nvidia,function = "pcie-x4";
- status = "okay";
- };
-
- pcie-2 {
- nvidia,function = "pcie-x4";
- status = "okay";
- };
-
- pcie-3 {
- nvidia,function = "pcie-x4";
- status = "okay";
- };
-
- pcie-4 {
- nvidia,function = "pcie-x4";
- status = "okay";
- };
-
- pcie-5 {
- nvidia,function = "usb3-ss";
- status = "okay";
- };
-
- pcie-6 {
- nvidia,function = "usb3-ss";
- status = "okay";
- };
- };
- };
-
- sata {
- status = "okay";
-
- lanes {
- sata-0 {
- nvidia,function = "sata";
- status = "okay";
- };
- };
- };
- };
-
- ports {
- usb2-0 {
- status = "okay";
- mode = "otg";
- };
-
- usb2-1 {
- status = "okay";
- vbus-supply = <&vdd_5v0_rtl>;
- mode = "host";
- };
-
- usb2-2 {
- status = "okay";
- vbus-supply = <&vdd_usb_vbus>;
- mode = "host";
- };
-
- usb2-3 {
- status = "okay";
- mode = "host";
- };
-
- usb3-0 {
- status = "okay";
- nvidia,lanes = "pcie-6";
- nvidia,port = <1>;
- };
-
- usb3-1 {
- status = "okay";
- nvidia,lanes = "pcie-5";
- nvidia,port = <2>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.yaml
new file mode 100644
index 000000000000..33b41b6b2fd5
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.yaml
@@ -0,0 +1,654 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/nvidia,tegra124-xusb-padctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra124 XUSB pad controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The Tegra XUSB pad controller manages a set of I/O lanes (with differential
+ signals) which connect directly to pins/pads on the SoC package. Each lane
+ is controlled by a HW block referred to as a "pad" in the Tegra hardware
+ documentation. Each such "pad" may control either one or multiple lanes,
+ and thus contains any logic common to all its lanes. Each lane can be
+ separately configured and powered up.
+
+ Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or
+ super-speed USB. Other lanes are for various types of low-speed, full-speed
+ or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller
+ contains a software-configurable mux that sits between the I/O controller
+ ports (e.g. PCIe) and the lanes.
+
+ In addition to per-lane configuration, USB 3.0 ports may require additional
+ settings on a per-board basis.
+
+ Pads will be represented as children of the top-level XUSB pad controller
+ device tree node. Each lane exposed by the pad will be represented by its
+ own subnode and can be referenced by users of the lane using the standard
+ PHY bindings, as described by the phy-bindings.txt file in this directory.
+
+ The Tegra hardware documentation refers to the connection between the XUSB
+ pad controller and the XUSB controller as "ports". This is confusing since
+ "port" is typically used to denote the physical USB receptacle. The device
+ tree binding in this document uses the term "port" to refer to the logical
+ abstraction of the signals that are routed to a USB receptacle (i.e. a PHY
+ for the USB signal, the VBUS power supply, the USB 2.0 companion port for
+ USB 3.0 receptacles, ...).
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra124-xusb-padctl
+
+ - items:
+ - const: nvidia,tegra132-xusb-padctl
+ - const: nvidia,tegra124-xusb-padctl
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ items:
+ - description: XUSB pad controller interrupt
+
+ resets:
+ items:
+ - description: pad controller reset
+
+ reset-names:
+ items:
+ - const: padctl
+
+ avdd-pll-utmip-supply:
+ description: UTMI PLL power supply. Must supply 1.8 V.
+
+ avdd-pll-erefe-supply:
+ description: PLLE reference PLL power supply. Must supply 1.05 V.
+
+ avdd-pex-pll-supply:
+ description: PCIe/USB3 PLL power supply. Must supply 1.05 V.
+
+ hvdd-pex-pll-e-supply:
+ description: High-voltage PLLE power supply. Must supply 3.3 V.
+
+ pads:
+ description: A required child node named "pads" contains a list of
+ subnodes, one for each of the pads exposed by the XUSB pad controller.
+ Each pad may need additional resources that can be referenced in its
+ pad node.
+
+ The "status" property is used to enable or disable the use of a pad.
+ If set to "disabled", the pad will not be used on the given board. In
+ order to use the pad and any of its lanes, this property must be set
+ to "okay" or be absent.
+ type: object
+ additionalProperties: false
+ properties:
+ usb2:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: USB2 tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ ulpi:
+ type: object
+ additionalProperties: false
+ properties:
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ ulpi-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb ]
+
+ hsic:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: HSIC tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ hsic-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb ]
+
+ hsic-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb ]
+
+ pcie:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: PLLE clock
+
+ clock-names:
+ items:
+ - const: pll
+
+ resets:
+ items:
+ - description: reset for the PCIe UPHY block
+
+ reset-names:
+ items:
+ - const: phy
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ pcie-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie, usb3-ss ]
+
+ pcie-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie, usb3-ss ]
+
+ pcie-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie, usb3-ss ]
+
+ pcie-3:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie, usb3-ss ]
+
+ pcie-4:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie, usb3-ss ]
+
+ sata:
+ type: object
+ additionalProperties: false
+ properties:
+ resets:
+ items:
+ - description: reset for the SATA UPHY block
+
+ reset-names:
+ items:
+ - const: phy
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ sata-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ sata, usb3-ss ]
+
+ ports:
+ description: A required child node named "ports" contains a list of
+ subnodes, one for each of the ports exposed by the XUSB pad controller.
+ Each port may need additional resources that can be referenced in its
+ port node.
+
+ The "status" property is used to enable or disable the use of a port.
+ If set to "disabled", the port will not be used on the given board. In
+ order to use the port, this property must be set to "okay".
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ ulpi-0:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ hsic-0:
+ type: object
+ additionalProperties: false
+ properties:
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ hsic-1:
+ type: object
+ additionalProperties: false
+ properties:
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-0:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-1:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - resets
+ - reset-names
+ - avdd-pll-utmip-supply
+ - avdd-pll-erefe-supply
+ - avdd-pex-pll-supply
+ - hvdd-pex-pll-e-supply
+
+examples:
+ # Tegra124 and Tegra132
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ padctl@7009f000 {
+ compatible = "nvidia,tegra124-xusb-padctl";
+ reg = <0x7009f000 0x1000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&tegra_car 142>;
+ reset-names = "padctl";
+
+ avdd-pll-utmip-supply = <&vddio_1v8>;
+ avdd-pll-erefe-supply = <&avdd_1v05_run>;
+ avdd-pex-pll-supply = <&vdd_1v05_run>;
+ hvdd-pex-pll-e-supply = <&vdd_3v3_lp0>;
+
+ pads {
+ usb2 {
+ lanes {
+ usb2-0 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-1 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-2 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ ulpi {
+ lanes {
+ ulpi-0 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ hsic {
+ lanes {
+ hsic-0 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ hsic-1 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ pcie {
+ lanes {
+ pcie-0 {
+ nvidia,function = "usb3-ss";
+ #phy-cells = <0>;
+ };
+
+ pcie-1 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ pcie-2 {
+ nvidia,function = "pcie";
+ #phy-cells = <0>;
+ };
+
+ pcie-3 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ pcie-4 {
+ nvidia,function = "pcie";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ sata {
+ lanes {
+ sata-0 {
+ nvidia,function = "sata";
+ #phy-cells = <0>;
+ };
+ };
+ };
+ };
+
+ ports {
+ /* Micro A/B */
+ usb2-0 {
+ mode = "otg";
+ };
+
+ /* Mini PCIe */
+ usb2-1 {
+ mode = "host";
+ };
+
+ /* USB3 */
+ usb2-2 {
+ vbus-supply = <&vdd_usb3_vbus>;
+ mode = "host";
+ };
+
+ ulpi-0 {
+ status = "disabled";
+ };
+
+ hsic-0 {
+ status = "disabled";
+ };
+
+ hsic-1 {
+ status = "disabled";
+ };
+
+ usb3-0 {
+ nvidia,usb2-companion = <2>;
+ };
+
+ usb3-1 {
+ status = "disabled";
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra186-xusb-padctl.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra186-xusb-padctl.yaml
new file mode 100644
index 000000000000..8b1d5a8529e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra186-xusb-padctl.yaml
@@ -0,0 +1,544 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/nvidia,tegra186-xusb-padctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra186 XUSB pad controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The Tegra XUSB pad controller manages a set of I/O lanes (with differential
+ signals) which connect directly to pins/pads on the SoC package. Each lane
+ is controlled by a HW block referred to as a "pad" in the Tegra hardware
+ documentation. Each such "pad" may control either one or multiple lanes,
+ and thus contains any logic common to all its lanes. Each lane can be
+ separately configured and powered up.
+
+ Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or
+ super-speed USB. Other lanes are for various types of low-speed, full-speed
+ or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller
+ contains a software-configurable mux that sits between the I/O controller
+ ports (e.g. PCIe) and the lanes.
+
+ In addition to per-lane configuration, USB 3.0 ports may require additional
+ settings on a per-board basis.
+
+ Pads will be represented as children of the top-level XUSB pad controller
+ device tree node. Each lane exposed by the pad will be represented by its
+ own subnode and can be referenced by users of the lane using the standard
+ PHY bindings, as described by the phy-bindings.txt file in this directory.
+
+ The Tegra hardware documentation refers to the connection between the XUSB
+ pad controller and the XUSB controller as "ports". This is confusing since
+ "port" is typically used to denote the physical USB receptacle. The device
+ tree binding in this document uses the term "port" to refer to the logical
+ abstraction of the signals that are routed to a USB receptacle (i.e. a PHY
+ for the USB signal, the VBUS power supply, the USB 2.0 companion port for
+ USB 3.0 receptacles, ...).
+
+properties:
+ compatible:
+ const: nvidia,tegra186-xusb-padctl
+
+ reg:
+ items:
+ - description: pad controller registers
+ - description: AO registers
+
+ interrupts:
+ items:
+ - description: XUSB pad controller interrupt
+
+ reg-names:
+ items:
+ - const: padctl
+ - const: ao
+
+ resets:
+ items:
+ - description: pad controller reset
+
+ reset-names:
+ items:
+ - const: padctl
+
+ avdd-pll-erefeut-supply:
+ description: UPHY brick and reference clock as well as UTMI PHY
+ power supply. Must supply 1.8 V.
+
+ avdd-usb-supply:
+ description: USB I/Os, VBUS, ID, REXT, D+/D- power supply. Must
+ supply 3.3 V.
+
+ vclamp-usb-supply:
+ description: Bias rail for USB pad. Must supply 1.8 V.
+
+ vddio-hsic-supply:
+ description: HSIC PHY power supply. Must supply 1.2 V.
+
+ pads:
+ description: A required child node named "pads" contains a list of
+ subnodes, one for each of the pads exposed by the XUSB pad controller.
+ Each pad may need additional resources that can be referenced in its
+ pad node.
+
+ The "status" property is used to enable or disable the use of a pad.
+ If set to "disabled", the pad will not be used on the given board. In
+ order to use the pad and any of its lanes, this property must be set
+ to "okay" or be absent.
+ type: object
+ additionalProperties: false
+ properties:
+ usb2:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: USB2 tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ hsic:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: HSIC tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ hsic-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3:
+ type: object
+ additionalProperties: false
+ properties:
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ usb3-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ ports:
+ description: A required child node named "ports" contains a list of
+ subnodes, one for each of the ports exposed by the XUSB pad controller.
+ Each port may need additional resources that can be referenced in its
+ port node.
+
+ The "status" property is used to enable or disable the use of a port.
+ If set to "disabled", the port will not be used on the given board. In
+ order to use the port, this property must be set to "okay".
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ hsic-0:
+ type: object
+ additionalProperties: false
+
+ usb3-0:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-1:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-2:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - resets
+ - reset-names
+ - avdd-pll-erefeut-supply
+ - avdd-usb-supply
+ - vclamp-usb-supply
+ - vddio-hsic-supply
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra186-clock.h>
+ #include <dt-bindings/gpio/tegra186-gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/reset/tegra186-reset.h>
+
+ padctl@3520000 {
+ compatible = "nvidia,tegra186-xusb-padctl";
+ reg = <0x03520000 0x1000>,
+ <0x03540000 0x1000>;
+ reg-names = "padctl", "ao";
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+
+ resets = <&bpmp TEGRA186_RESET_XUSB_PADCTL>;
+ reset-names = "padctl";
+
+ avdd-pll-erefeut-supply = <&vdd_1v8_pll>;
+ avdd-usb-supply = <&vdd_3v3_sys>;
+ vclamp-usb-supply = <&vdd_1v8>;
+ vddio-hsic-supply = <&gnd>;
+
+ pads {
+ usb2 {
+ clocks = <&bpmp TEGRA186_CLK_USB2_TRK>;
+ clock-names = "trk";
+
+ lanes {
+ usb2-0 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-1 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-2 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ hsic {
+ clocks = <&bpmp TEGRA186_CLK_HSIC_TRK>;
+ clock-names = "trk";
+ status = "disabled";
+
+ lanes {
+ hsic-0 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ usb3 {
+ lanes {
+ usb3-0 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb3-1 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb3-2 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+ };
+ };
+ };
+
+ ports {
+ usb2-0 {
+ mode = "otg";
+ vbus-supply = <&vdd_usb0>;
+ usb-role-switch;
+
+ connector {
+ compatible = "gpio-usb-b-connector",
+ "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ vbus-gpios = <&gpio TEGRA186_MAIN_GPIO(X, 7) GPIO_ACTIVE_LOW>;
+ id-gpios = <&pmic 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ usb2-1 {
+ vbus-supply = <&vdd_usb1>;
+ mode = "host";
+ };
+
+ usb2-2 {
+ status = "disabled";
+ };
+
+ hsic-0 {
+ status = "disabled";
+ };
+
+ usb3-0 {
+ nvidia,usb2-companion = <1>;
+ };
+
+ usb3-1 {
+ status = "disabled";
+ };
+
+ usb3-2 {
+ status = "disabled";
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml
new file mode 100644
index 000000000000..6e3398399628
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml
@@ -0,0 +1,632 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/nvidia,tegra194-xusb-padctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra194 XUSB pad controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The Tegra XUSB pad controller manages a set of I/O lanes (with differential
+ signals) which connect directly to pins/pads on the SoC package. Each lane
+ is controlled by a HW block referred to as a "pad" in the Tegra hardware
+ documentation. Each such "pad" may control either one or multiple lanes,
+ and thus contains any logic common to all its lanes. Each lane can be
+ separately configured and powered up.
+
+ Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or
+ super-speed USB. Other lanes are for various types of low-speed, full-speed
+ or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller
+ contains a software-configurable mux that sits between the I/O controller
+ ports (e.g. PCIe) and the lanes.
+
+ In addition to per-lane configuration, USB 3.0 ports may require additional
+ settings on a per-board basis.
+
+ Pads will be represented as children of the top-level XUSB pad controller
+ device tree node. Each lane exposed by the pad will be represented by its
+ own subnode and can be referenced by users of the lane using the standard
+ PHY bindings, as described by the phy-bindings.txt file in this directory.
+
+ The Tegra hardware documentation refers to the connection between the XUSB
+ pad controller and the XUSB controller as "ports". This is confusing since
+ "port" is typically used to denote the physical USB receptacle. The device
+ tree binding in this document uses the term "port" to refer to the logical
+ abstraction of the signals that are routed to a USB receptacle (i.e. a PHY
+ for the USB signal, the VBUS power supply, the USB 2.0 companion port for
+ USB 3.0 receptacles, ...).
+
+properties:
+ compatible:
+ enum:
+ - nvidia,tegra194-xusb-padctl
+ - nvidia,tegra234-xusb-padctl
+
+ reg:
+ items:
+ - description: pad controller registers
+ - description: AO registers
+
+ reg-names:
+ items:
+ - const: padctl
+ - const: ao
+
+ interrupts:
+ items:
+ - description: XUSB pad controller interrupt
+
+ resets:
+ items:
+ - description: pad controller reset
+
+ reset-names:
+ items:
+ - const: padctl
+
+ avdd-usb-supply:
+ description: USB I/Os, VBUS, ID, REXT, D+/D- power supply. Must
+ supply 3.3 V.
+
+ vclamp-usb-supply:
+ description: Bias rail for USB pad. Must supply 1.8 V.
+
+ pads:
+ description: A required child node named "pads" contains a list of
+ subnodes, one for each of the pads exposed by the XUSB pad controller.
+ Each pad may need additional resources that can be referenced in its
+ pad node.
+
+ The "status" property is used to enable or disable the use of a pad.
+ If set to "disabled", the pad will not be used on the given board. In
+ order to use the pad and any of its lanes, this property must be set
+ to "okay" or absent.
+ type: object
+ additionalProperties: false
+ properties:
+ usb2:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: USB2 tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb2-3:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3:
+ type: object
+ additionalProperties: false
+ properties:
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ usb3-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ usb3-3:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ xusb ]
+
+ ports:
+ description: A required child node named "ports" contains a list of
+ subnodes, one for each of the ports exposed by the XUSB pad controller.
+ Each port may need additional resources that can be referenced in its
+ port node.
+
+ The "status" property is used to enable or disable the use of a port.
+ If set to "disabled", the port will not be used on the given board. In
+ order to use the port, this property must be set to "okay".
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-3:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb3-0:
+ type: object
+ additionalProperties: false
+ properties:
+ maximum-speed:
+ description: A string property that specifies the maximum
+ supported speed of a USB3 port.
+ $ref: /schemas/types.yaml#/definitions/string
+ oneOf:
+ - description: The USB3 port supports USB 3.1 Gen 2 speed.
+ This is the default.
+ const: super-speed-plus
+ - description: The USB3 port supports USB 3.1 Gen 1 speed
+ only.
+ const: super-speed
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-1:
+ type: object
+ additionalProperties: false
+ properties:
+ maximum-speed:
+ description: A string property that specifies the maximum
+ supported speed of a USB3 port.
+ $ref: /schemas/types.yaml#/definitions/string
+ oneOf:
+ - description: The USB3 port supports USB 3.1 Gen 2 speed.
+ This is the default.
+ const: super-speed-plus
+ - description: The USB3 port supports USB 3.1 Gen 1 speed
+ only.
+ const: super-speed
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-2:
+ type: object
+ additionalProperties: false
+ properties:
+ maximum-speed:
+ description: A string property that specifies the maximum
+ supported speed of a USB3 port.
+ $ref: /schemas/types.yaml#/definitions/string
+ oneOf:
+ - description: The USB3 port supports USB 3.1 Gen 2 speed.
+ This is the default.
+ const: super-speed-plus
+ - description: The USB3 port supports USB 3.1 Gen 1 speed
+ only.
+ const: super-speed
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-3:
+ type: object
+ additionalProperties: false
+ properties:
+ maximum-speed:
+ description: A string property that specifies the maximum
+ supported speed of a USB3 port.
+ $ref: /schemas/types.yaml#/definitions/string
+ oneOf:
+ - description: The USB3 port supports USB 3.1 Gen 2 speed.
+ This is the default.
+ const: super-speed-plus
+ - description: The USB3 port supports USB 3.1 Gen 1 speed
+ only.
+ const: super-speed
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - resets
+ - reset-names
+ - avdd-usb-supply
+ - vclamp-usb-supply
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra194-clock.h>
+ #include <dt-bindings/gpio/tegra194-gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/reset/tegra194-reset.h>
+
+ padctl@3520000 {
+ compatible = "nvidia,tegra194-xusb-padctl";
+ reg = <0x03520000 0x1000>,
+ <0x03540000 0x1000>;
+ reg-names = "padctl", "ao";
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+
+ resets = <&bpmp TEGRA194_RESET_XUSB_PADCTL>;
+ reset-names = "padctl";
+
+ avdd-usb-supply = <&vdd_usb_3v3>;
+ vclamp-usb-supply = <&vdd_1v8ao>;
+
+ pads {
+ usb2 {
+ clocks = <&bpmp TEGRA194_CLK_USB2_TRK>;
+ clock-names = "trk";
+
+ lanes {
+ usb2-0 {
+ nvidia,function = "xusb";
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ usb2-1 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-2 {
+ nvidia,function = "xusb";
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ usb2-3 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ usb3 {
+ lanes {
+ usb3-0 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb3-1 {
+ nvidia,function = "xusb";
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ usb3-2 {
+ nvidia,function = "xusb";
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ usb3-3 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+ };
+ };
+ };
+
+ ports {
+ usb2-0 {
+ status = "disabled";
+ };
+
+ usb2-1 {
+ vbus-supply = <&vdd_5v0_sys>;
+ mode = "host";
+ };
+
+ usb2-2 {
+ status = "disabled";
+ };
+
+ usb2-3 {
+ vbus-supply = <&vdd_5v_sata>;
+ mode = "host";
+ };
+
+ usb3-0 {
+ vbus-supply = <&vdd_5v0_sys>;
+ nvidia,usb2-companion = <1>;
+ };
+
+ usb3-1 {
+ status = "disabled";
+ };
+
+ usb3-2 {
+ status = "disabled";
+ };
+
+ usb3-3 {
+ maximum-speed = "super-speed";
+ vbus-supply = <&vdd_5v0_sys>;
+ nvidia,usb2-companion = <3>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra210-xusb-padctl.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra210-xusb-padctl.yaml
new file mode 100644
index 000000000000..d16bd6e47f90
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra210-xusb-padctl.yaml
@@ -0,0 +1,786 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/nvidia,tegra210-xusb-padctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra210 XUSB pad controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The Tegra XUSB pad controller manages a set of I/O lanes (with differential
+ signals) which connect directly to pins/pads on the SoC package. Each lane
+ is controlled by a HW block referred to as a "pad" in the Tegra hardware
+ documentation. Each such "pad" may control either one or multiple lanes,
+ and thus contains any logic common to all its lanes. Each lane can be
+ separately configured and powered up.
+
+ Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or
+ super-speed USB. Other lanes are for various types of low-speed, full-speed
+ or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller
+ contains a software-configurable mux that sits between the I/O controller
+ ports (e.g. PCIe) and the lanes.
+
+ In addition to per-lane configuration, USB 3.0 ports may require additional
+ settings on a per-board basis.
+
+ Pads will be represented as children of the top-level XUSB pad controller
+ device tree node. Each lane exposed by the pad will be represented by its
+ own subnode and can be referenced by users of the lane using the standard
+ PHY bindings, as described by the phy-bindings.txt file in this directory.
+
+ The Tegra hardware documentation refers to the connection between the XUSB
+ pad controller and the XUSB controller as "ports". This is confusing since
+ "port" is typically used to denote the physical USB receptacle. The device
+ tree binding in this document uses the term "port" to refer to the logical
+ abstraction of the signals that are routed to a USB receptacle (i.e. a PHY
+ for the USB signal, the VBUS power supply, the USB 2.0 companion port for
+ USB 3.0 receptacles, ...).
+
+properties:
+ compatible:
+ const: nvidia,tegra210-xusb-padctl
+
+ reg:
+ maxItems: 1
+
+ resets:
+ items:
+ - description: pad controller reset
+
+ interrupts:
+ items:
+ - description: XUSB pad controller interrupt
+
+ reset-names:
+ items:
+ - const: padctl
+
+ avdd-pll-utmip-supply:
+ description: UTMI PLL power supply. Must supply 1.8 V.
+
+ avdd-pll-uerefe-supply:
+ description: PLLE reference PLL power supply. Must supply 1.05 V.
+
+ dvdd-pex-pll-supply:
+ description: PCIe/USB3 PLL power supply. Must supply 1.05 V.
+
+ hvdd-pex-pll-e-supply:
+ description: High-voltage PLLE power supply. Must supply 1.8 V.
+
+ nvidia,pmc:
+ description: phandle to the Tegra Power Management Controller (PMC) node
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ pads:
+ description: A required child node named "pads" contains a list of
+ subnodes, one for each of the pads exposed by the XUSB pad controller.
+ Each pad may need additional resources that can be referenced in its
+ pad node.
+
+ The "status" property is used to enable or disable the use of a pad.
+ If set to "disabled", the pad will not be used on the given board. In
+ order to use the pad and any of its lanes, this property must be set
+ to "okay" or be absent.
+ type: object
+ additionalProperties: false
+ properties:
+ usb2:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: USB2 tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ usb2-3:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb, uart ]
+
+ hsic:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: HSIC tracking clock
+
+ clock-names:
+ items:
+ - const: trk
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ hsic-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb ]
+
+ hsic-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ snps, xusb ]
+
+ pcie:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: PCIe PLL clock source
+
+ clock-names:
+ items:
+ - const: pll
+
+ resets:
+ items:
+ - description: PCIe PHY reset
+
+ reset-names:
+ items:
+ - const: phy
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ pcie-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ pcie-1:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ pcie-2:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ pcie-3:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ pcie-4:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ pcie-5:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ pcie-6:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ pcie-x1, usb3-ss, pcie-x4 ]
+
+ sata:
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ items:
+ - description: SATA PLL clock source
+
+ clock-names:
+ items:
+ - const: pll
+
+ resets:
+ items:
+ - description: SATA PHY reset
+
+ reset-names:
+ items:
+ - const: phy
+
+ lanes:
+ type: object
+ additionalProperties: false
+ properties:
+ sata-0:
+ type: object
+ additionalProperties: false
+ properties:
+ "#phy-cells":
+ const: 0
+
+ nvidia,function:
+ description: Function selection for this lane.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ usb3-ss, sata ]
+
+ ports:
+ description: A required child node named "ports" contains a list of
+ subnodes, one for each of the ports exposed by the XUSB pad controller.
+ Each port may need additional resources that can be referenced in its
+ port node.
+
+ The "status" property is used to enable or disable the use of a port.
+ If set to "disabled", the port will not be used on the given board. In
+ order to use the port, this property must be set to "okay".
+ type: object
+ additionalProperties: false
+ properties:
+ usb2-0:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-1:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-2:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ usb2-3:
+ type: object
+ additionalProperties: false
+ properties:
+ # no need to further describe this because the connector will
+ # match on gpio-usb-b-connector or usb-b-connector and cause
+ # that binding to be selected for the subnode
+ connector:
+ type: object
+
+ mode:
+ description: A string that determines the mode in which to
+ run the port.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum: [ host, peripheral, otg ]
+
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ usb-role-switch:
+ description: |
+ A boolean property whole presence indicates that the port
+ supports OTG or peripheral mode. If present, the port
+ supports switching between USB host and peripheral roles.
+ A connector must be added as a subnode in that case.
+
+ See ../connector/usb-connector.yaml.
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ dependencies:
+ usb-role-switch: [ connector ]
+
+ hsic-0:
+ type: object
+ additionalProperties: false
+ properties:
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ hsic-1:
+ type: object
+ additionalProperties: false
+ properties:
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-0:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-1:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-2:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+ usb3-3:
+ type: object
+ additionalProperties: false
+ properties:
+ nvidia,internal:
+ description: A boolean property whose presence determines
+ that a port is internal. In the absence of this property
+ the port is considered to be external.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,usb2-companion:
+ description: A single cell that specifies the physical port
+ number to map this super-speed USB port to. The range of
+ valid port numbers varies with the SoC generation.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 0, 1, 2, 3 ]
+
+ vbus-supply:
+ description: A phandle to the regulator supplying the VBUS
+ voltage.
+
+additionalProperties: false
+
+required:
+ - avdd-pll-utmip-supply
+ - avdd-pll-uerefe-supply
+ - dvdd-pex-pll-supply
+ - hvdd-pex-pll-e-supply
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/gpio/tegra-gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ padctl@7009f000 {
+ compatible = "nvidia,tegra210-xusb-padctl";
+ reg = <0x7009f000 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&tegra_car 142>;
+ reset-names = "padctl";
+
+ avdd-pll-utmip-supply = <&vdd_1v8>;
+ avdd-pll-uerefe-supply = <&vdd_pex_1v05>;
+ dvdd-pex-pll-supply = <&vdd_pex_1v05>;
+ hvdd-pex-pll-e-supply = <&vdd_1v8>;
+
+ pads {
+ usb2 {
+ clocks = <&tegra_car TEGRA210_CLK_USB2_TRK>;
+ clock-names = "trk";
+
+ lanes {
+ usb2-0 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-1 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-2 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+
+ usb2-3 {
+ nvidia,function = "xusb";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ hsic {
+ clocks = <&tegra_car TEGRA210_CLK_HSIC_TRK>;
+ clock-names = "trk";
+ status = "disabled";
+
+ lanes {
+ hsic-0 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
+ hsic-1 {
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ pcie {
+ clocks = <&tegra_car TEGRA210_CLK_PLL_E>;
+ clock-names = "pll";
+ resets = <&tegra_car 205>;
+ reset-names = "phy";
+
+ lanes {
+ pcie-0 {
+ nvidia,function = "pcie-x1";
+ #phy-cells = <0>;
+ };
+
+ pcie-1 {
+ nvidia,function = "pcie-x4";
+ #phy-cells = <0>;
+ };
+
+ pcie-2 {
+ nvidia,function = "pcie-x4";
+ #phy-cells = <0>;
+ };
+
+ pcie-3 {
+ nvidia,function = "pcie-x4";
+ #phy-cells = <0>;
+ };
+
+ pcie-4 {
+ nvidia,function = "pcie-x4";
+ #phy-cells = <0>;
+ };
+
+ pcie-5 {
+ nvidia,function = "usb3-ss";
+ #phy-cells = <0>;
+ };
+
+ pcie-6 {
+ nvidia,function = "usb3-ss";
+ #phy-cells = <0>;
+ };
+ };
+ };
+
+ sata {
+ clocks = <&tegra_car TEGRA210_CLK_PLL_E>;
+ clock-names = "pll";
+ resets = <&tegra_car 204>;
+ reset-names = "phy";
+
+ lanes {
+ sata-0 {
+ nvidia,function = "sata";
+ #phy-cells = <0>;
+ };
+ };
+ };
+ };
+
+ ports {
+ usb2-0 {
+ mode = "peripheral";
+ usb-role-switch;
+
+ connector {
+ compatible = "gpio-usb-b-connector",
+ "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ vbus-gpios = <&gpio TEGRA_GPIO(CC, 4) GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ usb2-1 {
+ vbus-supply = <&vdd_5v0_rtl>;
+ mode = "host";
+ };
+
+ usb2-2 {
+ vbus-supply = <&vdd_usb_vbus>;
+ mode = "host";
+ };
+
+ usb2-3 {
+ mode = "host";
+ };
+
+ hsic-0 {
+ status = "disabled";
+ };
+
+ hsic-1 {
+ status = "disabled";
+ };
+
+ usb3-0 {
+ nvidia,usb2-companion = <1>;
+ };
+
+ usb3-1 {
+ nvidia,usb2-companion = <2>;
+ };
+
+ usb3-2 {
+ status = "disabled";
+ };
+
+ usb3-3 {
+ status = "disabled";
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-ufs-phy.yaml
index be41acbd3b6c..80a5348dbfde 100644
--- a/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-ufs-phy.yaml
@@ -75,6 +75,9 @@ patternProperties:
minItems: 3
maxItems: 6
+ "#clock-cells":
+ const: 1
+
"#phy-cells":
const: 0
diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-usb3-phy.yaml
index 0c6b3ba7346b..e81a38281f8c 100644
--- a/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-usb3-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,msm8996-qmp-usb3-phy.yaml
@@ -30,6 +30,7 @@ properties:
- qcom,sdm845-qmp-usb3-uni-phy
- qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy
+ - qcom,sm6115-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-uni-phy
- qcom,sm8250-qmp-usb3-phy
@@ -253,6 +254,7 @@ allOf:
contains:
enum:
- qcom,qcm2290-qmp-usb3-phy
+ - qcom,sm6115-qmp-usb3-phy
then:
properties:
clocks:
@@ -321,6 +323,7 @@ allOf:
- qcom,sc8180x-qmp-usb3-phy
- qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy
+ - qcom,sm6115-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-uni-phy
- qcom,sm8250-qmp-usb3-phy
then:
diff --git a/Documentation/devicetree/bindings/phy/qcom,pcie2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,pcie2-phy.yaml
new file mode 100644
index 000000000000..dbc4a4c71f05
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,pcie2-phy.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,pcie2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PCIe2 PHY controller
+
+maintainers:
+ - Vinod Koul <vkoul@kernel.org>
+
+description:
+ The Qualcomm PCIe2 PHY is a Synopsys based phy found in a number of Qualcomm
+ platforms.
+
+properties:
+ compatible:
+ items:
+ - const: qcom,qcs404-pcie2-phy
+ - const: qcom,pcie2-phy
+
+ reg:
+ items:
+ - description: PHY register set
+
+ clocks:
+ items:
+ - description: a clock-specifier pair for the "pipe" clock
+
+ clock-output-names:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 0
+
+ "#phy-cells":
+ const: 0
+
+ vdda-vp-supply:
+ description: low voltage regulator
+
+ vdda-vph-supply:
+ description: high voltage regulator
+
+ resets:
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: phy
+ - const: pipe
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-output-names
+ - "#clock-cells"
+ - "#phy-cells"
+ - vdda-vp-supply
+ - vdda-vph-supply
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,gcc-qcs404.h>
+ phy@7786000 {
+ compatible = "qcom,qcs404-pcie2-phy", "qcom,pcie2-phy";
+ reg = <0x07786000 0xb8>;
+
+ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
+ resets = <&gcc GCC_PCIEPHY_0_PHY_BCR>,
+ <&gcc GCC_PCIE_0_PIPE_ARES>;
+ reset-names = "phy", "pipe";
+
+ vdda-vp-supply = <&vreg_l3_1p05>;
+ vdda-vph-supply = <&vreg_l5_1p8>;
+
+ clock-output-names = "pcie_0_pipe_clk";
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
index 636ea430fbff..7f403e77f320 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
@@ -82,81 +82,74 @@ properties:
Phandle to TCSR syscon register region.
$ref: /schemas/types.yaml#/definitions/phandle
-if:
- properties:
- compatible:
- contains:
- const: qcom,qusb2-v2-phy
-then:
- properties:
- qcom,imp-res-offset-value:
- description:
- It is a 6 bit value that specifies offset to be
- added to PHY refgen RESCODE via IMP_CTRL1 register. It is a PHY
- tuning parameter that may vary for different boards of same SOC.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 63
- default: 0
-
- qcom,bias-ctrl-value:
- description:
- It is a 6 bit value that specifies bias-ctrl-value. It is a PHY
- tuning parameter that may vary for different boards of same SOC.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 63
- default: 32
-
- qcom,charge-ctrl-value:
- description:
- It is a 2 bit value that specifies charge-ctrl-value. It is a PHY
- tuning parameter that may vary for different boards of same SOC.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 3
- default: 0
-
- qcom,hstx-trim-value:
- description:
- It is a 4 bit value that specifies tuning for HSTX
- output current.
- Possible range is - 15mA to 24mA (stepsize of 600 uA).
- See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 15
- default: 3
-
- qcom,preemphasis-level:
- description:
- It is a 2 bit value that specifies pre-emphasis level.
- Possible range is 0 to 15% (stepsize of 5%).
- See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 3
- default: 2
-
- qcom,preemphasis-width:
- description:
- It is a 1 bit value that specifies how long the HSTX
- pre-emphasis (specified using qcom,preemphasis-level) must be in
- effect. Duration could be half-bit of full-bit.
- See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 1
- default: 0
-
- qcom,hsdisc-trim-value:
- description:
- It is a 2 bit value tuning parameter that control disconnect
- threshold and may vary for different boards of same SOC.
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
- maximum: 3
- default: 0
+ qcom,imp-res-offset-value:
+ description:
+ It is a 6 bit value that specifies offset to be
+ added to PHY refgen RESCODE via IMP_CTRL1 register. It is a PHY
+ tuning parameter that may vary for different boards of same SOC.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 63
+ default: 0
+
+ qcom,bias-ctrl-value:
+ description:
+ It is a 6 bit value that specifies bias-ctrl-value. It is a PHY
+ tuning parameter that may vary for different boards of same SOC.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 63
+ default: 32
+
+ qcom,charge-ctrl-value:
+ description:
+ It is a 2 bit value that specifies charge-ctrl-value. It is a PHY
+ tuning parameter that may vary for different boards of same SOC.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 3
+ default: 0
+
+ qcom,hstx-trim-value:
+ description:
+ It is a 4 bit value that specifies tuning for HSTX
+ output current.
+ Possible range is - 15mA to 24mA (stepsize of 600 uA).
+ See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 15
+ default: 3
+
+ qcom,preemphasis-level:
+ description:
+ It is a 2 bit value that specifies pre-emphasis level.
+ Possible range is 0 to 15% (stepsize of 5%).
+ See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 3
+ default: 2
+
+ qcom,preemphasis-width:
+ description:
+ It is a 1 bit value that specifies how long the HSTX
+ pre-emphasis (specified using qcom,preemphasis-level) must be in
+ effect. Duration could be half-bit of full-bit.
+ See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 1
+ default: 0
+
+ qcom,hsdisc-trim-value:
+ description:
+ It is a 2 bit value tuning parameter that control disconnect
+ threshold and may vary for different boards of same SOC.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 3
+ default: 0
required:
- compatible
@@ -169,6 +162,23 @@ required:
- vdda-phy-dpdm-supply
- resets
+allOf:
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: qcom,qusb2-v2-phy
+ then:
+ properties:
+ qcom,imp-res-offset-value: false
+ qcom,bias-ctrl-value: false
+ qcom,charge-ctrl-value: false
+ qcom,hstx-trim-value: false
+ qcom,preemphasis-level: false
+ qcom,preemphasis-width: false
+ qcom,hsdisc-trim-value: false
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
index d9d0ab90edb1..2e19a434c669 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
@@ -19,12 +19,17 @@ maintainers:
properties:
compatible:
- enum:
- - qcom,sc7180-qmp-usb3-dp-phy
- - qcom,sc7280-qmp-usb3-dp-phy
- - qcom,sc8180x-qmp-usb3-dp-phy
- - qcom,sdm845-qmp-usb3-dp-phy
- - qcom,sm8250-qmp-usb3-dp-phy
+ oneOf:
+ - 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
+ - items:
+ - enum:
+ - qcom,sc7280-qmp-usb3-dp-phy
+ - const: qcom,sm8250-qmp-usb3-dp-phy
+
reg:
items:
- description: Address and length of PHY's USB serdes block.
@@ -46,18 +51,12 @@ properties:
ranges: true
clocks:
- items:
- - description: Phy aux clock.
- - description: Phy config clock.
- - description: 19.2 MHz ref clk.
- - description: Phy common block aux clock.
+ minItems: 3
+ maxItems: 4
clock-names:
- items:
- - const: aux
- - const: cfg_ahb
- - const: ref
- - const: com_aux
+ minItems: 3
+ maxItems: 4
power-domains:
maxItems: 1
@@ -166,6 +165,64 @@ required:
- vdda-phy-supply
- vdda-pll-supply
+allOf:
+ - if:
+ properties:
+ compatible:
+ enum:
+ - qcom,sc7180-qmp-usb3-dp-phy
+ - qcom,sdm845-qmp-usb3-dp-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: Phy aux clock
+ - description: Phy config clock
+ - description: 19.2 MHz ref clk
+ - description: Phy common block aux clock
+ clock-names:
+ items:
+ - const: aux
+ - const: cfg_ahb
+ - const: ref
+ - const: com_aux
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - qcom,sc8180x-qmp-usb3-dp-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: Phy aux clock
+ - description: 19.2 MHz ref clk
+ - description: Phy common block aux clock
+ clock-names:
+ items:
+ - const: aux
+ - const: ref
+ - const: com_aux
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - qcom,sm8250-qmp-usb3-dp-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: Phy aux clock
+ - description: Board XO source
+ - description: Phy common block aux clock
+ clock-names:
+ items:
+ - const: aux
+ - const: ref_clk_src
+ - const: com_aux
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index 80aa8d2507fb..ef49efbd0a20 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -19,15 +19,20 @@ properties:
- qcom,sc8280xp-qmp-gen3x1-pcie-phy
- qcom,sc8280xp-qmp-gen3x2-pcie-phy
- qcom,sc8280xp-qmp-gen3x4-pcie-phy
+ - qcom,sm8350-qmp-gen3x1-pcie-phy
+ - qcom,sm8550-qmp-gen3x2-pcie-phy
+ - qcom,sm8550-qmp-gen4x2-pcie-phy
reg:
minItems: 1
maxItems: 2
clocks:
+ minItems: 5
maxItems: 6
clock-names:
+ minItems: 5
items:
- const: aux
- const: cfg_ahb
@@ -40,16 +45,21 @@ properties:
maxItems: 1
resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
reset-names:
+ minItems: 1
items:
- const: phy
+ - const: phy_nocsr
vdda-phy-supply: true
vdda-pll-supply: true
+ vdda-qref-supply: true
+
qcom,4ln-config-sel:
description: PCIe 4-lane configuration
$ref: /schemas/types.yaml#/definitions/phandle-array
@@ -104,6 +114,46 @@ allOf:
reg:
maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,sm8350-qmp-gen3x1-pcie-phy
+ - qcom,sm8550-qmp-gen3x2-pcie-phy
+ - qcom,sm8550-qmp-gen4x2-pcie-phy
+ then:
+ properties:
+ clocks:
+ maxItems: 5
+ clock-names:
+ maxItems: 5
+ else:
+ properties:
+ clocks:
+ minItems: 6
+ clock-names:
+ minItems: 6
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,sm8550-qmp-gen4x2-pcie-phy
+ then:
+ properties:
+ resets:
+ minItems: 2
+ reset-names:
+ minItems: 2
+ else:
+ properties:
+ resets:
+ maxItems: 1
+ reset-names:
+ maxItems: 1
+
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
index dde86a19f792..64ed331880f6 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -17,6 +17,8 @@ properties:
compatible:
enum:
- qcom,sc8280xp-qmp-ufs-phy
+ - qcom,sm6125-qmp-ufs-phy
+ - qcom,sm8550-qmp-ufs-phy
reg:
maxItems: 1
@@ -43,6 +45,9 @@ properties:
vdda-pll-supply: true
+ "#clock-cells":
+ const: 1
+
"#phy-cells":
const: 0
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
index 6f31693d9868..3cd5fc3e8fab 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
@@ -17,6 +17,10 @@ properties:
compatible:
enum:
- qcom,sc8280xp-qmp-usb43dp-phy
+ - qcom,sm6350-qmp-usb3-dp-phy
+ - qcom,sm8350-qmp-usb3-dp-phy
+ - qcom,sm8450-qmp-usb3-dp-phy
+ - qcom,sm8550-qmp-usb3-dp-phy
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml
new file mode 100644
index 000000000000..c53bab107b6d
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,snps-eusb2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SNPS eUSB2 phy controller
+
+maintainers:
+ - Abel Vesa <abel.vesa@linaro.org>
+
+description:
+ eUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets.
+
+properties:
+ compatible:
+ const: qcom,sm8550-snps-eusb2-phy
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ clocks:
+ items:
+ - description: ref
+
+ clock-names:
+ items:
+ - const: ref
+
+ resets:
+ maxItems: 1
+
+ phys:
+ maxItems: 1
+ description:
+ Phandle to eUSB2 to USB 2.0 repeater
+
+ vdd-supply:
+ description:
+ Phandle to 0.88V regulator supply to PHY digital circuit.
+
+ vdda12-supply:
+ description:
+ Phandle to 1.2V regulator supply to PHY refclk pll block.
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+ - clocks
+ - clock-names
+ - vdd-supply
+ - vdda12-supply
+ - resets
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,sm8550-gcc.h>
+ #include <dt-bindings/clock/qcom,rpmh.h>
+ #include <dt-bindings/clock/qcom,sm8550-tcsr.h>
+
+ usb_1_hsphy: phy@88e3000 {
+ compatible = "qcom,sm8550-snps-eusb2-phy";
+ reg = <0x88e3000 0x154>;
+ #phy-cells = <0>;
+
+ clocks = <&tcsrcc TCSR_USB2_CLKREF_EN>;
+ clock-names = "ref";
+
+ vdd-supply = <&vreg_l1e_0p88>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml
new file mode 100644
index 000000000000..083fda530b48
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,snps-eusb2-repeater.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Synopsis eUSB2 to USB 2.0 repeater
+
+maintainers:
+ - Abel Vesa <abel.vesa@linaro.org>
+
+description:
+ eUSB2 repeater converts between eUSB2 and USB 2.0 signaling levels and
+ allows a eUSB2 PHY to connect to legacy USB 2.0 products
+
+properties:
+ compatible:
+ const: qcom,pm8550b-eusb2-repeater
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ vdd18-supply: true
+
+ vdd3-supply: true
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/spmi/spmi.h>
+
+ pmic@7 {
+ reg = <0x7 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8550b_eusb2_repeater: phy@fd00 {
+ compatible = "qcom,pm8550b-eusb2-repeater";
+ reg = <0xfd00>;
+ #phy-cells = <0>;
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
deleted file mode 100644
index 3c7cb2be4b12..000000000000
--- a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-Qualcomm's USB HSIC PHY
-
-PROPERTIES
-
-- compatible:
- Usage: required
- Value type: <string>
- Definition: Should contain "qcom,usb-hsic-phy" and more specifically one of the
- following:
-
- "qcom,usb-hsic-phy-mdm9615"
- "qcom,usb-hsic-phy-msm8974"
-
-- #phy-cells:
- Usage: required
- Value type: <u32>
- Definition: Should contain 0
-
-- clocks:
- Usage: required
- Value type: <prop-encoded-array>
- Definition: Should contain clock specifier for phy, calibration and
- a calibration sleep clock
-
-- clock-names:
- Usage: required
- Value type: <stringlist>
- Definition: Should contain "phy, "cal" and "cal_sleep"
-
-- pinctrl-names:
- Usage: required
- Value type: <stringlist>
- Definition: Should contain "init" and "default" in that order
-
-- pinctrl-0:
- Usage: required
- Value type: <prop-encoded-array>
- Definition: List of pinctrl settings to apply to keep HSIC pins in a glitch
- free state
-
-- pinctrl-1:
- Usage: required
- Value type: <prop-encoded-array>
- Definition: List of pinctrl settings to apply to mux out the HSIC pins
-
-EXAMPLE
-
-usb-controller {
- ulpi {
- phy {
- compatible = "qcom,usb-hsic-phy-msm8974",
- "qcom,usb-hsic-phy";
- #phy-cells = <0>;
- pinctrl-names = "init", "default";
- pinctrl-0 = <&hsic_sleep>;
- pinctrl-1 = <&hsic_default>;
- clocks = <&gcc GCC_USB_HSIC_CLK>,
- <&gcc GCC_USB_HSIC_IO_CAL_CLK>,
- <&gcc GCC_USB_HSIC_IO_CAL_SLEEP_CLK>;
- clock-names = "phy", "cal", "cal_sleep";
- assigned-clocks = <&gcc GCC_USB_HSIC_IO_CAL_CLK>;
- assigned-clock-rates = <960000>;
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.yaml
new file mode 100644
index 000000000000..077e13a94448
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,usb-hsic-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm USB HSIC PHY Controller
+
+maintainers:
+ - Bjorn Andersson <andersson@kernel.org>
+ - Vinod Koul <vkoul@kernel.org>
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - qcom,usb-hsic-phy-mdm9615
+ - qcom,usb-hsic-phy-msm8974
+ - const: qcom,usb-hsic-phy
+
+ clocks:
+ maxItems: 3
+
+ clock-names:
+ items:
+ - const: phy
+ - const: cal
+ - const: cal_sleep
+
+ "#phy-cells":
+ const: 0
+
+ pinctrl-0: true
+ pinctrl-1: true
+
+ pinctrl-names:
+ items:
+ - const: init
+ - const: default
+
+required:
+ - compatible
+ - clocks
+ - clock-names
+ - "#phy-cells"
+ - pinctrl-0
+ - pinctrl-1
+ - pinctrl-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,gcc-msm8974.h>
+
+ phy {
+ compatible = "qcom,usb-hsic-phy-msm8974",
+ "qcom,usb-hsic-phy";
+ clocks = <&gcc GCC_USB_HSIC_CLK>,
+ <&gcc GCC_USB_HSIC_IO_CAL_CLK>,
+ <&gcc GCC_USB_HSIC_IO_CAL_SLEEP_CLK>;
+ clock-names = "phy", "cal", "cal_sleep";
+ #phy-cells = <0>;
+ pinctrl-names = "init", "default";
+ pinctrl-0 = <&hsic_sleep>;
+ pinctrl-1 = <&hsic_default>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
index 68e70961beb2..85d405e028b9 100644
--- a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
@@ -14,18 +14,25 @@ description: |
properties:
compatible:
- enum:
- - qcom,usb-snps-hs-5nm-phy
- - qcom,usb-snps-hs-7nm-phy
- - qcom,sc7280-usb-hs-phy
- - qcom,sc8180x-usb-hs-phy
- - qcom,sc8280xp-usb-hs-phy
- - qcom,sm6375-usb-hs-phy
- - qcom,sm8150-usb-hs-phy
- - qcom,sm8250-usb-hs-phy
- - qcom,sm8350-usb-hs-phy
- - qcom,sm8450-usb-hs-phy
- - qcom,usb-snps-femto-v2-phy
+ oneOf:
+ - enum:
+ - qcom,sc8180x-usb-hs-phy
+ - qcom,usb-snps-femto-v2-phy
+ - items:
+ - enum:
+ - qcom,sc8280xp-usb-hs-phy
+ - const: qcom,usb-snps-hs-5nm-phy
+ - items:
+ - enum:
+ - qcom,sc7280-usb-hs-phy
+ - qcom,sdx55-usb-hs-phy
+ - qcom,sdx65-usb-hs-phy
+ - qcom,sm6375-usb-hs-phy
+ - qcom,sm8150-usb-hs-phy
+ - qcom,sm8250-usb-hs-phy
+ - qcom,sm8350-usb-hs-phy
+ - qcom,sm8450-usb-hs-phy
+ - const: qcom,usb-snps-hs-7nm-phy
reg:
maxItems: 1
@@ -160,7 +167,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,gcc-sm8150.h>
phy@88e2000 {
- compatible = "qcom,sm8150-usb-hs-phy";
+ compatible = "qcom,sm8150-usb-hs-phy", "qcom,usb-snps-hs-7nm-phy";
reg = <0x088e2000 0x400>;
#phy-cells = <0>;
diff --git a/Documentation/devicetree/bindings/phy/qcom-pcie2-phy.txt b/Documentation/devicetree/bindings/phy/qcom-pcie2-phy.txt
deleted file mode 100644
index 30064253f290..000000000000
--- a/Documentation/devicetree/bindings/phy/qcom-pcie2-phy.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-Qualcomm PCIe2 PHY controller
-=============================
-
-The Qualcomm PCIe2 PHY is a Synopsys based phy found in a number of Qualcomm
-platforms.
-
-Required properties:
- - compatible: compatible list, should be:
- "qcom,qcs404-pcie2-phy", "qcom,pcie2-phy"
-
- - reg: offset and length of the PHY register set.
- - #phy-cells: must be 0.
-
- - clocks: a clock-specifier pair for the "pipe" clock
-
- - vdda-vp-supply: phandle to low voltage regulator
- - vdda-vph-supply: phandle to high voltage regulator
-
- - resets: reset-specifier pairs for the "phy" and "pipe" resets
- - reset-names: list of resets, should contain:
- "phy" and "pipe"
-
- - clock-output-names: name of the outgoing clock signal from the PHY PLL
- - #clock-cells: must be 0
-
-Example:
- phy@7786000 {
- compatible = "qcom,qcs404-pcie2-phy", "qcom,pcie2-phy";
- reg = <0x07786000 0xb8>;
-
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- resets = <&gcc GCC_PCIEPHY_0_PHY_BCR>,
- <&gcc GCC_PCIE_0_PIPE_ARES>;
- reset-names = "phy", "pipe";
-
- vdda-vp-supply = <&vreg_l3_1p05>;
- vdda-vph-supply = <&vreg_l5_1p8>;
-
- clock-output-names = "pcie_0_pipe_clk";
- #clock-cells = <0>;
- #phy-cells = <0>;
- };
diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 02b76f15e717..237295b2b5a8 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -15,6 +15,7 @@ properties:
compatible:
enum:
+ - nxp,tjr1443
- ti,tcan1042
- ti,tcan1043
diff --git a/Documentation/driver-api/phy/phy.rst b/Documentation/driver-api/phy/phy.rst
index 8e8b3e8f9523..81785c084f3e 100644
--- a/Documentation/driver-api/phy/phy.rst
+++ b/Documentation/driver-api/phy/phy.rst
@@ -103,27 +103,31 @@ it. This framework provides the following APIs to get a reference to the PHY.
::
struct phy *phy_get(struct device *dev, const char *string);
- struct phy *phy_optional_get(struct device *dev, const char *string);
struct phy *devm_phy_get(struct device *dev, const char *string);
struct phy *devm_phy_optional_get(struct device *dev,
const char *string);
+ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
+ const char *con_id);
+ struct phy *devm_of_phy_optional_get(struct device *dev,
+ struct device_node *np,
+ const char *con_id);
struct phy *devm_of_phy_get_by_index(struct device *dev,
struct device_node *np,
int index);
-phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can
-be used to get the PHY. In the case of dt boot, the string arguments
+phy_get, devm_phy_get and devm_phy_optional_get can be used to get the PHY.
+In the case of dt boot, the string arguments
should contain the phy name as given in the dt data and in the case of
non-dt boot, it should contain the label of the PHY. The two
devm_phy_get associates the device with the PHY using devres on
successful PHY get. On driver detach, release function is invoked on
-the devres data and devres data is freed. phy_optional_get and
-devm_phy_optional_get should be used when the phy is optional. These
-two functions will never return -ENODEV, but instead returns NULL when
-the phy cannot be found.Some generic drivers, such as ehci, may use multiple
-phys and for such drivers referencing phy(s) by name(s) does not make sense. In
-this case, devm_of_phy_get_by_index can be used to get a phy reference based on
-the index.
+the devres data and devres data is freed.
+The _optional_get variants should be used when the phy is optional. These
+functions will never return -ENODEV, but instead return NULL when
+the phy cannot be found.
+Some generic drivers, such as ehci, may use multiple phys. In this case,
+devm_of_phy_get or devm_of_phy_get_by_index can be used to get a phy
+reference based on name or index.
It should be noted that NULL is a valid phy reference. All phy
consumer calls on the NULL phy become NOPs. That is the release calls,
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index 587ad81a2dc3..625c79d5636f 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -1155,13 +1155,12 @@ int memac_initialization(struct mac_device *mac_dev,
else
memac->sgmii_pcs = pcs;
- memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
- err = PTR_ERR(memac->serdes);
- if (err == -ENODEV || err == -ENOSYS) {
+ memac->serdes = devm_of_phy_optional_get(mac_dev->dev, mac_node,
+ "serdes");
+ if (!memac->serdes) {
dev_dbg(mac_dev->dev, "could not get (optional) serdes\n");
- memac->serdes = NULL;
} else if (IS_ERR(memac->serdes)) {
- dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
+ err = PTR_ERR(memac->serdes);
goto _return_fm_mac_free;
}
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 8b89de0541ff..685e8cd7658c 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -1154,9 +1154,8 @@ static int lan966x_probe(struct platform_device *pdev)
lan966x->ports[p]->config.portmode = phy_mode;
lan966x->ports[p]->fwnode = fwnode_handle_get(portnp);
- serdes = devm_of_phy_get(lan966x->dev, to_of_node(portnp), NULL);
- if (PTR_ERR(serdes) == -ENODEV)
- serdes = NULL;
+ serdes = devm_of_phy_optional_get(lan966x->dev,
+ to_of_node(portnp), NULL);
if (IS_ERR(serdes)) {
err = PTR_ERR(serdes);
goto cleanup_ports;
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 5bb05564d6f8..74c109f14ff0 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -1330,12 +1330,9 @@ static struct phy *devm_of_phy_optional_get_index(struct device *dev,
if (!name)
return ERR_PTR(-ENOMEM);
- phy = devm_of_phy_get(dev, np, name);
+ phy = devm_of_phy_optional_get(dev, np, name);
kfree(name);
- if (PTR_ERR(phy) == -ENODEV)
- phy = NULL;
-
return phy;
}
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 5472db9e87ef..fbcd7014ab43 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -99,28 +99,17 @@
#define DEBOUNCE_TIME msecs_to_jiffies(50)
#define POLL_TIME msecs_to_jiffies(250)
-enum sun4i_usb_phy_type {
- sun4i_a10_phy,
- sun6i_a31_phy,
- sun8i_a33_phy,
- sun8i_a83t_phy,
- sun8i_h3_phy,
- sun8i_r40_phy,
- sun8i_v3s_phy,
- sun50i_a64_phy,
- sun50i_h6_phy,
-};
-
struct sun4i_usb_phy_cfg {
int num_phys;
int hsic_index;
- enum sun4i_usb_phy_type type;
u32 disc_thresh;
u32 hci_phy_ctl_clear;
u8 phyctl_offset;
bool dedicated_clocks;
bool phy0_dual_route;
bool needs_phy2_siddq;
+ bool siddq_in_base;
+ bool poll_vbusen;
int missing_phys;
};
@@ -252,7 +241,8 @@ static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
/* A83T USB2 is HSIC */
- if (phy_data->cfg->type == sun8i_a83t_phy && phy->index == 2)
+ if (phy_data->cfg->hsic_index &&
+ phy->index == phy_data->cfg->hsic_index)
bits |= SUNXI_EHCI_HS_FORCE | SUNXI_HSIC_CONNECT_INT |
SUNXI_HSIC;
@@ -340,8 +330,7 @@ static int sun4i_usb_phy_init(struct phy *_phy)
writel(val, phy->pmu + REG_HCI_PHY_CTL);
}
- if (data->cfg->type == sun8i_a83t_phy ||
- data->cfg->type == sun50i_h6_phy) {
+ if (data->cfg->siddq_in_base) {
if (phy->index == 0) {
val = readl(data->base + data->cfg->phyctl_offset);
val |= PHY_CTL_VBUSVLDEXT;
@@ -385,8 +374,7 @@ static int sun4i_usb_phy_exit(struct phy *_phy)
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
if (phy->index == 0) {
- if (data->cfg->type == sun8i_a83t_phy ||
- data->cfg->type == sun50i_h6_phy) {
+ if (data->cfg->siddq_in_base) {
void __iomem *phyctl = data->base +
data->cfg->phyctl_offset;
@@ -466,9 +454,8 @@ static bool sun4i_usb_phy0_poll(struct sun4i_usb_phy_data *data)
* vbus using the N_VBUSEN pin on the pmic, so we must poll
* when using the pmic for vbus-det _and_ we're driving vbus.
*/
- if ((data->cfg->type == sun6i_a31_phy ||
- data->cfg->type == sun8i_a33_phy) &&
- data->vbus_power_supply && data->phys[0].regulator_on)
+ if (data->cfg->poll_vbusen && data->vbus_power_supply &&
+ data->phys[0].regulator_on)
return true;
return false;
@@ -918,9 +905,15 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return 0;
}
+static const struct sun4i_usb_phy_cfg suniv_f1c100s_cfg = {
+ .num_phys = 1,
+ .disc_thresh = 3,
+ .phyctl_offset = REG_PHYCTL_A10,
+ .dedicated_clocks = true,
+};
+
static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
.num_phys = 3,
- .type = sun4i_a10_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = false,
@@ -928,7 +921,6 @@ static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
.num_phys = 2,
- .type = sun4i_a10_phy,
.disc_thresh = 2,
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = false,
@@ -936,15 +928,14 @@ static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
.num_phys = 3,
- .type = sun6i_a31_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = true,
+ .poll_vbusen = true,
};
static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
.num_phys = 3,
- .type = sun4i_a10_phy,
.disc_thresh = 2,
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = false,
@@ -952,31 +943,30 @@ static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
.num_phys = 2,
- .type = sun6i_a31_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = true,
+ .poll_vbusen = true,
};
static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
.num_phys = 2,
- .type = sun8i_a33_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
+ .poll_vbusen = true,
};
static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
.num_phys = 3,
.hsic_index = 2,
- .type = sun8i_a83t_phy,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
+ .siddq_in_base = true,
};
static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
.num_phys = 4,
- .type = sun8i_h3_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
@@ -986,7 +976,6 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
.num_phys = 3,
- .type = sun8i_r40_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
@@ -996,7 +985,6 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
.num_phys = 1,
- .type = sun8i_v3s_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
@@ -1006,16 +994,15 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = {
.num_phys = 2,
- .type = sun50i_h6_phy,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
.phy0_dual_route = true,
+ .siddq_in_base = true,
};
static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
.num_phys = 2,
- .type = sun50i_a64_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
@@ -1025,22 +1012,22 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
.num_phys = 4,
- .type = sun50i_h6_phy,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.phy0_dual_route = true,
.missing_phys = BIT(1) | BIT(2),
+ .siddq_in_base = true,
};
static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = {
.num_phys = 4,
- .type = sun50i_h6_phy,
.disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.phy0_dual_route = true,
.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
.needs_phy2_siddq = true,
+ .siddq_in_base = true,
};
static const struct of_device_id sun4i_usb_phy_of_match[] = {
@@ -1059,6 +1046,8 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = {
.data = &sun50i_a64_cfg},
{ .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg },
{ .compatible = "allwinner,sun50i-h616-usb-phy", .data = &sun50i_h616_cfg },
+ { .compatible = "allwinner,suniv-f1c100s-usb-phy",
+ .data = &suniv_f1c100s_cfg },
{ },
};
MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);
diff --git a/drivers/phy/mediatek/phy-mtk-io.h b/drivers/phy/mediatek/phy-mtk-io.h
index d20ad5e5be81..58f06db822cb 100644
--- a/drivers/phy/mediatek/phy-mtk-io.h
+++ b/drivers/phy/mediatek/phy-mtk-io.h
@@ -39,8 +39,8 @@ static inline void mtk_phy_update_bits(void __iomem *reg, u32 mask, u32 val)
/* field @mask shall be constant and continuous */
#define mtk_phy_update_field(reg, mask, val) \
({ \
- typeof(mask) mask_ = (mask); \
- mtk_phy_update_bits(reg, mask_, FIELD_PREP(mask_, val)); \
+ BUILD_BUG_ON_MSG(!__builtin_constant_p(mask), "mask is not constant"); \
+ mtk_phy_update_bits(reg, mask, FIELD_PREP(mask, val)); \
})
#endif
diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index ce511ad5d369..5487b9dd1ead 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -84,6 +84,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
.compatible = "ti,tcan1043",
.data = &tcan1043_drvdata
},
+ {
+ .compatible = "nxp,tjr1443",
+ .data = &tcan1043_drvdata
+ },
{ }
};
MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index d93ddf1262c5..9951efc03eaa 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -767,27 +767,6 @@ struct phy *phy_get(struct device *dev, const char *string)
EXPORT_SYMBOL_GPL(phy_get);
/**
- * phy_optional_get() - lookup and obtain a reference to an optional phy.
- * @dev: device that requests this phy
- * @string: the phy name as given in the dt data or the name of the controller
- * port for non-dt case
- *
- * Returns the phy driver, after getting a refcount to it; or
- * NULL if there is no such phy. The caller is responsible for
- * calling phy_put() to release that count.
- */
-struct phy *phy_optional_get(struct device *dev, const char *string)
-{
- struct phy *phy = phy_get(dev, string);
-
- if (PTR_ERR(phy) == -ENODEV)
- phy = NULL;
-
- return phy;
-}
-EXPORT_SYMBOL_GPL(phy_optional_get);
-
-/**
* devm_phy_get() - lookup and obtain a reference to a phy.
* @dev: device that requests this phy
* @string: the phy name as given in the dt data or phy device name
@@ -880,6 +859,36 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
EXPORT_SYMBOL_GPL(devm_of_phy_get);
/**
+ * devm_of_phy_optional_get() - lookup and obtain a reference to an optional
+ * phy.
+ * @dev: device that requests this phy
+ * @np: node containing the phy
+ * @con_id: name of the phy from device's point of view
+ *
+ * Gets the phy using of_phy_get(), and associates a device with it using
+ * devres. On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed. This differs to devm_of_phy_get() in
+ * that if the phy does not exist, it is not considered an error and
+ * -ENODEV will not be returned. Instead the NULL phy is returned,
+ * which can be passed to all other phy consumer calls.
+ */
+struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
+ const char *con_id)
+{
+ struct phy *phy = devm_of_phy_get(dev, np, con_id);
+
+ if (PTR_ERR(phy) == -ENODEV)
+ phy = NULL;
+
+ if (IS_ERR(phy))
+ dev_err_probe(dev, PTR_ERR(phy), "failed to get PHY %pOF:%s",
+ np, con_id);
+
+ return phy;
+}
+EXPORT_SYMBOL_GPL(devm_of_phy_optional_get);
+
+/**
* devm_of_phy_get_by_index() - lookup and obtain a reference to a phy by index.
* @dev: device that requests this phy
* @np: node containing the phy
diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index eb9ddc685b38..4850d48f31fa 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -50,14 +50,56 @@ config PHY_QCOM_PCIE2
Enable this to support the Qualcomm PCIe PHY, used with the Synopsys
based PCIe controller.
-config PHY_QCOM_QMP
- tristate "Qualcomm QMP PHY Driver"
+menuconfig PHY_QCOM_QMP
+ tristate "Qualcomm QMP PHY Drivers"
depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
+
+if PHY_QCOM_QMP
+
+config PHY_QCOM_QMP_COMBO
+ tristate "Qualcomm QMP Combo PHY Driver"
+ default PHY_QCOM_QMP
select GENERIC_PHY
select MFD_SYSCON
help
- Enable this to support the QMP PHY transceiver that is used
- with controllers such as PCIe, UFS, and USB on Qualcomm chips.
+ Enable this to support the QMP Combo PHY transceiver that is used
+ with USB3 and DisplayPort controllers on Qualcomm chips.
+
+config PHY_QCOM_QMP_PCIE
+ tristate "Qualcomm QMP PCIe PHY Driver"
+ depends on PCI || COMPILE_TEST
+ select GENERIC_PHY
+ default PHY_QCOM_QMP
+ help
+ Enable this to support the QMP PCIe PHY transceiver that is used
+ with PCIe controllers on Qualcomm chips.
+
+config PHY_QCOM_QMP_PCIE_8996
+ tristate "Qualcomm QMP PCIe 8996 PHY Driver"
+ depends on PCI || COMPILE_TEST
+ select GENERIC_PHY
+ default PHY_QCOM_QMP
+ help
+ Enable this to support the QMP PCIe PHY transceiver that is used
+ with PCIe controllers on Qualcomm msm8996 chips.
+
+config PHY_QCOM_QMP_UFS
+ tristate "Qualcomm QMP UFS PHY Driver"
+ select GENERIC_PHY
+ default PHY_QCOM_QMP
+ help
+ Enable this to support the QMP UFS PHY transceiver that is used
+ with UFS controllers on Qualcomm chips.
+
+config PHY_QCOM_QMP_USB
+ tristate "Qualcomm QMP USB PHY Driver"
+ select GENERIC_PHY
+ default PHY_QCOM_QMP
+ help
+ Enable this to support the QMP USB PHY transceiver that is used
+ with USB3 controllers on Qualcomm chips.
+
+endif # PHY_QCOM_QMP
config PHY_QCOM_QUSB2
tristate "Qualcomm QUSB2 PHY Driver"
@@ -70,6 +112,24 @@ config PHY_QCOM_QUSB2
PHY which is usually paired with either the ChipIdea or Synopsys DWC3
USB IPs on MSM SOCs.
+config PHY_QCOM_SNPS_EUSB2
+ tristate "Qualcomm SNPS eUSB2 PHY Driver"
+ depends on OF && (ARCH_QCOM || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ Enable support for the USB high-speed SNPS eUSB2 phy on Qualcomm
+ chipsets. The PHY is paired with a Synopsys DWC3 USB controller
+ on Qualcomm SOCs.
+
+config PHY_QCOM_EUSB2_REPEATER
+ tristate "Qualcomm SNPS eUSB2 Repeater Driver"
+ depends on OF && (ARCH_QCOM || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ Enable support for the USB high-speed SNPS eUSB2 repeater on Qualcomm
+ PMICs. The repeater is paired with a Synopsys eUSB2 Phy
+ on Qualcomm SOCs.
+
config PHY_QCOM_USB_HS
tristate "Qualcomm USB HS PHY module"
depends on USB_ULPI_BUS
diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile
index 65f6c30a3e93..de3dc9ccf067 100644
--- a/drivers/phy/qualcomm/Makefile
+++ b/drivers/phy/qualcomm/Makefile
@@ -5,14 +5,16 @@ obj-$(CONFIG_PHY_QCOM_EDP) += phy-qcom-edp.o
obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o
-obj-$(CONFIG_PHY_QCOM_QMP) += \
- phy-qcom-qmp-combo.o \
- phy-qcom-qmp-pcie.o \
- phy-qcom-qmp-pcie-msm8996.o \
- phy-qcom-qmp-ufs.o \
- phy-qcom-qmp-usb.o
+
+obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o
+obj-$(CONFIG_PHY_QCOM_QMP_PCIE) += phy-qcom-qmp-pcie.o
+obj-$(CONFIG_PHY_QCOM_QMP_PCIE_8996) += phy-qcom-qmp-pcie-msm8996.o
+obj-$(CONFIG_PHY_QCOM_QMP_UFS) += phy-qcom-qmp-ufs.o
+obj-$(CONFIG_PHY_QCOM_QMP_USB) += phy-qcom-qmp-usb.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
+obj-$(CONFIG_PHY_QCOM_SNPS_EUSB2) += phy-qcom-snps-eusb2.o
+obj-$(CONFIG_PHY_QCOM_EUSB2_REPEATER) += phy-qcom-eusb2-repeater.o
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
new file mode 100644
index 000000000000..3f265ac2df20
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+
+/* eUSB2 status registers */
+#define EUSB2_RPTR_STATUS 0x08
+#define RPTR_OK BIT(7)
+
+/* eUSB2 control registers */
+#define EUSB2_EN_CTL1 0x46
+#define EUSB2_RPTR_EN BIT(7)
+
+#define EUSB2_FORCE_EN_5 0xe8
+#define F_CLK_19P2M_EN BIT(6)
+
+#define EUSB2_FORCE_VAL_5 0xeD
+#define V_CLK_19P2M_EN BIT(6)
+
+#define EUSB2_TUNE_IUSB2 0x51
+#define EUSB2_TUNE_SQUELCH_U 0x54
+#define EUSB2_TUNE_USB2_PREEM 0x57
+
+#define QCOM_EUSB2_REPEATER_INIT_CFG(o, v) \
+ { \
+ .offset = o, \
+ .val = v, \
+ }
+
+struct eusb2_repeater_init_tbl {
+ unsigned int offset;
+ unsigned int val;
+};
+
+struct eusb2_repeater_cfg {
+ const struct eusb2_repeater_init_tbl *init_tbl;
+ int init_tbl_num;
+ const char * const *vreg_list;
+ int num_vregs;
+};
+
+struct eusb2_repeater {
+ struct device *dev;
+ struct regmap *regmap;
+ struct phy *phy;
+ struct regulator_bulk_data *vregs;
+ const struct eusb2_repeater_cfg *cfg;
+ u16 base;
+ enum phy_mode mode;
+};
+
+static const char * const pm8550b_vreg_l[] = {
+ "vdd18", "vdd3",
+};
+
+static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = {
+ QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_IUSB2, 0x8),
+ QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_SQUELCH_U, 0x3),
+ QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_USB2_PREEM, 0x5),
+};
+
+static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = {
+ .init_tbl = pm8550b_init_tbl,
+ .init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl),
+ .vreg_list = pm8550b_vreg_l,
+ .num_vregs = ARRAY_SIZE(pm8550b_vreg_l),
+};
+
+static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
+{
+ int num = rptr->cfg->num_vregs;
+ struct device *dev = rptr->dev;
+ int i;
+
+ rptr->vregs = devm_kcalloc(dev, num, sizeof(*rptr->vregs), GFP_KERNEL);
+ if (!rptr->vregs)
+ return -ENOMEM;
+
+ for (i = 0; i < num; i++)
+ rptr->vregs[i].supply = rptr->cfg->vreg_list[i];
+
+ return devm_regulator_bulk_get(dev, num, rptr->vregs);
+}
+
+static int eusb2_repeater_init(struct phy *phy)
+{
+ struct eusb2_repeater *rptr = phy_get_drvdata(phy);
+ const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl;
+ int num = rptr->cfg->init_tbl_num;
+ u32 val;
+ int ret;
+ int i;
+
+ ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs);
+ if (ret)
+ return ret;
+
+ regmap_update_bits(rptr->regmap, rptr->base + EUSB2_EN_CTL1,
+ EUSB2_RPTR_EN, EUSB2_RPTR_EN);
+
+ for (i = 0; i < num; i++)
+ regmap_update_bits(rptr->regmap,
+ rptr->base + init_tbl[i].offset,
+ init_tbl[i].val, init_tbl[i].val);
+
+ ret = regmap_read_poll_timeout(rptr->regmap,
+ rptr->base + EUSB2_RPTR_STATUS, val,
+ val & RPTR_OK, 10, 5);
+ if (ret)
+ dev_err(rptr->dev, "initialization timed-out\n");
+
+ return ret;
+}
+
+static int eusb2_repeater_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
+{
+ struct eusb2_repeater *rptr = phy_get_drvdata(phy);
+
+ switch (mode) {
+ case PHY_MODE_USB_HOST:
+ /*
+ * CM.Lx is prohibited when repeater is already into Lx state as
+ * per eUSB 1.2 Spec. Below implement software workaround until
+ * PHY and controller is fixing seen observation.
+ */
+ regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5,
+ F_CLK_19P2M_EN, F_CLK_19P2M_EN);
+ regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5,
+ V_CLK_19P2M_EN, V_CLK_19P2M_EN);
+ break;
+ case PHY_MODE_USB_DEVICE:
+ /*
+ * In device mode clear host mode related workaround as there
+ * is no repeater reset available, and enable/disable of
+ * repeater doesn't clear previous value due to shared
+ * regulators (say host <-> device mode switch).
+ */
+ regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5,
+ F_CLK_19P2M_EN, 0);
+ regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5,
+ V_CLK_19P2M_EN, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int eusb2_repeater_exit(struct phy *phy)
+{
+ struct eusb2_repeater *rptr = phy_get_drvdata(phy);
+
+ return regulator_bulk_disable(rptr->cfg->num_vregs, rptr->vregs);
+}
+
+static const struct phy_ops eusb2_repeater_ops = {
+ .init = eusb2_repeater_init,
+ .exit = eusb2_repeater_exit,
+ .set_mode = eusb2_repeater_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static int eusb2_repeater_probe(struct platform_device *pdev)
+{
+ struct eusb2_repeater *rptr;
+ struct device *dev = &pdev->dev;
+ struct phy_provider *phy_provider;
+ struct device_node *np = dev->of_node;
+ u32 res;
+ int ret;
+
+ rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL);
+ if (!rptr)
+ return -ENOMEM;
+
+ rptr->dev = dev;
+ dev_set_drvdata(dev, rptr);
+
+ rptr->cfg = of_device_get_match_data(dev);
+ if (!rptr->cfg)
+ return -EINVAL;
+
+ rptr->regmap = dev_get_regmap(dev->parent, NULL);
+ if (!rptr->regmap)
+ return -ENODEV;
+
+ ret = of_property_read_u32(np, "reg", &res);
+ if (ret < 0)
+ return ret;
+
+ rptr->base = res;
+
+ ret = eusb2_repeater_init_vregs(rptr);
+ if (ret < 0) {
+ dev_err(dev, "unable to get supplies\n");
+ return ret;
+ }
+
+ rptr->phy = devm_phy_create(dev, np, &eusb2_repeater_ops);
+ if (IS_ERR(rptr->phy)) {
+ dev_err(dev, "failed to create PHY: %d\n", ret);
+ return PTR_ERR(rptr->phy);
+ }
+
+ phy_set_drvdata(rptr->phy, rptr);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider))
+ return PTR_ERR(phy_provider);
+
+ dev_info(dev, "Registered Qcom-eUSB2 repeater\n");
+
+ return 0;
+}
+
+static int eusb2_repeater_remove(struct platform_device *pdev)
+{
+ struct eusb2_repeater *rptr = platform_get_drvdata(pdev);
+
+ if (!rptr)
+ return 0;
+
+ eusb2_repeater_exit(rptr->phy);
+
+ return 0;
+}
+
+static const struct of_device_id eusb2_repeater_of_match_table[] = {
+ {
+ .compatible = "qcom,pm8550b-eusb2-repeater",
+ .data = &pm8550b_eusb2_cfg,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table);
+
+static struct platform_driver eusb2_repeater_driver = {
+ .probe = eusb2_repeater_probe,
+ .remove = eusb2_repeater_remove,
+ .driver = {
+ .name = "qcom-eusb2-repeater",
+ .of_match_table = eusb2_repeater_of_match_table,
+ },
+};
+
+module_platform_driver(eusb2_repeater_driver);
+
+MODULE_DESCRIPTION("Qualcomm PMIC eUSB2 Repeater driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/qualcomm/phy-qcom-pcie2.c b/drivers/phy/qualcomm/phy-qcom-pcie2.c
index 5407e59bb185..11a2bb958681 100644
--- a/drivers/phy/qualcomm/phy-qcom-pcie2.c
+++ b/drivers/phy/qualcomm/phy-qcom-pcie2.c
@@ -243,7 +243,11 @@ static int phy_pipe_clksrc_register(struct qcom_phy *qphy)
fixed->fixed_rate = 250000000;
fixed->hw.init = &init;
- return devm_clk_hw_register(qphy->dev, &fixed->hw);
+ ret = devm_clk_hw_register(qphy->dev, &fixed->hw);
+ if (ret < 0)
+ return ret;
+
+ return devm_of_clk_add_hw_provider(qphy->dev, of_clk_hw_simple_get, &fixed->hw);
}
static int qcom_pcie2_phy_probe(struct platform_device *pdev)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 77052c66cf70..c1483e157af4 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -23,6 +23,10 @@
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-misc-v3.h"
+#include "phy-qcom-qmp-pcs-usb-v4.h"
+#include "phy-qcom-qmp-pcs-usb-v5.h"
+#include "phy-qcom-qmp-pcs-usb-v6.h"
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -56,9 +60,6 @@
/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
#define IRQ_CLEAR BIT(0)
-/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
-#define RCVR_DETECT BIT(0)
-
/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
#define CLAMP_EN BIT(0) /* enables i/o clamp_n */
@@ -96,31 +97,29 @@ enum qphy_reg_layout {
QPHY_PCS_STATUS,
QPHY_PCS_AUTONOMOUS_MODE_CTRL,
QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
- QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
QPHY_PCS_POWER_DOWN_CONTROL,
/* Keep last to ensure regs_layout arrays are properly initialized */
QPHY_LAYOUT_SIZE
};
static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_STATUS] = 0x174,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
- [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
- [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0dc,
- [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
+ [QPHY_SW_RESET] = QPHY_V3_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V3_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V3_PCS_PCS_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
};
static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x44,
- [QPHY_PCS_STATUS] = 0x14,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40,
+ [QPHY_SW_RESET] = QPHY_V4_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V4_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V4_PCS_PCS_STATUS1,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_POWER_DOWN_CONTROL,
/* In PCS_USB */
- [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x008,
- [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x014,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
};
static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
@@ -311,6 +310,70 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
};
+static const struct qmp_phy_init_tbl sm6350_usb3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl sm6350_usb3_pcs_tbl[] = {
+ /* FLL settings */
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+
+ /* Lock Det settings */
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
+
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xcc),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
+
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_DET_HIGH_COUNT_VAL, 0x04),
+
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x21),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
+};
+
static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
@@ -494,6 +557,223 @@ static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
+static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
+};
+
+static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
+};
+
+static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
+};
+
+static const struct qmp_phy_init_tbl sm8350_usb3_pcs_usb_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sm8550_usb3_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MSB_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0x75),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE1, 0x25),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MSB_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x75),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE0, 0x25),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_3, 0x37),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sm8550_usb3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_TX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_RX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0xf5),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_3, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_4, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_5, 0x5f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_TX_PI_QEC_CTRL, 0x21, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_TX_PI_QEC_CTRL, 0x05, 2),
+};
+
+static const struct qmp_phy_init_tbl sm8550_usb3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_PI_CONTROLS, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_GAIN1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_GAIN2, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL1, 0x54),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_GM_CAL, 0x13),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CNTRL, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_LOW, 0xdc),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH2, 0x9c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH3, 0x1d),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH4, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_DCC_CTRL1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_VTH_CODE, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_CTRL1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_TRIM, 0x08),
+
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_LOW, 0x3f, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xbf, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xff, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xdf, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xed, 1),
+
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_LOW, 0xbf, 2),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xbf, 2),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xbf, 2),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xdf, 2),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xfd, 2),
+};
+
+static const struct qmp_phy_init_tbl sm8550_usb3_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG1, 0xc4),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG2, 0x89),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG3, 0x20),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG6, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_REFGEN_REQ_CONFIG1, 0x21),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_RX_SIGDET_LVL, 0x99),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_CDR_RESET_TIME, 0x0a),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_ALIGN_DETECT_CONFIG1, 0x88),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_ALIGN_DETECT_CONFIG2, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_PCS_TX_RX_CONFIG, 0x0c),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG1, 0x4b),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG5, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1, 0x68),
+};
+
+static const struct qmp_phy_init_tbl sm8550_usb3_pcs_usb_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
+};
+
static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
@@ -600,6 +880,20 @@ static const struct qmp_phy_init_tbl qmp_v5_dp_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
};
+static const struct qmp_phy_init_tbl qmp_v5_dp_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_VMODE_CTRL1, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_INTERFACE_SELECT, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_CLKBUF_ENABLE, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RESET_TSYNC_EN, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_TX_INTERFACE_MODE, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_TX_BAND, 0x04),
+};
+
static const struct qmp_phy_init_tbl qmp_v5_5nm_dp_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_5NM_TX_LANE_MODE_3, 0x51),
QMP_PHY_INIT_CFG(QSERDES_V5_5NM_TX_TRANSCEIVER_BIAS_EN, 0x1a),
@@ -615,6 +909,91 @@ static const struct qmp_phy_init_tbl qmp_v5_5nm_dp_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_5NM_TX_TX_BAND, 0x01),
};
+static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SVS_MODE_CLK_SEL, 0x15),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_CTRL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_INTERFACE_SELECT, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_CLKBUF_ENABLE, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RESET_TSYNC_EN, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_TRAN_DRVR_EMP_EN, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_TX_INTERFACE_MODE, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_TX_BAND, 0x4),
+};
+
+static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x37),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_hbr[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_hbr2[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x46),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x97),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x10),
+};
+
+static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_hbr3[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x15),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c),
+};
+
static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
@@ -768,6 +1147,27 @@ static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
{ 0x1f, 0xff, 0xff, 0xff }
};
+static const u8 qmp_dp_v4_pre_emphasis_hbr3_hbr2[4][4] = {
+ { 0x00, 0x0c, 0x15, 0x1b },
+ { 0x02, 0x0e, 0x16, 0xff },
+ { 0x02, 0x11, 0xff, 0xff },
+ { 0x04, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v4_pre_emphasis_hbr_rbr[4][4] = {
+ { 0x00, 0x0d, 0x14, 0x1a },
+ { 0x00, 0x0e, 0x15, 0xff },
+ { 0x00, 0x0d, 0xff, 0xff },
+ { 0x03, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v4_voltage_swing_hbr_rbr[4][4] = {
+ { 0x08, 0x0f, 0x16, 0x1f },
+ { 0x11, 0x1e, 0x1f, 0xff },
+ { 0x16, 0x1f, 0xff, 0xff },
+ { 0x1f, 0xff, 0xff, 0xff }
+};
+
static const u8 qmp_dp_v5_pre_emphasis_hbr3_hbr2[4][4] = {
{ 0x20, 0x2c, 0x35, 0x3b },
{ 0x22, 0x2e, 0x36, 0xff },
@@ -796,6 +1196,13 @@ static const u8 qmp_dp_v5_voltage_swing_hbr_rbr[4][4] = {
{ 0x3f, 0xff, 0xff, 0xff }
};
+static const u8 qmp_dp_v6_pre_emphasis_hbr_rbr[4][4] = {
+ { 0x20, 0x2d, 0x34, 0x3a },
+ { 0x20, 0x2e, 0x35, 0xff },
+ { 0x20, 0x2e, 0xff, 0xff },
+ { 0x22, 0xff, 0xff, 0xff }
+};
+
struct qmp_combo;
struct qmp_combo_offsets {
@@ -809,6 +1216,8 @@ struct qmp_combo_offsets {
u16 usb3_pcs;
u16 usb3_pcs_usb;
u16 dp_serdes;
+ u16 dp_txa;
+ u16 dp_txb;
u16 dp_dp_phy;
};
@@ -928,6 +1337,9 @@ static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp);
static int qmp_v5_configure_dp_phy(struct qmp_combo *qmp);
+static void qmp_v6_dp_aux_init(struct qmp_combo *qmp);
+static int qmp_v6_configure_dp_phy(struct qmp_combo *qmp);
+
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
{
u32 reg;
@@ -975,6 +1387,21 @@ static const char * const sc7180_usb3phy_reset_l[] = {
"phy",
};
+static const struct qmp_combo_offsets qmp_combo_offsets_v3 = {
+ .com = 0x0000,
+ .txa = 0x1200,
+ .rxa = 0x1400,
+ .txb = 0x1600,
+ .rxb = 0x1800,
+ .usb3_serdes = 0x1000,
+ .usb3_pcs_misc = 0x1a00,
+ .usb3_pcs = 0x1c00,
+ .dp_serdes = 0x2000,
+ .dp_txa = 0x2200,
+ .dp_txb = 0x2600,
+ .dp_dp_phy = 0x2a00,
+};
+
static const struct qmp_combo_offsets qmp_combo_offsets_v5 = {
.com = 0x0000,
.txa = 0x0400,
@@ -989,6 +1416,22 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v5 = {
.dp_dp_phy = 0x2200,
};
+static const struct qmp_combo_offsets qmp_combo_offsets_v6 = {
+ .com = 0x0000,
+ .txa = 0x1200,
+ .rxa = 0x1400,
+ .txb = 0x1600,
+ .rxb = 0x1800,
+ .usb3_serdes = 0x1000,
+ .usb3_pcs_misc = 0x1a00,
+ .usb3_pcs = 0x1c00,
+ .usb3_pcs_usb = 0x1f00,
+ .dp_serdes = 0x2000,
+ .dp_txa = 0x2200,
+ .dp_txb = 0x2600,
+ .dp_dp_phy = 0x2a00,
+};
+
static const struct qmp_phy_cfg sc7180_usb3dpphy_cfg = {
.serdes_tbl = qmp_v3_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
@@ -1172,6 +1615,51 @@ static const struct qmp_phy_cfg sc8280xp_usb43dpphy_cfg = {
.regs = qmp_v4_usb3phy_regs_layout,
};
+static const struct qmp_phy_cfg sm6350_usb3dpphy_cfg = {
+ .offsets = &qmp_combo_offsets_v3,
+
+ .serdes_tbl = qmp_v3_usb3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
+ .tx_tbl = qmp_v3_usb3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
+ .rx_tbl = sm6350_usb3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(sm6350_usb3_rx_tbl),
+ .pcs_tbl = sm6350_usb3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(sm6350_usb3_pcs_tbl),
+
+ .dp_serdes_tbl = qmp_v3_dp_serdes_tbl,
+ .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
+ .dp_tx_tbl = qmp_v3_dp_tx_tbl,
+ .dp_tx_tbl_num = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
+
+ .serdes_tbl_rbr = qmp_v3_dp_serdes_tbl_rbr,
+ .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
+ .serdes_tbl_hbr = qmp_v3_dp_serdes_tbl_hbr,
+ .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
+ .serdes_tbl_hbr2 = qmp_v3_dp_serdes_tbl_hbr2,
+ .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
+ .serdes_tbl_hbr3 = qmp_v3_dp_serdes_tbl_hbr3,
+ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
+
+ .swing_hbr_rbr = &qmp_dp_v3_voltage_swing_hbr_rbr,
+ .pre_emphasis_hbr_rbr = &qmp_dp_v3_pre_emphasis_hbr_rbr,
+ .swing_hbr3_hbr2 = &qmp_dp_v3_voltage_swing_hbr3_hbr2,
+ .pre_emphasis_hbr3_hbr2 = &qmp_dp_v3_pre_emphasis_hbr3_hbr2,
+
+ .dp_aux_init = qmp_v3_dp_aux_init,
+ .configure_dp_tx = qmp_v3_configure_dp_tx,
+ .configure_dp_phy = qmp_v3_configure_dp_phy,
+ .calibrate_dp_phy = qmp_v3_calibrate_dp_phy,
+
+ .clk_list = qmp_v4_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v3_usb3phy_regs_layout,
+};
+
static const struct qmp_phy_cfg sm8250_usb3dpphy_cfg = {
.serdes_tbl = sm8150_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
@@ -1220,6 +1708,102 @@ static const struct qmp_phy_cfg sm8250_usb3dpphy_cfg = {
.has_pwrdn_delay = true,
};
+static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = {
+ .offsets = &qmp_combo_offsets_v3,
+
+ .serdes_tbl = sm8150_usb3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
+ .tx_tbl = sm8350_usb3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(sm8350_usb3_tx_tbl),
+ .rx_tbl = sm8350_usb3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(sm8350_usb3_rx_tbl),
+ .pcs_tbl = sm8350_usb3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(sm8350_usb3_pcs_tbl),
+ .pcs_usb_tbl = sm8350_usb3_pcs_usb_tbl,
+ .pcs_usb_tbl_num = ARRAY_SIZE(sm8350_usb3_pcs_usb_tbl),
+
+ .dp_serdes_tbl = qmp_v4_dp_serdes_tbl,
+ .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
+ .dp_tx_tbl = qmp_v5_dp_tx_tbl,
+ .dp_tx_tbl_num = ARRAY_SIZE(qmp_v5_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),
+
+ .swing_hbr_rbr = &qmp_dp_v4_voltage_swing_hbr_rbr,
+ .pre_emphasis_hbr_rbr = &qmp_dp_v4_pre_emphasis_hbr_rbr,
+ .swing_hbr3_hbr2 = &qmp_dp_v3_voltage_swing_hbr3_hbr2,
+ .pre_emphasis_hbr3_hbr2 = &qmp_dp_v4_pre_emphasis_hbr3_hbr2,
+
+ .dp_aux_init = qmp_v4_dp_aux_init,
+ .configure_dp_tx = qmp_v4_configure_dp_tx,
+ .configure_dp_phy = qmp_v4_configure_dp_phy,
+ .calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
+
+ .clk_list = qmp_v4_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v4_usb3phy_regs_layout,
+
+ .has_pwrdn_delay = true,
+};
+
+static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {
+ .offsets = &qmp_combo_offsets_v6,
+
+ .serdes_tbl = sm8550_usb3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(sm8550_usb3_serdes_tbl),
+ .tx_tbl = sm8550_usb3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(sm8550_usb3_tx_tbl),
+ .rx_tbl = sm8550_usb3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(sm8550_usb3_rx_tbl),
+ .pcs_tbl = sm8550_usb3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_tbl),
+ .pcs_usb_tbl = sm8550_usb3_pcs_usb_tbl,
+ .pcs_usb_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_usb_tbl),
+
+ .dp_serdes_tbl = qmp_v6_dp_serdes_tbl,
+ .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl),
+ .dp_tx_tbl = qmp_v6_dp_tx_tbl,
+ .dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl),
+
+ .serdes_tbl_rbr = qmp_v6_dp_serdes_tbl_rbr,
+ .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_rbr),
+ .serdes_tbl_hbr = qmp_v6_dp_serdes_tbl_hbr,
+ .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr),
+ .serdes_tbl_hbr2 = qmp_v6_dp_serdes_tbl_hbr2,
+ .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr2),
+ .serdes_tbl_hbr3 = qmp_v6_dp_serdes_tbl_hbr3,
+ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr3),
+
+ .swing_hbr_rbr = &qmp_dp_v5_voltage_swing_hbr_rbr,
+ .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr,
+ .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2,
+ .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2,
+
+ .dp_aux_init = qmp_v6_dp_aux_init,
+ .configure_dp_tx = qmp_v4_configure_dp_tx,
+ .configure_dp_phy = qmp_v6_configure_dp_phy,
+ .calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
+
+ .regs = qmp_v4_usb3phy_regs_layout,
+ .clk_list = qmp_v4_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+};
+
static void qmp_combo_configure_lane(void __iomem *base,
const struct qmp_phy_init_tbl tbl[],
int num,
@@ -1530,6 +2114,33 @@ static void qmp_v4_dp_aux_init(struct qmp_combo *qmp)
qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
}
+static void qmp_v6_dp_aux_init(struct qmp_combo *qmp)
+{
+ writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
+ DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
+ qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
+
+ /* Turn on BIAS current for PHY/PLL */
+ writel(0x17, qmp->dp_serdes + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN);
+
+ writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0);
+ writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
+ writel(0xa4, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
+ writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3);
+ writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4);
+ writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5);
+ writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6);
+ writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7);
+ writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8);
+ writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9);
+ qmp->dp_aux_cfg = 0;
+
+ writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
+ PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
+ PHY_AUX_REQ_ERR_MASK,
+ qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
+}
+
static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp)
{
/* Program default values before writing proper values */
@@ -1543,7 +2154,10 @@ static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp)
QSERDES_V4_TX_TX_EMP_POST1_LVL);
}
-static int qmp_v45_configure_dp_phy(struct qmp_combo *qmp)
+static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp,
+ unsigned int com_resetm_ctrl_reg,
+ unsigned int com_c_ready_status_reg,
+ unsigned int dp_phy_status_reg)
{
const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
u32 phy_vco_div, status;
@@ -1590,9 +2204,9 @@ static int qmp_v45_configure_dp_phy(struct qmp_combo *qmp)
writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
- writel(0x20, qmp->dp_serdes + QSERDES_V4_COM_RESETSM_CNTRL);
+ writel(0x20, qmp->dp_serdes + com_resetm_ctrl_reg);
- if (readl_poll_timeout(qmp->dp_serdes + QSERDES_V4_COM_C_READY_STATUS,
+ if (readl_poll_timeout(qmp->dp_serdes + com_c_ready_status_reg,
status,
((status & BIT(0)) > 0),
500,
@@ -1615,14 +2229,14 @@ static int qmp_v45_configure_dp_phy(struct qmp_combo *qmp)
writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
- if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V4_DP_PHY_STATUS,
+ if (readl_poll_timeout(qmp->dp_dp_phy + dp_phy_status_reg,
status,
((status & BIT(0)) > 0),
500,
10000))
return -ETIMEDOUT;
- if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V4_DP_PHY_STATUS,
+ if (readl_poll_timeout(qmp->dp_dp_phy + dp_phy_status_reg,
status,
((status & BIT(1)) > 0),
500,
@@ -1640,7 +2254,9 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp)
u32 status;
int ret;
- ret = qmp_v45_configure_dp_phy(qmp);
+ ret = qmp_v456_configure_dp_phy(qmp, QSERDES_V4_COM_RESETSM_CNTRL,
+ QSERDES_V4_COM_C_READY_STATUS,
+ QSERDES_V4_DP_PHY_STATUS);
if (ret < 0)
return ret;
@@ -1702,7 +2318,9 @@ static int qmp_v5_configure_dp_phy(struct qmp_combo *qmp)
u32 status;
int ret;
- ret = qmp_v45_configure_dp_phy(qmp);
+ ret = qmp_v456_configure_dp_phy(qmp, QSERDES_V4_COM_RESETSM_CNTRL,
+ QSERDES_V4_COM_C_READY_STATUS,
+ QSERDES_V4_DP_PHY_STATUS);
if (ret < 0)
return ret;
@@ -1751,6 +2369,65 @@ static int qmp_v5_configure_dp_phy(struct qmp_combo *qmp)
return 0;
}
+static int qmp_v6_configure_dp_phy(struct qmp_combo *qmp)
+{
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
+ bool reverse = false;
+ u32 status;
+ int ret;
+
+ ret = qmp_v456_configure_dp_phy(qmp, QSERDES_V6_COM_RESETSM_CNTRL,
+ QSERDES_V6_COM_C_READY_STATUS,
+ QSERDES_V6_DP_PHY_STATUS);
+ if (ret < 0)
+ return ret;
+
+ if (dp_opts->lanes == 1) {
+ bias0_en = reverse ? 0x3e : 0x1a;
+ drvr0_en = reverse ? 0x13 : 0x10;
+ bias1_en = reverse ? 0x15 : 0x3e;
+ drvr1_en = reverse ? 0x10 : 0x13;
+ } else if (dp_opts->lanes == 2) {
+ bias0_en = reverse ? 0x3f : 0x15;
+ drvr0_en = 0x10;
+ bias1_en = reverse ? 0x15 : 0x3f;
+ drvr1_en = 0x10;
+ } else {
+ bias0_en = 0x3f;
+ bias1_en = 0x3f;
+ drvr0_en = 0x10;
+ drvr1_en = 0x10;
+ }
+
+ writel(drvr0_en, qmp->dp_tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
+ writel(bias0_en, qmp->dp_tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
+ writel(drvr1_en, qmp->dp_tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
+ writel(bias1_en, qmp->dp_tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
+
+ writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+ udelay(2000);
+ writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+
+ if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V6_DP_PHY_STATUS,
+ status,
+ ((status & BIT(1)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ writel(0x0a, qmp->dp_tx + QSERDES_V4_TX_TX_POL_INV);
+ writel(0x0a, qmp->dp_tx2 + QSERDES_V4_TX_TX_POL_INV);
+
+ writel(0x27, qmp->dp_tx + QSERDES_V4_TX_TX_DRV_LVL);
+ writel(0x27, qmp->dp_tx2 + QSERDES_V4_TX_TX_DRV_LVL);
+
+ writel(0x20, qmp->dp_tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+ writel(0x20, qmp->dp_tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+
+ return 0;
+}
+
/*
* We need to calibrate the aux setting here as many times
* as the caller tries
@@ -2641,8 +3318,13 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)
qmp->pcs_usb = base + offs->usb3_pcs_usb;
qmp->dp_serdes = base + offs->dp_serdes;
- qmp->dp_tx = base + offs->txa;
- qmp->dp_tx2 = base + offs->txb;
+ if (offs->dp_txa) {
+ qmp->dp_tx = base + offs->dp_txa;
+ qmp->dp_tx2 = base + offs->dp_txb;
+ } else {
+ qmp->dp_tx = base + offs->txa;
+ qmp->dp_tx2 = base + offs->txb;
+ }
qmp->dp_dp_phy = base + offs->dp_dp_phy;
qmp->pipe_clk = devm_clk_get(dev, "usb3_pipe");
@@ -2790,9 +3472,25 @@ static const struct of_device_id qmp_combo_of_match_table[] = {
.data = &sdm845_usb3dpphy_cfg,
},
{
+ .compatible = "qcom,sm6350-qmp-usb3-dp-phy",
+ .data = &sm6350_usb3dpphy_cfg,
+ },
+ {
.compatible = "qcom,sm8250-qmp-usb3-dp-phy",
.data = &sm8250_usb3dpphy_cfg,
},
+ {
+ .compatible = "qcom,sm8350-qmp-usb3-dp-phy",
+ .data = &sm8350_usb3dpphy_cfg,
+ },
+ {
+ .compatible = "qcom,sm8450-qmp-usb3-dp-phy",
+ .data = &sm8350_usb3dpphy_cfg,
+ },
+ {
+ .compatible = "qcom,sm8550-qmp-usb3-dp-phy",
+ .data = &sm8550_usb3dpphy_cfg,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, qmp_combo_of_match_table);
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
index a088477e274f..09824be088c9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
@@ -84,9 +84,9 @@ static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_COM_POWER_DOWN_CONTROL] = 0x404,
[QPHY_COM_START_CONTROL] = 0x408,
[QPHY_COM_PCS_READY_STATUS] = 0x448,
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_STATUS] = 0x174,
+ [QPHY_SW_RESET] = QPHY_V2_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V2_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V2_PCS_PCI_PCS_STATUS,
};
static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 1b136a87053f..5182aeac43ee 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -24,6 +24,14 @@
#include <linux/slab.h>
#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-misc-v3.h"
+#include "phy-qcom-qmp-pcs-pcie-v4.h"
+#include "phy-qcom-qmp-pcs-pcie-v4_20.h"
+#include "phy-qcom-qmp-pcs-pcie-v5.h"
+#include "phy-qcom-qmp-pcs-pcie-v5_20.h"
+#include "phy-qcom-qmp-pcs-pcie-v6.h"
+#include "phy-qcom-qmp-pcs-pcie-v6_20.h"
+#include "phy-qcom-qmp-pcie-qhp.h"
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -74,25 +82,18 @@ enum qphy_reg_layout {
QPHY_LAYOUT_SIZE
};
-static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x44,
- [QPHY_PCS_STATUS] = 0x14,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40,
+static const unsigned int pciephy_v2_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V2_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V2_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V2_PCS_PCI_PCS_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_POWER_DOWN_CONTROL,
};
-static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_STATUS] = 0x174,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
-};
-
-static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_STATUS] = 0x174,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
+static const unsigned int pciephy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V3_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V3_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V3_PCS_PCS_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL,
};
static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
@@ -102,11 +103,18 @@ static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
};
-static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x44,
- [QPHY_PCS_STATUS] = 0x14,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40,
+static const unsigned int pciephy_v4_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V4_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V4_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V4_PCS_PCS_STATUS1,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_POWER_DOWN_CONTROL,
+};
+
+static const unsigned int pciephy_v5_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V5_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V5_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V5_PCS_PCS_STATUS1,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V5_PCS_POWER_DOWN_CONTROL,
};
static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
@@ -1216,7 +1224,7 @@ static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
};
-static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
+static const struct qmp_phy_init_tbl sm8450_qmp_gen3_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
@@ -1250,7 +1258,6 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
- QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
@@ -1261,6 +1268,10 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
};
+static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rc_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
+};
+
static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
@@ -1269,11 +1280,9 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x04),
};
-static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
+static const struct qmp_phy_init_tbl sm8450_qmp_gen3_pcie_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
- QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
- QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
@@ -1281,20 +1290,25 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
- QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
- QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
- QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
+};
+
+static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rc_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
};
-static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_tbl[] = {
+static const struct qmp_phy_init_tbl sm8450_qmp_gen3_pcie_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
@@ -1307,6 +1321,40 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
};
+static const struct qmp_phy_init_tbl sm8350_qmp_gen3x1_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1d),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sm8350_qmp_gen3x1_pcie_rc_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
+};
+
+static const struct qmp_phy_init_tbl sm8350_qmp_gen3x2_pcie_rc_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl sm8350_qmp_gen3x2_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V5_TX_PI_QEC_CTRL, 0x02, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V5_TX_PI_QEC_CTRL, 0x04, 2),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xd5),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1d),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sm8350_qmp_gen3x2_pcie_rc_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x0f),
+};
+
static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
@@ -1458,6 +1506,234 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl[] =
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08),
};
+static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x93),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC_3, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x15),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_4, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_PI_QEC_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x18),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_GM_CAL, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xb7),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xea),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_LOW, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH2, 0x9c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH3, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH4, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_LOW, 0xdc),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH, 0x94),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH2, 0x5b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH3, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH4, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIDGET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_TRIM, 0x08),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_REFGEN_REQ_CONFIG1, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_RX_SIGDET_LVL, 0x77),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_RATE_SLEW_CNTRL1, 0x0b),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG2, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_PCS_TX_RX_CONFIG, 0x8c),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_ln_shrd_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_Q_EN_RATES, 0xe),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1d),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x7c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0xb3),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x26),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0xdb),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xdb),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x78),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
+ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G3S2_PRE_GAIN, 0x2e),
+ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_COM_ELECIDLE_DLY_SEL, 0x25),
+ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG4, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG5, 0x22),
+ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_TX_RX_CONFIG1, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_TX_RX_CONFIG2, 0x02),
+};
+
+static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG1, 0x16),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG5, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN, 0x2e),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG3, 0x28),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_TX_RX_CONFIG, 0xc0),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_POWER_STATE_CONFIG2, 0x1d),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG5, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_FOM_EQ_CONFIG5, 0xf2),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0xf2),
+};
+
struct qmp_pcie_offsets {
u16 serdes;
u16 pcs;
@@ -1466,6 +1742,7 @@ struct qmp_pcie_offsets {
u16 rx;
u16 tx2;
u16 rx2;
+ u16 ln_shrd;
};
struct qmp_phy_cfg_tbls {
@@ -1479,6 +1756,8 @@ struct qmp_phy_cfg_tbls {
int pcs_num;
const struct qmp_phy_init_tbl *pcs_misc;
int pcs_misc_num;
+ const struct qmp_phy_init_tbl *ln_shrd;
+ int ln_shrd_num;
};
/* struct qmp_phy_cfg - per-PHY initialization config */
@@ -1521,6 +1800,8 @@ struct qmp_phy_cfg {
bool skip_start_delay;
+ bool has_nocsr_reset;
+
/* QMP PHY pipe clock interface rate */
unsigned long pipe_clock_rate;
};
@@ -1538,6 +1819,7 @@ struct qmp_pcie {
void __iomem *rx;
void __iomem *tx2;
void __iomem *rx2;
+ void __iomem *ln_shrd;
void __iomem *port_b;
@@ -1546,6 +1828,7 @@ struct qmp_pcie {
int num_pipe_clks;
struct reset_control_bulk_data *resets;
+ struct reset_control *nocsr_reset;
struct regulator_bulk_data *vregs;
struct phy *phy;
@@ -1600,6 +1883,10 @@ static const char * const qmp_phy_vreg_l[] = {
"vdda-phy", "vdda-pll",
};
+static const char * const sm8550_qmp_phy_vreg_l[] = {
+ "vdda-phy", "vdda-pll", "vdda-qref",
+};
+
/* list of resets */
static const char * const ipq8074_pciephy_reset_l[] = {
"phy", "common",
@@ -1619,6 +1906,17 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v5 = {
.rx2 = 0x1800,
};
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = {
+ .serdes = 0x1000,
+ .pcs = 0x1200,
+ .pcs_misc = 0x1400,
+ .tx = 0x0000,
+ .rx = 0x0200,
+ .tx2 = 0x0800,
+ .rx2 = 0x0a00,
+ .ln_shrd = 0x0e00,
+};
+
static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.lanes = 1,
@@ -1638,7 +1936,7 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
.vreg_list = NULL,
.num_vregs = 0,
- .regs = pciephy_regs_layout,
+ .regs = pciephy_v2_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1665,7 +1963,7 @@ static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
.vreg_list = NULL,
.num_vregs = 0,
- .regs = ipq_pciephy_gen3_regs_layout,
+ .regs = pciephy_v4_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1694,7 +1992,7 @@ static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
.vreg_list = NULL,
.num_vregs = 0,
- .regs = ipq_pciephy_gen3_regs_layout,
+ .regs = pciephy_v4_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1721,7 +2019,7 @@ static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sdm845_qmp_pciephy_regs_layout,
+ .regs = pciephy_v3_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1783,7 +2081,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v4_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1820,7 +2118,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v4_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1845,7 +2143,7 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = pciephy_regs_layout,
+ .regs = pciephy_v3_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1874,7 +2172,7 @@ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v4_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1909,7 +2207,7 @@ static const struct qmp_phy_cfg sc8280xp_qmp_gen3x1_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v5_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1944,7 +2242,7 @@ static const struct qmp_phy_cfg sc8280xp_qmp_gen3x2_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v5_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -1982,7 +2280,7 @@ static const struct qmp_phy_cfg sc8280xp_qmp_gen3x4_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v5_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -2009,34 +2307,116 @@ static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v4_regs_layout,
.pwrdn_ctrl = SW_PWRDN,
.phy_status = PHYSTATUS_4_20,
};
+static const struct qmp_phy_cfg sm8350_qmp_gen3x1_pciephy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = sm8450_qmp_gen3_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_serdes_tbl),
+ .tx = sm8350_qmp_gen3x1_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sm8350_qmp_gen3x1_pcie_tx_tbl),
+ .rx = sm8450_qmp_gen3_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_rx_tbl),
+ .pcs = sm8450_qmp_gen3_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_pcs_tbl),
+ .pcs_misc = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
+ },
+
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+ .serdes = sm8450_qmp_gen3x1_pcie_rc_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rc_serdes_tbl),
+ .rx = sm8350_qmp_gen3x1_pcie_rc_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8350_qmp_gen3x1_pcie_rc_rx_tbl),
+ },
+
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_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 = pciephy_v5_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
+static const struct qmp_phy_cfg sm8350_qmp_gen3x2_pciephy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = sm8450_qmp_gen3_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_serdes_tbl),
+ .tx = sm8350_qmp_gen3x2_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sm8350_qmp_gen3x2_pcie_tx_tbl),
+ .rx = sm8450_qmp_gen3_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_rx_tbl),
+ .pcs = sm8450_qmp_gen3_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_pcs_tbl),
+ .pcs_misc = sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl),
+ },
+
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+ .rx = sm8350_qmp_gen3x2_pcie_rc_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8350_qmp_gen3x2_pcie_rc_rx_tbl),
+ .pcs = sm8350_qmp_gen3x2_pcie_rc_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sm8350_qmp_gen3x2_pcie_rc_pcs_tbl),
+ },
+
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_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 = pciephy_v5_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
.lanes = 1,
.tbls = {
- .serdes = sm8450_qmp_gen3x1_pcie_serdes_tbl,
- .serdes_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
+ .serdes = sm8450_qmp_gen3_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_serdes_tbl),
.tx = sm8450_qmp_gen3x1_pcie_tx_tbl,
.tx_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_tx_tbl),
- .rx = sm8450_qmp_gen3x1_pcie_rx_tbl,
- .rx_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rx_tbl),
- .pcs = sm8450_qmp_gen3x1_pcie_pcs_tbl,
- .pcs_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_tbl),
+ .rx = sm8450_qmp_gen3_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_rx_tbl),
+ .pcs = sm8450_qmp_gen3_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sm8450_qmp_gen3_pcie_pcs_tbl),
.pcs_misc = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
},
+
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+ .serdes = sm8450_qmp_gen3x1_pcie_rc_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rc_serdes_tbl),
+ .rx = sm8450_qmp_gen3x1_pcie_rc_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rc_rx_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,
+ .regs = pciephy_v5_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
@@ -2078,12 +2458,73 @@ static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8250_pcie_regs_layout,
+ .regs = pciephy_v5_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS_4_20,
};
+static const struct qmp_phy_cfg sm8550_qmp_gen3x2_pciephy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = sm8550_qmp_gen3x2_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_serdes_tbl),
+ .tx = sm8550_qmp_gen3x2_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_tx_tbl),
+ .rx = sm8550_qmp_gen3x2_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_rx_tbl),
+ .pcs = sm8550_qmp_gen3x2_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_tbl),
+ .pcs_misc = sm8550_qmp_gen3x2_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_misc_tbl),
+ },
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_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 = pciephy_v5_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
+static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_pcie_offsets_v6_20,
+
+ .tbls = {
+ .serdes = sm8550_qmp_gen4x2_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sm8550_qmp_gen4x2_pcie_serdes_tbl),
+ .tx = sm8550_qmp_gen4x2_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sm8550_qmp_gen4x2_pcie_tx_tbl),
+ .rx = sm8550_qmp_gen4x2_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sm8550_qmp_gen4x2_pcie_rx_tbl),
+ .pcs = sm8550_qmp_gen4x2_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sm8550_qmp_gen4x2_pcie_pcs_tbl),
+ .pcs_misc = sm8550_qmp_gen4x2_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sm8550_qmp_gen4x2_pcie_pcs_misc_tbl),
+ .ln_shrd = sm8550_qmp_gen4x2_pcie_ln_shrd_tbl,
+ .ln_shrd_num = ARRAY_SIZE(sm8550_qmp_gen4x2_pcie_ln_shrd_tbl),
+ },
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_pciephy_clk_l),
+ .reset_list = sdm845_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
+ .vreg_list = sm8550_qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
+ .regs = pciephy_v5_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS_4_20,
+ .has_nocsr_reset = true,
+};
+
static void qmp_pcie_configure_lane(void __iomem *base,
const struct qmp_phy_init_tbl tbl[],
int num,
@@ -2138,6 +2579,7 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
void __iomem *rx2 = qmp->rx2;
void __iomem *pcs = qmp->pcs;
void __iomem *pcs_misc = qmp->pcs_misc;
+ void __iomem *ln_shrd = qmp->ln_shrd;
if (!tbls)
return;
@@ -2159,6 +2601,8 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
qmp_pcie_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
qmp_pcie_init_port_b(qmp, tbls);
}
+
+ qmp_pcie_configure(ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
}
static int qmp_pcie_init(struct phy *phy)
@@ -2179,12 +2623,18 @@ static int qmp_pcie_init(struct phy *phy)
goto err_disable_regulators;
}
+ ret = reset_control_assert(qmp->nocsr_reset);
+ if (ret) {
+ dev_err(qmp->dev, "no-csr reset assert failed\n");
+ goto err_assert_reset;
+ }
+
usleep_range(200, 300);
ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
if (ret) {
dev_err(qmp->dev, "reset deassert failed\n");
- goto err_disable_regulators;
+ goto err_assert_reset;
}
ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
@@ -2240,6 +2690,12 @@ static int qmp_pcie_power_on(struct phy *phy)
if (ret)
return ret;
+ ret = reset_control_deassert(qmp->nocsr_reset);
+ if (ret) {
+ dev_err(qmp->dev, "no-csr reset deassert failed\n");
+ goto err_disable_pipe_clk;
+ }
+
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
@@ -2373,6 +2829,13 @@ static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
if (ret)
return dev_err_probe(dev, ret, "failed to get resets\n");
+ if (cfg->has_nocsr_reset) {
+ qmp->nocsr_reset = devm_reset_control_get_exclusive(dev, "phy_nocsr");
+ if (IS_ERR(qmp->nocsr_reset))
+ return dev_err_probe(dev, PTR_ERR(qmp->nocsr_reset),
+ "failed to get no-csr reset\n");
+ }
+
return 0;
}
@@ -2595,11 +3058,18 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
return PTR_ERR(qmp->port_b);
}
+ if (cfg->tbls.ln_shrd)
+ qmp->ln_shrd = base + offs->ln_shrd;
+
qmp->num_pipe_clks = 2;
qmp->pipe_clks[0].id = "pipe";
qmp->pipe_clks[1].id = "pipediv2";
- ret = devm_clk_bulk_get(dev, qmp->num_pipe_clks, qmp->pipe_clks);
+ ret = devm_clk_bulk_get(dev, 1, qmp->pipe_clks);
+ if (ret)
+ return ret;
+
+ ret = devm_clk_bulk_get_optional(dev, qmp->num_pipe_clks - 1, qmp->pipe_clks + 1);
if (ret)
return ret;
@@ -2720,11 +3190,23 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
.compatible = "qcom,sm8250-qmp-modem-pcie-phy",
.data = &sm8250_qmp_gen3x2_pciephy_cfg,
}, {
+ .compatible = "qcom,sm8350-qmp-gen3x1-pcie-phy",
+ .data = &sm8350_qmp_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8350-qmp-gen3x2-pcie-phy",
+ .data = &sm8350_qmp_gen3x2_pciephy_cfg,
+ }, {
.compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
.data = &sm8450_qmp_gen3x1_pciephy_cfg,
}, {
.compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
.data = &sm8450_qmp_gen4x2_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8550-qmp-gen3x2-pcie-phy",
+ .data = &sm8550_qmp_gen3x2_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8550-qmp-gen4x2-pcie-phy",
+ .data = &sm8550_qmp_gen4x2_pciephy_cfg,
},
{ },
};
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
new file mode 100644
index 000000000000..91e70002eb47
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_PCIE_V6_H_
+#define QCOM_PHY_QMP_PCS_PCIE_V6_H_
+
+/* Only for QMP V6 PHY - PCIE have different offsets than V5 */
+#define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
+#define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4 0x14
+#define QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
+#define QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h
new file mode 100644
index 000000000000..e3eb08776339
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_PCIE_V6_20_H_
+#define QCOM_PHY_QMP_PCS_PCIE_V6_20_H_
+
+/* Only for QMP V6_20 PHY - PCIE have different offsets than V5 */
+#define QPHY_PCIE_V6_20_PCS_POWER_STATE_CONFIG2 0x00c
+#define QPHY_PCIE_V6_20_PCS_TX_RX_CONFIG 0x018
+#define QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE 0x01c
+#define QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS 0x090
+#define QPHY_PCIE_V6_20_PCS_EQ_CONFIG1 0x0a0
+#define QPHY_PCIE_V6_20_PCS_EQ_CONFIG5 0x108
+#define QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN 0x15c
+#define QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1 0x17c
+#define QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG3 0x184
+#define QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG5 0x18c
+#define QPHY_PCIE_V6_20_PCS_G3_FOM_EQ_CONFIG5 0x1ac
+#define QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5 0x1c0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v2.h
new file mode 100644
index 000000000000..a0803a8783d2
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v2.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V2_H_
+#define QCOM_PHY_QMP_PCS_UFS_V2_H_
+
+#define QPHY_V2_PCS_UFS_PHY_START 0x000
+#define QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL 0x004
+
+#define QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x034
+#define QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL 0x038
+#define QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x03c
+#define QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL 0x040
+
+#define QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP 0x0cc
+#define QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL 0x13c
+#define QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME 0x140
+#define QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2 0x148
+#define QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND 0x154
+
+#define QPHY_V2_PCS_UFS_READY_STATUS 0x168
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v3.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v3.h
index ba1ea29d2884..adea13c3a9e6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v3.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v3.h
@@ -6,12 +6,15 @@
#ifndef QCOM_PHY_QMP_PCS_UFS_V3_H_
#define QCOM_PHY_QMP_PCS_UFS_V3_H_
+#define QPHY_V3_PCS_UFS_PHY_START 0x000
+#define QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL 0x004
#define QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x02c
#define QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x034
#define QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL 0x134
#define QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME 0x138
#define QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1 0x13c
#define QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2 0x140
+#define QPHY_V3_PCS_UFS_READY_STATUS 0x160
#define QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1 0x1bc
#define QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1 0x1c4
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v5.h
index bcca23493b7e..07959964fcf6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v5.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v5.h
@@ -8,11 +8,15 @@
#define QCOM_PHY_QMP_PCS_UFS_V5_H_
/* Only for QMP V5 PHY - UFS PCS registers */
+#define QPHY_V5_PCS_UFS_PHY_START 0x000
+#define QPHY_V5_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V5_PCS_UFS_SW_RESET 0x008
#define QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB 0x00c
#define QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB 0x010
#define QPHY_V5_PCS_UFS_PLL_CNTL 0x02c
#define QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x030
#define QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x038
+#define QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL 0x060
#define QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY 0x074
#define QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY 0x0b4
#define QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL 0x124
@@ -21,6 +25,7 @@
#define QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2 0x158
#define QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND 0x160
#define QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND 0x168
+#define QPHY_V5_PCS_UFS_READY_STATUS 0x180
#define QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1 0x1d8
#define QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1 0x1e0
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
new file mode 100644
index 000000000000..c23d5e41e25b
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V6_H_
+#define QCOM_PHY_QMP_PCS_UFS_V6_H_
+
+/* Only for QMP V6 PHY - UFS PCS registers */
+#define QPHY_V6_PCS_UFS_PHY_START 0x000
+#define QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V6_PCS_UFS_SW_RESET 0x008
+#define QPHY_V6_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB 0x00c
+#define QPHY_V6_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB 0x010
+#define QPHY_V6_PCS_UFS_PLL_CNTL 0x02c
+#define QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x030
+#define QPHY_V6_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x038
+#define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL 0x060
+#define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY 0x074
+#define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY 0x0bc
+#define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL 0x158
+#define QPHY_V6_PCS_UFS_LINECFG_DISABLE 0x17c
+#define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME 0x184
+#define QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2 0x18c
+#define QPHY_V6_PCS_UFS_TX_PWM_GEAR_BAND 0x178
+#define QPHY_V6_PCS_UFS_TX_HS_GEAR_BAND 0x174
+#define QPHY_V6_PCS_UFS_READY_STATUS 0x1a8
+#define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1 0x1f4
+#define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1 0x1fc
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h
new file mode 100644
index 000000000000..9510e63ba9d8
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_USB_V6_H_
+#define QCOM_PHY_QMP_PCS_USB_V6_H_
+
+/* Only for QMP V6 PHY - USB3 have different offsets than V5 */
+#define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG1 0xc4
+#define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG2 0xc8
+#define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG3 0xcc
+#define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG6 0xd8
+#define QPHY_USB_V6_PCS_REFGEN_REQ_CONFIG1 0xdc
+#define QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1 0x90
+#define QPHY_USB_V6_PCS_RX_SIGDET_LVL 0x188
+#define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
+#define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
+#define QPHY_USB_V6_PCS_CDR_RESET_TIME 0x1b0
+#define QPHY_USB_V6_PCS_ALIGN_DETECT_CONFIG1 0x1c0
+#define QPHY_USB_V6_PCS_ALIGN_DETECT_CONFIG2 0x1c4
+#define QPHY_USB_V6_PCS_PCS_TX_RX_CONFIG 0x1d0
+#define QPHY_USB_V6_PCS_EQ_CONFIG1 0x1dc
+#define QPHY_USB_V6_PCS_EQ_CONFIG5 0x1ec
+
+#define QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x18
+#define QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x3c
+#define QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40
+#define QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_H 0x44
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v2.h
index c8515f506872..bf36399d0057 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v2.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v2.h
@@ -7,13 +7,11 @@
#define QCOM_PHY_QMP_PCS_V2_H_
/* Only for QMP V2 PHY - PCS registers */
+#define QPHY_V2_PCS_SW_RESET 0x000
#define QPHY_V2_PCS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V2_PCS_START_CONTROL 0x008
#define QPHY_V2_PCS_TXDEEMPH_M6DB_V0 0x024
#define QPHY_V2_PCS_TXDEEMPH_M3P5DB_V0 0x028
-#define QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL 0x034
-#define QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL 0x038
-#define QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL 0x03c
-#define QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL 0x040
#define QPHY_V2_PCS_ENDPOINT_REFCLK_DRIVE 0x054
#define QPHY_V2_PCS_RX_IDLE_DTCT_CNTRL 0x058
#define QPHY_V2_PCS_POWER_STATE_CONFIG1 0x060
@@ -30,17 +28,16 @@
#define QPHY_V2_PCS_FLL_CNT_VAL_L 0x0c8
#define QPHY_V2_PCS_FLL_CNT_VAL_H_TOL 0x0cc
#define QPHY_V2_PCS_FLL_MAN_CODE 0x0d0
-
-/* UFS only ? */
-#define QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP 0x0cc
-#define QPHY_V2_PCS_RX_SYM_RESYNC_CTRL 0x13c
-#define QPHY_V2_PCS_RX_MIN_HIBERN8_TIME 0x140
-#define QPHY_V2_PCS_RX_SIGDET_CTRL2 0x148
-#define QPHY_V2_PCS_RX_PWM_GEAR_BAND 0x154
+#define QPHY_V2_PCS_AUTONOMOUS_MODE_CTRL 0x0d4
+#define QPHY_V2_PCS_LFPS_RXTERM_IRQ_CLEAR 0x0d8
+#define QPHY_V2_PCS_LFPS_RXTERM_IRQ_STATUS 0x178
+#define QPHY_V2_PCS_USB_PCS_STATUS 0x17c /* USB */
#define QPHY_V2_PCS_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1a8
#define QPHY_V2_PCS_OSC_DTCT_ACTIONS 0x1ac
#define QPHY_V2_PCS_RX_SIGDET_LVL 0x1d8
#define QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1dc
#define QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1e0
+#define QPHY_V2_PCS_PCI_PCS_STATUS 0x174 /* PCI */
+
#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5.h
index 04f260711ea1..36cc80bb9059 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5.h
@@ -7,6 +7,10 @@
#define QCOM_PHY_QMP_PCS_V5_H_
/* Only for QMP V5 PHY - USB/PCIe PCS registers */
+#define QPHY_V5_PCS_SW_RESET 0x000
+#define QPHY_V5_PCS_PCS_STATUS1 0x014
+#define QPHY_V5_PCS_POWER_DOWN_CONTROL 0x040
+#define QPHY_V5_PCS_START_CONTROL 0x044
#define QPHY_V5_PCS_LOCK_DETECT_CONFIG1 0x0c4
#define QPHY_V5_PCS_LOCK_DETECT_CONFIG2 0x0c8
#define QPHY_V5_PCS_LOCK_DETECT_CONFIG3 0x0cc
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6.h
new file mode 100644
index 000000000000..18c4a3abe590
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V6_H_
+#define QCOM_PHY_QMP_PCS_V6_H_
+
+/* Only for QMP V6 PHY - USB/PCIe PCS registers */
+#define QPHY_V6_PCS_REFGEN_REQ_CONFIG1 0xdc
+#define QPHY_V6_PCS_RX_SIGDET_LVL 0x188
+#define QPHY_V6_PCS_RATE_SLEW_CNTRL1 0x198
+#define QPHY_V6_PCS_EQ_CONFIG2 0x1e0
+#define QPHY_V6_PCS_PCS_TX_RX_CONFIG 0x1d0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h
new file mode 100644
index 000000000000..9c3f1e4950e6
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V6_20_H_
+#define QCOM_PHY_QMP_PCS_V6_20_H_
+
+/* Only for QMP V6_20 PHY - USB/PCIe PCS registers */
+#define QPHY_V6_20_PCS_G3S2_PRE_GAIN 0x178
+#define QPHY_V6_20_PCS_RX_SIGDET_LVL 0x190
+#define QPHY_V6_20_PCS_COM_ELECIDLE_DLY_SEL 0x1b8
+#define QPHY_V6_20_PCS_TX_RX_CONFIG1 0x1dc
+#define QPHY_V6_20_PCS_TX_RX_CONFIG2 0x1e0
+#define QPHY_V6_20_PCS_EQ_CONFIG4 0x1f8
+#define QPHY_V6_20_PCS_EQ_CONFIG5 0x1fc
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
new file mode 100644
index 000000000000..f420f8faf16a
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_COM_V6_H_
+#define QCOM_PHY_QMP_QSERDES_COM_V6_H_
+
+/* Only for QMP V6 PHY - QSERDES COM registers */
+
+#define QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1 0x00
+#define QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1 0x04
+#define QSERDES_V6_COM_CP_CTRL_MODE1 0x10
+#define QSERDES_V6_COM_PLL_RCTRL_MODE1 0x14
+#define QSERDES_V6_COM_PLL_CCTRL_MODE1 0x18
+#define QSERDES_V6_COM_CORECLK_DIV_MODE1 0x1c
+#define QSERDES_V6_COM_LOCK_CMP1_MODE1 0x20
+#define QSERDES_V6_COM_LOCK_CMP2_MODE1 0x24
+#define QSERDES_V6_COM_DEC_START_MODE1 0x28
+#define QSERDES_V6_COM_DEC_START_MSB_MODE1 0x2c
+#define QSERDES_V6_COM_DIV_FRAC_START1_MODE1 0x30
+#define QSERDES_V6_COM_DIV_FRAC_START2_MODE1 0x34
+#define QSERDES_V6_COM_DIV_FRAC_START3_MODE1 0x38
+#define QSERDES_V6_COM_HSCLK_SEL_1 0x3c
+#define QSERDES_V6_COM_VCO_TUNE1_MODE1 0x48
+#define QSERDES_V6_COM_VCO_TUNE2_MODE1 0x4c
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x50
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x54
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x58
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x5c
+#define QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0 0x60
+#define QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0 0x64
+#define QSERDES_V6_COM_CP_CTRL_MODE0 0x70
+#define QSERDES_V6_COM_PLL_RCTRL_MODE0 0x74
+#define QSERDES_V6_COM_PLL_CCTRL_MODE0 0x78
+#define QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0 0x7c
+#define QSERDES_V6_COM_LOCK_CMP1_MODE0 0x80
+#define QSERDES_V6_COM_LOCK_CMP2_MODE0 0x84
+#define QSERDES_V6_COM_DEC_START_MODE0 0x88
+#define QSERDES_V6_COM_DEC_START_MSB_MODE0 0x8c
+#define QSERDES_V6_COM_DIV_FRAC_START1_MODE0 0x90
+#define QSERDES_V6_COM_DIV_FRAC_START2_MODE0 0x94
+#define QSERDES_V6_COM_DIV_FRAC_START3_MODE0 0x98
+#define QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1 0x9c
+#define QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0 0xa0
+#define QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0 0xa4
+#define QSERDES_V6_COM_VCO_TUNE1_MODE0 0xa8
+#define QSERDES_V6_COM_VCO_TUNE2_MODE0 0xac
+#define QSERDES_V6_COM_BG_TIMER 0xbc
+#define QSERDES_V6_COM_SSC_EN_CENTER 0xc0
+#define QSERDES_V6_COM_SSC_PER1 0xcc
+#define QSERDES_V6_COM_SSC_PER2 0xd0
+#define QSERDES_V6_COM_PLL_POST_DIV_MUX 0xd8
+#define QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN 0xdc
+#define QSERDES_V6_COM_CLK_ENABLE1 0xe0
+#define QSERDES_V6_COM_SYS_CLK_CTRL 0xe4
+#define QSERDES_V6_COM_SYSCLK_BUF_ENABLE 0xe8
+#define QSERDES_V6_COM_PLL_IVCO 0xf4
+#define QSERDES_V6_COM_SYSCLK_EN_SEL 0x110
+#define QSERDES_V6_COM_RESETSM_CNTRL 0x118
+#define QSERDES_V6_COM_LOCK_CMP_EN 0x120
+#define QSERDES_V6_COM_LOCK_CMP_CFG 0x124
+#define QSERDES_V6_COM_VCO_TUNE_CTRL 0x13c
+#define QSERDES_V6_COM_VCO_TUNE_MAP 0x140
+#define QSERDES_V6_COM_VCO_TUNE_INITVAL2 0x148
+#define QSERDES_V6_COM_CLK_SELECT 0x164
+#define QSERDES_V6_COM_CORE_CLK_EN 0x170
+#define QSERDES_V6_COM_CMN_CONFIG_1 0x174
+#define QSERDES_V6_COM_SVS_MODE_CLK_SEL 0x17c
+#define QSERDES_V6_COM_CMN_MISC_1 0x184
+#define QSERDES_V6_COM_CMN_MODE 0x188
+#define QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL 0x198
+#define QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
+#define QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
+#define QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
+#define QSERDES_V6_COM_ADDITIONAL_MISC 0x1b4
+#define QSERDES_V6_COM_ADDITIONAL_MISC_2 0x1b8
+#define QSERDES_V6_COM_ADDITIONAL_MISC_3 0x1bc
+#define QSERDES_V6_COM_CMN_STATUS 0x1d0
+#define QSERDES_V6_COM_C_READY_STATUS 0x1f8
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com.h
index fbaf6ef467f8..7fa5363feeb9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com.h
@@ -135,6 +135,6 @@
#define QSERDES_COM_CMN_MISC2 0x1b8
#define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
#define QSERDES_COM_CORECLK_DIV_MODE2 0x1c0
-#define QSERDES_COM_CMN_RSVD5 0x1c0
+#define QSERDES_COM_CMN_RSVD5 0x1c4
#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-ln-shrd-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-ln-shrd-v6.h
new file mode 100644
index 000000000000..86d7d796d5d7
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-ln-shrd-v6.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_LN_SHRD_V6_H_
+#define QCOM_PHY_QMP_QSERDES_LN_SHRD_V6_H_
+
+#define QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL 0xa0
+#define QSERDES_V6_LN_SHRD_RX_Q_EN_RATES 0xb0
+#define QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1 0xb4
+#define QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1 0xc4
+#define QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2 0xc8
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0 0xd4
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1 0xd8
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2 0xdc
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3 0xe0
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4 0xe4
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5 0xe8
+#define QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6 0xec
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210 0xf0
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3 0xf4
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210 0xf8
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3 0xfc
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210 0x100
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3 0x104
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3 0x10c
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3 0x114
+#define QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3 0x11c
+#define QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE 0x128
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
new file mode 100644
index 000000000000..15bcb4ba9139
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_UFS_V6_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_UFS_V6_H_
+
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_TX 0x28
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX 0x2c
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX 0x30
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX 0x34
+
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2 0x08
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4 0x10
+#define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL 0x178
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0 0x208
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1 0x20c
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3 0x214
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6 0x220
+#define QSERDES_UFS_V6_RX_MODE_RATE2_B3 0x238
+#define QSERDES_UFS_V6_RX_MODE_RATE2_B6 0x244
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B3 0x25c
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B4 0x260
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B5 0x264
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B8 0x270
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B3 0x280
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B6 0x28c
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_5nm.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_5nm.h
index a1c088bd5158..a4a4e251348d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_5nm.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_5nm.h
@@ -7,11 +7,6 @@
#define QCOM_PHY_QMP_QSERDES_TXRX_V5_5NM_H_
/* Only for QMP V5 5NM PHY - TX registers */
-#define QSERDES_V5_5NM_TX_RES_CODE_LANE_OFFSET_TX 0x30
-#define QSERDES_V5_5NM_TX_RES_CODE_LANE_OFFSET_RX 0x34
-#define QSERDES_V5_5NM_TX_LANE_MODE_1 0x78
-#define QSERDES_V5_5NM_TX_LANE_MODE_2 0x7c
-#define QSERDES_V5_5NM_TX_LANE_MODE_3 0x80
#define QSERDES_V5_5NM_TX_BIST_MODE_LANENO 0x00
#define QSERDES_V5_5NM_TX_BIST_INVERT 0x04
#define QSERDES_V5_5NM_TX_CLKBUF_ENABLE 0x08
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6.h
new file mode 100644
index 000000000000..a69233e68f9a
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_USB_V6_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_USB_V6_H_
+
+#define QSERDES_V6_TX_CLKBUF_ENABLE 0x08
+#define QSERDES_V6_TX_RESET_TSYNC_EN 0x1c
+#define QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN 0x20
+#define QSERDES_V6_TX_TX_BAND 0x24
+#define QSERDES_V6_TX_INTERFACE_SELECT 0x2c
+#define QSERDES_V6_TX_RES_CODE_LANE_TX 0x34
+#define QSERDES_V6_TX_RES_CODE_LANE_RX 0x38
+#define QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX 0x3c
+#define QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX 0x40
+#define QSERDES_V6_TX_PARRATE_REC_DETECT_IDLE_EN 0x60
+#define QSERDES_V6_TX_BIST_PATTERN7 0x7c
+#define QSERDES_V6_TX_LANE_MODE_1 0x84
+#define QSERDES_V6_TX_LANE_MODE_3 0x8c
+#define QSERDES_V6_TX_LANE_MODE_4 0x90
+#define QSERDES_V6_TX_LANE_MODE_5 0x94
+#define QSERDES_V6_TX_RCV_DETECT_LVL_2 0xa4
+#define QSERDES_V6_TX_TRAN_DRVR_EMP_EN 0xc0
+#define QSERDES_V6_TX_TX_INTERFACE_MODE 0xc4
+#define QSERDES_V6_TX_VMODE_CTRL1 0xc8
+#define QSERDES_V6_TX_PI_QEC_CTRL 0xe4
+
+#define QSERDES_V6_RX_UCDR_FO_GAIN 0x08
+#define QSERDES_V6_RX_UCDR_SO_GAIN 0x14
+#define QSERDES_V6_RX_UCDR_FASTLOCK_FO_GAIN 0x30
+#define QSERDES_V6_RX_UCDR_SO_SATURATION_AND_ENABLE 0x34
+#define QSERDES_V6_RX_UCDR_FASTLOCK_COUNT_LOW 0x3c
+#define QSERDES_V6_RX_UCDR_FASTLOCK_COUNT_HIGH 0x40
+#define QSERDES_V6_RX_UCDR_PI_CONTROLS 0x44
+#define QSERDES_V6_RX_UCDR_SB2_THRESH1 0x4c
+#define QSERDES_V6_RX_UCDR_SB2_THRESH2 0x50
+#define QSERDES_V6_RX_UCDR_SB2_GAIN1 0x54
+#define QSERDES_V6_RX_UCDR_SB2_GAIN2 0x58
+#define QSERDES_V6_RX_AUX_DATA_TCOARSE_TFINE 0x60
+#define QSERDES_V6_RX_TX_ADAPT_POST_THRESH 0xcc
+#define QSERDES_V6_RX_VGA_CAL_CNTRL1 0xd4
+#define QSERDES_V6_RX_VGA_CAL_CNTRL2 0xd8
+#define QSERDES_V6_RX_GM_CAL 0xdc
+#define QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL2 0xec
+#define QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL3 0xf0
+#define QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL4 0xf4
+#define QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW 0xf8
+#define QSERDES_V6_RX_RX_IDAC_TSETTLE_HIGH 0xfc
+#define QSERDES_V6_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
+#define QSERDES_V6_RX_SIDGET_ENABLES 0x118
+#define QSERDES_V6_RX_SIGDET_CNTRL 0x11c
+#define QSERDES_V6_RX_SIGDET_DEGLITCH_CNTRL 0x124
+#define QSERDES_V6_RX_RX_MODE_00_LOW 0x15c
+#define QSERDES_V6_RX_RX_MODE_00_HIGH 0x160
+#define QSERDES_V6_RX_RX_MODE_00_HIGH2 0x164
+#define QSERDES_V6_RX_RX_MODE_00_HIGH3 0x168
+#define QSERDES_V6_RX_RX_MODE_00_HIGH4 0x16c
+#define QSERDES_V6_RX_RX_MODE_01_LOW 0x170
+#define QSERDES_V6_RX_RX_MODE_01_HIGH 0x174
+#define QSERDES_V6_RX_RX_MODE_01_HIGH2 0x178
+#define QSERDES_V6_RX_RX_MODE_01_HIGH3 0x17c
+#define QSERDES_V6_RX_RX_MODE_01_HIGH4 0x180
+#define QSERDES_V6_RX_RX_MODE_10_LOW 0x184
+#define QSERDES_V6_RX_RX_MODE_10_HIGH 0x188
+#define QSERDES_V6_RX_RX_MODE_10_HIGH2 0x18c
+#define QSERDES_V6_RX_RX_MODE_10_HIGH3 0x190
+#define QSERDES_V6_RX_RX_MODE_10_HIGH4 0x194
+#define QSERDES_V6_RX_DFE_EN_TIMER 0x1a0
+#define QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET 0x1a4
+#define QSERDES_V6_RX_DCC_CTRL1 0x1a8
+#define QSERDES_V6_RX_VTH_CODE 0x1b0
+#define QSERDES_V6_RX_SIGDET_CAL_CTRL1 0x1e4
+#define QSERDES_V6_RX_SIGDET_CAL_TRIM 0x1f8
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h
new file mode 100644
index 000000000000..5385a8b60970
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V6_20_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V6_20_H_
+
+#define QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX 0x30
+#define QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX 0x34
+#define QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN 0xac
+#define QSERDES_V6_20_TX_LANE_MODE_1 0x78
+#define QSERDES_V6_20_TX_LANE_MODE_2 0x7c
+#define QSERDES_V6_20_TX_LANE_MODE_3 0x80
+
+#define QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2 0x08
+#define QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3 0x0c
+#define QSERDES_V6_20_RX_UCDR_PI_CONTROLS 0x20
+#define QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3 0x34
+#define QSERDES_V6_20_RX_IVCM_CAL_CTRL2 0x9c
+#define QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET 0xa0
+#define QSERDES_V6_20_RX_DFE_3 0xb4
+#define QSERDES_V6_20_RX_VGA_CAL_MAN_VAL 0xe8
+#define QSERDES_V6_20_RX_GM_CAL 0x10c
+#define QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4 0x120
+#define QSERDES_V6_20_RX_SIGDET_ENABLES 0x148
+#define QSERDES_V6_20_RX_PHPRE_CTRL 0x188
+#define QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET 0x194
+#define QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32 0x1dc
+#define QSERDES_V6_20_RX_MODE_RATE2_B0 0x1f4
+#define QSERDES_V6_20_RX_MODE_RATE2_B1 0x1f8
+#define QSERDES_V6_20_RX_MODE_RATE2_B2 0x1fc
+#define QSERDES_V6_20_RX_MODE_RATE2_B3 0x200
+#define QSERDES_V6_20_RX_MODE_RATE2_B4 0x204
+#define QSERDES_V6_20_RX_MODE_RATE2_B5 0x208
+#define QSERDES_V6_20_RX_MODE_RATE2_B6 0x20c
+#define QSERDES_V6_20_RX_MODE_RATE3_B0 0x210
+#define QSERDES_V6_20_RX_MODE_RATE3_B1 0x214
+#define QSERDES_V6_20_RX_MODE_RATE3_B2 0x218
+#define QSERDES_V6_20_RX_MODE_RATE3_B3 0x21c
+#define QSERDES_V6_20_RX_MODE_RATE3_B4 0x220
+#define QSERDES_V6_20_RX_MODE_RATE3_B5 0x224
+#define QSERDES_V6_20_RX_MODE_RATE3_B6 0x228
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 318eea35b972..994ddd5d4a81 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -20,7 +20,15 @@
#include <linux/reset.h>
#include <linux/slab.h>
+#include <ufs/unipro.h>
#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-ufs-v2.h"
+#include "phy-qcom-qmp-pcs-ufs-v3.h"
+#include "phy-qcom-qmp-pcs-ufs-v4.h"
+#include "phy-qcom-qmp-pcs-ufs-v5.h"
+#include "phy-qcom-qmp-pcs-ufs-v6.h"
+
+#include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -69,32 +77,40 @@ enum qphy_reg_layout {
QPHY_LAYOUT_SIZE
};
-static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_START_CTRL] = 0x00,
- [QPHY_PCS_READY_STATUS] = 0x168,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
-};
-
-static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_START_CTRL] = 0x00,
- [QPHY_PCS_READY_STATUS] = 0x160,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
+static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V2_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V2_PCS_UFS_READY_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL,
};
-static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_START_CTRL] = 0x00,
- [QPHY_PCS_READY_STATUS] = 0x168,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
+static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL,
};
-static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
+static const unsigned int ufsphy_v4_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START,
[QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS,
[QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET,
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL,
};
-static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
+static const unsigned int ufsphy_v5_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V5_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V5_PCS_UFS_READY_STATUS,
+ [QPHY_SW_RESET] = QPHY_V5_PCS_UFS_SW_RESET,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V5_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
+static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V6_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V6_PCS_UFS_READY_STATUS,
+ [QPHY_SW_RESET] = QPHY_V6_PCS_UFS_SW_RESET,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
+static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
@@ -143,12 +159,12 @@ static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
};
-static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
+static const struct qmp_phy_init_tbl msm8996_ufsphy_tx[] = {
QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
};
-static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
+static const struct qmp_phy_init_tbl msm8996_ufsphy_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
@@ -162,7 +178,7 @@ static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
};
-static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
+static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes[] = {
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),
@@ -213,17 +229,18 @@ static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
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 */
+static const struct qmp_phy_init_tbl sm6115_ufsphy_hs_b_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
};
-static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
+static const struct qmp_phy_init_tbl sm6115_ufsphy_tx[] = {
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[] = {
+static const struct qmp_phy_init_tbl sm6115_ufsphy_rx[] = {
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),
@@ -241,19 +258,19 @@ static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
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_V2_PCS_RX_PWM_GEAR_BAND, 0x15),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_CTRL2, 0x6d),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SYM_RESYNC_CTRL, 0x03),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
- QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
+static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
};
-static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
+static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
@@ -290,18 +307,19 @@ static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
+};
- /* Rate B */
+static const struct qmp_phy_init_tbl sdm845_ufsphy_hs_b_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
};
-static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
+static const struct qmp_phy_init_tbl sdm845_ufsphy_tx[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
};
-static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
+static const struct qmp_phy_init_tbl sdm845_ufsphy_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
@@ -320,7 +338,7 @@ static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
};
-static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
+static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
@@ -331,7 +349,7 @@ static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
};
-static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
+static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
@@ -356,12 +374,13 @@ static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
+};
- /* Rate B */
+static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_b_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
};
-static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
+static const struct qmp_phy_init_tbl sm8150_ufsphy_tx[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
@@ -370,7 +389,11 @@ static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
};
-static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
+static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x75),
+};
+
+static const struct qmp_phy_init_tbl sm8150_ufsphy_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
@@ -405,10 +428,28 @@ static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
+};
+static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
+ 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, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x6c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
};
-static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
+static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
@@ -418,7 +459,40 @@ static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
};
-static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
+static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
+};
+
+static const struct qmp_phy_init_tbl sm8250_ufsphy_hs_g4_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5),
+};
+
+static const struct qmp_phy_init_tbl sm8250_ufsphy_hs_g4_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
+ 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, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
+};
+
+static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
@@ -443,12 +517,13 @@ static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
+};
- /* Rate B */
+static const struct qmp_phy_init_tbl sm8350_ufsphy_hs_b_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
};
-static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
+static const struct qmp_phy_init_tbl sm8350_ufsphy_tx[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
@@ -460,7 +535,7 @@ static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
};
-static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
+static const struct qmp_phy_init_tbl sm8350_ufsphy_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
@@ -500,24 +575,100 @@ static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
};
-static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
+static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
- QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
};
+static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xe5),
+};
+
+static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x81),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x6f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x2d),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xed),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0x3c),
+};
+
+static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
+
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
+
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
+
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+};
+
struct qmp_ufs_offsets {
u16 serdes;
u16 pcs;
@@ -527,21 +678,30 @@ struct qmp_ufs_offsets {
u16 rx2;
};
+struct qmp_phy_cfg_tbls {
+ /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
+ const struct qmp_phy_init_tbl *serdes;
+ int serdes_num;
+ const struct qmp_phy_init_tbl *tx;
+ int tx_num;
+ const struct qmp_phy_init_tbl *rx;
+ int rx_num;
+ const struct qmp_phy_init_tbl *pcs;
+ int pcs_num;
+};
+
/* struct qmp_phy_cfg - per-PHY initialization config */
struct qmp_phy_cfg {
int lanes;
const struct qmp_ufs_offsets *offsets;
- /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
- const struct qmp_phy_init_tbl *serdes_tbl;
- int serdes_tbl_num;
- const struct qmp_phy_init_tbl *tx_tbl;
- int tx_tbl_num;
- const struct qmp_phy_init_tbl *rx_tbl;
- int rx_tbl_num;
- const struct qmp_phy_init_tbl *pcs_tbl;
- int pcs_tbl_num;
+ /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
+ const struct qmp_phy_cfg_tbls tbls;
+ /* Additional sequence for HS Series B */
+ const struct qmp_phy_cfg_tbls tbls_hs_b;
+ /* Additional sequence for HS G4 */
+ const struct qmp_phy_cfg_tbls tbls_hs_g4;
/* clock ids to be requested */
const char * const *clk_list;
@@ -575,6 +735,8 @@ struct qmp_ufs {
struct reset_control *ufs_reset;
struct phy *phy;
+ u32 mode;
+ u32 submode;
};
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -620,7 +782,7 @@ static const char * const qmp_phy_vreg_l[] = {
"vdda-phy", "vdda-pll",
};
-static const struct qmp_ufs_offsets qmp_ufs_offsets_v5 = {
+static const struct qmp_ufs_offsets qmp_ufs_offsets = {
.serdes = 0,
.pcs = 0xc00,
.tx = 0x400,
@@ -629,15 +791,26 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v5 = {
.rx2 = 0xa00,
};
-static const struct qmp_phy_cfg msm8996_ufs_cfg = {
+static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
+ .serdes = 0,
+ .pcs = 0x0400,
+ .tx = 0x1000,
+ .rx = 0x1200,
+ .tx2 = 0x1800,
+ .rx2 = 0x1a00,
+};
+
+static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
.lanes = 1,
- .serdes_tbl = msm8996_ufs_serdes_tbl,
- .serdes_tbl_num = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
- .tx_tbl = msm8996_ufs_tx_tbl,
- .tx_tbl_num = ARRAY_SIZE(msm8996_ufs_tx_tbl),
- .rx_tbl = msm8996_ufs_rx_tbl,
- .rx_tbl_num = ARRAY_SIZE(msm8996_ufs_rx_tbl),
+ .tbls = {
+ .serdes = msm8996_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(msm8996_ufsphy_serdes),
+ .tx = msm8996_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(msm8996_ufsphy_tx),
+ .rx = msm8996_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(msm8996_ufsphy_rx),
+ },
.clk_list = msm8996_ufs_phy_clk_l,
.num_clks = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
@@ -645,7 +818,7 @@ static const struct qmp_phy_cfg msm8996_ufs_cfg = {
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = msm8996_ufsphy_regs_layout,
+ .regs = ufsphy_v2_regs_layout,
.no_pcs_sw_reset = true,
};
@@ -653,39 +826,59 @@ static const struct qmp_phy_cfg msm8996_ufs_cfg = {
static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
.lanes = 2,
- .offsets = &qmp_ufs_offsets_v5,
-
- .serdes_tbl = sm8350_ufsphy_serdes_tbl,
- .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
- .tx_tbl = sm8350_ufsphy_tx_tbl,
- .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
- .rx_tbl = sm8350_ufsphy_rx_tbl,
- .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
- .pcs_tbl = sm8350_ufsphy_pcs_tbl,
- .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
+ .offsets = &qmp_ufs_offsets,
+
+ .tbls = {
+ .serdes = sm8350_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
+ .tx = sm8350_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
+ .rx = sm8350_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
+ .pcs = sm8350_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8350_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
+ },
+ .tbls_hs_g4 = {
+ .tx = sm8350_ufsphy_g4_tx,
+ .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
+ .rx = sm8350_ufsphy_g4_rx,
+ .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
+ .pcs = sm8350_ufsphy_g4_pcs,
+ .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+ },
.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 = sm8150_ufsphy_regs_layout,
+ .regs = ufsphy_v5_regs_layout,
};
static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
.lanes = 2,
- .serdes_tbl = sdm845_ufsphy_serdes_tbl,
- .serdes_tbl_num = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
- .tx_tbl = sdm845_ufsphy_tx_tbl,
- .tx_tbl_num = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
- .rx_tbl = sdm845_ufsphy_rx_tbl,
- .rx_tbl_num = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
- .pcs_tbl = sdm845_ufsphy_pcs_tbl,
- .pcs_tbl_num = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
+ .tbls = {
+ .serdes = sdm845_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes),
+ .tx = sdm845_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx),
+ .rx = sdm845_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sdm845_ufsphy_rx),
+ .pcs = sdm845_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sdm845_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sdm845_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
+ },
.clk_list = sdm845_ufs_phy_clk_l,
.num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sdm845_ufsphy_regs_layout,
+ .regs = ufsphy_v3_regs_layout,
.no_pcs_sw_reset = true,
};
@@ -693,19 +886,27 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
.lanes = 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),
+ .offsets = &qmp_ufs_offsets,
+
+ .tbls = {
+ .serdes = sm6115_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm6115_ufsphy_serdes),
+ .tx = sm6115_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm6115_ufsphy_tx),
+ .rx = sm6115_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm6115_ufsphy_rx),
+ .pcs = sm6115_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm6115_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm6115_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),
+ },
.clk_list = sdm845_ufs_phy_clk_l,
.num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm6115_ufsphy_regs_layout,
+ .regs = ufsphy_v2_regs_layout,
.no_pcs_sw_reset = true,
};
@@ -713,55 +914,151 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
.lanes = 2,
- .serdes_tbl = sm8150_ufsphy_serdes_tbl,
- .serdes_tbl_num = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
- .tx_tbl = sm8150_ufsphy_tx_tbl,
- .tx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
- .rx_tbl = sm8150_ufsphy_rx_tbl,
- .rx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
- .pcs_tbl = sm8150_ufsphy_pcs_tbl,
- .pcs_tbl_num = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
+ .tbls = {
+ .serdes = sm8150_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
+ .tx = sm8150_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
+ .rx = sm8150_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
+ .pcs = sm8150_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8150_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
+ },
+ .tbls_hs_g4 = {
+ .tx = sm8150_ufsphy_hs_g4_tx,
+ .tx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_tx),
+ .rx = sm8150_ufsphy_hs_g4_rx,
+ .rx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_rx),
+ .pcs = sm8150_ufsphy_hs_g4_pcs,
+ .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = ufsphy_v4_regs_layout,
+};
+
+static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {
+ .lanes = 2,
+
+ .tbls = {
+ .serdes = sm8150_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
+ .tx = sm8150_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
+ .rx = sm8150_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
+ .pcs = sm8150_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8150_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
+ },
+ .tbls_hs_g4 = {
+ .tx = sm8250_ufsphy_hs_g4_tx,
+ .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
+ .rx = sm8250_ufsphy_hs_g4_rx,
+ .rx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),
+ .pcs = sm8150_ufsphy_hs_g4_pcs,
+ .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
+ },
.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 = sm8150_ufsphy_regs_layout,
+ .regs = ufsphy_v4_regs_layout,
};
static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
.lanes = 2,
- .serdes_tbl = sm8350_ufsphy_serdes_tbl,
- .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
- .tx_tbl = sm8350_ufsphy_tx_tbl,
- .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
- .rx_tbl = sm8350_ufsphy_rx_tbl,
- .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
- .pcs_tbl = sm8350_ufsphy_pcs_tbl,
- .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
+ .tbls = {
+ .serdes = sm8350_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
+ .tx = sm8350_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
+ .rx = sm8350_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
+ .pcs = sm8350_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8350_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
+ },
+ .tbls_hs_g4 = {
+ .tx = sm8350_ufsphy_g4_tx,
+ .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
+ .rx = sm8350_ufsphy_g4_rx,
+ .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
+ .pcs = sm8350_ufsphy_g4_pcs,
+ .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+ },
.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 = sm8150_ufsphy_regs_layout,
+ .regs = ufsphy_v5_regs_layout,
};
static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
.lanes = 2,
- .serdes_tbl = sm8350_ufsphy_serdes_tbl,
- .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
- .tx_tbl = sm8350_ufsphy_tx_tbl,
- .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
- .rx_tbl = sm8350_ufsphy_rx_tbl,
- .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
- .pcs_tbl = sm8350_ufsphy_pcs_tbl,
- .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
+ .tbls = {
+ .serdes = sm8350_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
+ .tx = sm8350_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
+ .rx = sm8350_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
+ .pcs = sm8350_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8350_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
+ },
+ .tbls_hs_g4 = {
+ .tx = sm8350_ufsphy_g4_tx,
+ .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
+ .rx = sm8350_ufsphy_g4_rx,
+ .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
+ .pcs = sm8350_ufsphy_g4_pcs,
+ .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
+ },
.clk_list = sm8450_ufs_phy_clk_l,
.num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = sm8150_ufsphy_regs_layout,
+ .regs = ufsphy_v5_regs_layout,
+};
+
+static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_ufs_offsets_v6,
+
+ .tbls = {
+ .serdes = sm8550_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8550_ufsphy_serdes),
+ .tx = sm8550_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
+ .rx = sm8550_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
+ .pcs = sm8550_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = ufsphy_v6_regs_layout,
};
static void qmp_ufs_configure_lane(void __iomem *base,
@@ -790,16 +1087,46 @@ static void qmp_ufs_configure(void __iomem *base,
qmp_ufs_configure_lane(base, tbl, num, 0xff);
}
-static int qmp_ufs_serdes_init(struct qmp_ufs *qmp)
+static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
- const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *serdes = qmp->serdes;
- const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
- int serdes_tbl_num = cfg->serdes_tbl_num;
- qmp_ufs_configure(serdes, serdes_tbl, serdes_tbl_num);
+ qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);
+}
- return 0;
+static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
+{
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ void __iomem *tx = qmp->tx;
+ void __iomem *rx = qmp->rx;
+
+ qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
+ qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
+
+ if (cfg->lanes >= 2) {
+ qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
+ qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
+ }
+}
+
+static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
+{
+ void __iomem *pcs = qmp->pcs;
+
+ qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);
+}
+
+static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
+{
+ qmp_ufs_serdes_init(qmp, &cfg->tbls);
+ if (qmp->mode == PHY_MODE_UFS_HS_B)
+ qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
+ qmp_ufs_lanes_init(qmp, &cfg->tbls);
+ if (qmp->submode == UFS_HS_G4)
+ qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4);
+ qmp_ufs_pcs_init(qmp, &cfg->tbls);
+ if (qmp->submode == UFS_HS_G4)
+ qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4);
}
static int qmp_ufs_com_init(struct qmp_ufs *qmp)
@@ -886,25 +1213,12 @@ static int qmp_ufs_power_on(struct phy *phy)
{
struct qmp_ufs *qmp = phy_get_drvdata(phy);
const struct qmp_phy_cfg *cfg = qmp->cfg;
- void __iomem *tx = qmp->tx;
- void __iomem *rx = qmp->rx;
void __iomem *pcs = qmp->pcs;
void __iomem *status;
unsigned int val;
int ret;
- qmp_ufs_serdes_init(qmp);
-
- /* Tx, Rx, and PCS configurations */
- qmp_ufs_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
- qmp_ufs_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
-
- if (cfg->lanes >= 2) {
- qmp_ufs_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
- qmp_ufs_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
- }
-
- qmp_ufs_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+ qmp_ufs_init_registers(qmp, cfg);
ret = reset_control_deassert(qmp->ufs_reset);
if (ret)
@@ -981,9 +1295,20 @@ static int qmp_ufs_disable(struct phy *phy)
return qmp_ufs_exit(phy);
}
+static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+ struct qmp_ufs *qmp = phy_get_drvdata(phy);
+
+ qmp->mode = mode;
+ qmp->submode = submode;
+
+ return 0;
+}
+
static const struct phy_ops qcom_qmp_ufs_phy_ops = {
.power_on = qmp_ufs_enable,
.power_off = qmp_ufs_disable,
+ .set_mode = qmp_ufs_set_mode,
.owner = THIS_MODULE,
};
@@ -1021,6 +1346,59 @@ static int qmp_ufs_clk_init(struct qmp_ufs *qmp)
return devm_clk_bulk_get(dev, num, qmp->clks);
}
+static void qmp_ufs_clk_release_provider(void *res)
+{
+ of_clk_del_provider(res);
+}
+
+#define UFS_SYMBOL_CLOCKS 3
+
+static int qmp_ufs_register_clocks(struct qmp_ufs *qmp, struct device_node *np)
+{
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_hw *hw;
+ char name[64];
+ int ret;
+
+ clk_data = devm_kzalloc(qmp->dev,
+ struct_size(clk_data, hws, UFS_SYMBOL_CLOCKS),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = UFS_SYMBOL_CLOCKS;
+
+ snprintf(name, sizeof(name), "%s::rx_symbol_0", dev_name(qmp->dev));
+ hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ clk_data->hws[0] = hw;
+
+ snprintf(name, sizeof(name), "%s::rx_symbol_1", dev_name(qmp->dev));
+ hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ clk_data->hws[1] = hw;
+
+ snprintf(name, sizeof(name), "%s::tx_symbol_0", dev_name(qmp->dev));
+ hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ clk_data->hws[2] = hw;
+
+ ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+ if (ret)
+ return ret;
+
+ /*
+ * Roll a devm action because the clock provider can be a child node.
+ */
+ return devm_add_action_or_reset(qmp->dev, qmp_ufs_clk_release_provider, np);
+}
+
static int qmp_ufs_parse_dt_legacy(struct qmp_ufs *qmp, struct device_node *np)
{
struct platform_device *pdev = to_platform_device(qmp->dev);
@@ -1133,6 +1511,10 @@ static int qmp_ufs_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ ret = qmp_ufs_register_clocks(qmp, np);
+ if (ret)
+ goto err_node_put;
+
qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops);
if (IS_ERR(qmp->phy)) {
ret = PTR_ERR(qmp->phy);
@@ -1156,7 +1538,7 @@ err_node_put:
static const struct of_device_id qmp_ufs_of_match_table[] = {
{
.compatible = "qcom,msm8996-qmp-ufs-phy",
- .data = &msm8996_ufs_cfg,
+ .data = &msm8996_ufsphy_cfg,
}, {
.compatible = "qcom,msm8998-qmp-ufs-phy",
.data = &sdm845_ufsphy_cfg,
@@ -1173,6 +1555,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
.compatible = "qcom,sm6115-qmp-ufs-phy",
.data = &sm6115_ufsphy_cfg,
}, {
+ .compatible = "qcom,sm6125-qmp-ufs-phy",
+ .data = &sm6115_ufsphy_cfg,
+ }, {
.compatible = "qcom,sm6350-qmp-ufs-phy",
.data = &sdm845_ufsphy_cfg,
}, {
@@ -1180,13 +1565,16 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
.data = &sm8150_ufsphy_cfg,
}, {
.compatible = "qcom,sm8250-qmp-ufs-phy",
- .data = &sm8150_ufsphy_cfg,
+ .data = &sm8250_ufsphy_cfg,
}, {
.compatible = "qcom,sm8350-qmp-ufs-phy",
.data = &sm8350_ufsphy_cfg,
}, {
.compatible = "qcom,sm8450-qmp-ufs-phy",
.data = &sm8450_ufsphy_cfg,
+ }, {
+ .compatible = "qcom,sm8550-qmp-ufs-phy",
+ .data = &sm8550_ufsphy_cfg,
},
{ },
};
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index 4aa338fc4643..a49711c5a63d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -21,6 +21,9 @@
#include <linux/slab.h>
#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-misc-v3.h"
+#include "phy-qcom-qmp-pcs-usb-v4.h"
+#include "phy-qcom-qmp-pcs-usb-v5.h"
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -54,9 +57,6 @@
/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
#define IRQ_CLEAR BIT(0)
-/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
-#define RCVR_DETECT BIT(0)
-
/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
#define CLAMP_EN BIT(0) /* enables i/o clamp_n */
@@ -94,53 +94,49 @@ enum qphy_reg_layout {
QPHY_PCS_STATUS,
QPHY_PCS_AUTONOMOUS_MODE_CTRL,
QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
- QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
QPHY_PCS_POWER_DOWN_CONTROL,
- /* PCS_MISC registers */
- QPHY_PCS_MISC_TYPEC_CTRL,
/* Keep last to ensure regs_layout arrays are properly initialized */
QPHY_LAYOUT_SIZE
};
-static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_STATUS] = 0x17c,
- [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
- [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0d8,
- [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
+static const unsigned int qmp_v2_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V2_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V2_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V2_PCS_USB_PCS_STATUS,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V2_PCS_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V2_PCS_LFPS_RXTERM_IRQ_CLEAR,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_POWER_DOWN_CONTROL,
};
static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_STATUS] = 0x174,
- [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
- [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0dc,
- [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
+ [QPHY_SW_RESET] = QPHY_V3_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V3_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V3_PCS_PCS_STATUS,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL,
};
static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_START_CTRL] = 0x44,
- [QPHY_PCS_STATUS] = 0x14,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40,
+ [QPHY_SW_RESET] = QPHY_V4_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V4_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V4_PCS_PCS_STATUS1,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_POWER_DOWN_CONTROL,
/* In PCS_USB */
- [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x008,
- [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x014,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
};
-static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
- [QPHY_SW_RESET] = 0x00,
- [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04,
- [QPHY_START_CTRL] = 0x08,
- [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0xd8,
- [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0xdc,
- [QPHY_PCS_STATUS] = 0x174,
- [QPHY_PCS_MISC_TYPEC_CTRL] = 0x00,
+static const unsigned int qmp_v5_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V5_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V5_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V5_PCS_PCS_STATUS1,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V5_PCS_POWER_DOWN_CONTROL,
+
+ /* In PCS_USB */
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
};
static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
@@ -1265,7 +1261,7 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
- QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
@@ -1607,7 +1603,7 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = usb3phy_regs_layout,
+ .regs = qmp_v2_usb3phy_regs_layout,
};
static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
@@ -1675,7 +1671,7 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = {
.num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = qmp_v4_usb3phy_regs_layout,
+ .regs = qmp_v5_usb3phy_regs_layout,
};
static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
@@ -1866,7 +1862,7 @@ static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = qmp_v4_usb3phy_regs_layout,
+ .regs = qmp_v5_usb3phy_regs_layout,
.pcs_usb_offset = 0x1000,
.has_pwrdn_delay = true,
@@ -1891,7 +1887,7 @@ static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = qmp_v4_usb3phy_regs_layout,
+ .regs = qmp_v5_usb3phy_regs_layout,
.pcs_usb_offset = 0x300,
.has_pwrdn_delay = true,
@@ -1917,7 +1913,7 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = qmp_v4_usb3phy_regs_layout,
+ .regs = qmp_v5_usb3phy_regs_layout,
.pcs_usb_offset = 0x1000,
.has_pwrdn_delay = true,
@@ -1940,7 +1936,7 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
.num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
- .regs = qcm2290_usb3phy_regs_layout,
+ .regs = qmp_v3_usb3phy_regs_layout,
};
static void qmp_usb_configure_lane(void __iomem *base,
@@ -2623,6 +2619,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
.compatible = "qcom,sdx65-qmp-usb3-uni-phy",
.data = &sdx65_usb3_uniphy_cfg,
}, {
+ .compatible = "qcom,sm6115-qmp-usb3-phy",
+ .data = &qcm2290_usb3phy_cfg,
+ }, {
.compatible = "qcom,sm8150-qmp-usb3-phy",
.data = &sm8150_usb3phy_cfg,
}, {
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index 29a48f0436d2..7ee4b0e07d11 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -21,31 +21,28 @@
#include "phy-qcom-qmp-qserdes-txrx-v5_20.h"
#include "phy-qcom-qmp-qserdes-txrx-v5_5nm.h"
+#include "phy-qcom-qmp-qserdes-com-v6.h"
+#include "phy-qcom-qmp-qserdes-txrx-v6.h"
+#include "phy-qcom-qmp-qserdes-txrx-v6_20.h"
+#include "phy-qcom-qmp-qserdes-ln-shrd-v6.h"
+
#include "phy-qcom-qmp-qserdes-pll.h"
#include "phy-qcom-qmp-pcs-v2.h"
#include "phy-qcom-qmp-pcs-v3.h"
-#include "phy-qcom-qmp-pcs-misc-v3.h"
-#include "phy-qcom-qmp-pcs-ufs-v3.h"
#include "phy-qcom-qmp-pcs-v4.h"
-#include "phy-qcom-qmp-pcs-pcie-v4.h"
-#include "phy-qcom-qmp-pcs-usb-v4.h"
-#include "phy-qcom-qmp-pcs-ufs-v4.h"
#include "phy-qcom-qmp-pcs-v4_20.h"
-#include "phy-qcom-qmp-pcs-pcie-v4_20.h"
#include "phy-qcom-qmp-pcs-v5.h"
+
#include "phy-qcom-qmp-pcs-v5_20.h"
-#include "phy-qcom-qmp-pcs-pcie-v5.h"
-#include "phy-qcom-qmp-pcs-usb-v5.h"
-#include "phy-qcom-qmp-pcs-ufs-v5.h"
-#include "phy-qcom-qmp-pcs-pcie-v5_20.h"
+#include "phy-qcom-qmp-pcs-v6.h"
-#include "phy-qcom-qmp-pcie-qhp.h"
+#include "phy-qcom-qmp-pcs-v6_20.h"
/* Only for QMP V3 & V4 PHY - DP COM registers */
#define QPHY_V3_DP_COM_PHY_MODE_CTRL 0x00
@@ -137,4 +134,8 @@
#define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10
#define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14
+/* Only for QMP V6 PHY - DP PHY registers */
+#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0
+#define QSERDES_V6_DP_PHY_STATUS 0x0e4
+
#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c
new file mode 100644
index 000000000000..eeaa1eb0e24b
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c
@@ -0,0 +1,441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+
+#define USB_PHY_UTMI_CTRL0 (0x3c)
+#define SLEEPM BIT(0)
+#define OPMODE_MASK GENMASK(4, 3)
+#define OPMODE_NONDRIVING BIT(3)
+
+#define USB_PHY_UTMI_CTRL5 (0x50)
+#define POR BIT(1)
+
+#define USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
+#define PHY_ENABLE BIT(0)
+#define SIDDQ_SEL BIT(1)
+#define SIDDQ BIT(2)
+#define RETENABLEN BIT(3)
+#define FSEL_MASK GENMASK(6, 4)
+#define FSEL_19_2_MHZ_VAL (0x0)
+#define FSEL_38_4_MHZ_VAL (0x4)
+
+#define USB_PHY_CFG_CTRL_1 (0x58)
+#define PHY_CFG_PLL_CPBIAS_CNTRL_MASK GENMASK(7, 1)
+
+#define USB_PHY_CFG_CTRL_2 (0x5c)
+#define PHY_CFG_PLL_FB_DIV_7_0_MASK GENMASK(7, 0)
+#define DIV_7_0_19_2_MHZ_VAL (0x90)
+#define DIV_7_0_38_4_MHZ_VAL (0xc8)
+
+#define USB_PHY_CFG_CTRL_3 (0x60)
+#define PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(3, 0)
+#define DIV_11_8_19_2_MHZ_VAL (0x1)
+#define DIV_11_8_38_4_MHZ_VAL (0x0)
+
+#define PHY_CFG_PLL_REF_DIV GENMASK(7, 4)
+#define PLL_REF_DIV_VAL (0x0)
+
+#define USB_PHY_HS_PHY_CTRL2 (0x64)
+#define VBUSVLDEXT0 BIT(0)
+#define USB2_SUSPEND_N BIT(2)
+#define USB2_SUSPEND_N_SEL BIT(3)
+#define VBUS_DET_EXT_SEL BIT(4)
+
+#define USB_PHY_CFG_CTRL_4 (0x68)
+#define PHY_CFG_PLL_GMP_CNTRL_MASK GENMASK(1, 0)
+#define PHY_CFG_PLL_INT_CNTRL_MASK GENMASK(7, 2)
+
+#define USB_PHY_CFG_CTRL_5 (0x6c)
+#define PHY_CFG_PLL_PROP_CNTRL_MASK GENMASK(4, 0)
+#define PHY_CFG_PLL_VREF_TUNE_MASK GENMASK(7, 6)
+
+#define USB_PHY_CFG_CTRL_6 (0x70)
+#define PHY_CFG_PLL_VCO_CNTRL_MASK GENMASK(2, 0)
+
+#define USB_PHY_CFG_CTRL_7 (0x74)
+
+#define USB_PHY_CFG_CTRL_8 (0x78)
+#define PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(1, 0)
+#define PHY_CFG_TX_FSLS_VREG_BYPASS BIT(2)
+#define PHY_CFG_TX_HS_VREF_TUNE_MASK GENMASK(5, 3)
+#define PHY_CFG_TX_HS_XV_TUNE_MASK GENMASK(7, 6)
+
+#define USB_PHY_CFG_CTRL_9 (0x7c)
+#define PHY_CFG_TX_PREEMP_TUNE_MASK GENMASK(2, 0)
+#define PHY_CFG_TX_RES_TUNE_MASK GENMASK(4, 3)
+#define PHY_CFG_TX_RISE_TUNE_MASK GENMASK(6, 5)
+#define PHY_CFG_RCAL_BYPASS BIT(7)
+
+#define USB_PHY_CFG_CTRL_10 (0x80)
+
+#define USB_PHY_CFG0 (0x94)
+#define DATAPATH_CTRL_OVERRIDE_EN BIT(0)
+#define CMN_CTRL_OVERRIDE_EN BIT(1)
+
+#define UTMI_PHY_CMN_CTRL0 (0x98)
+#define TESTBURNIN BIT(6)
+
+#define USB_PHY_FSEL_SEL (0xb8)
+#define FSEL_SEL BIT(0)
+
+#define USB_PHY_APB_ACCESS_CMD (0x130)
+#define RW_ACCESS BIT(0)
+#define APB_START_CMD BIT(1)
+#define APB_LOGIC_RESET BIT(2)
+
+#define USB_PHY_APB_ACCESS_STATUS (0x134)
+#define ACCESS_DONE BIT(0)
+#define TIMED_OUT BIT(1)
+#define ACCESS_ERROR BIT(2)
+#define ACCESS_IN_PROGRESS BIT(3)
+
+#define USB_PHY_APB_ADDRESS (0x138)
+#define APB_REG_ADDR_MASK GENMASK(7, 0)
+
+#define USB_PHY_APB_WRDATA_LSB (0x13c)
+#define APB_REG_WRDATA_7_0_MASK GENMASK(3, 0)
+
+#define USB_PHY_APB_WRDATA_MSB (0x140)
+#define APB_REG_WRDATA_15_8_MASK GENMASK(7, 4)
+
+#define USB_PHY_APB_RDDATA_LSB (0x144)
+#define APB_REG_RDDATA_7_0_MASK GENMASK(3, 0)
+
+#define USB_PHY_APB_RDDATA_MSB (0x148)
+#define APB_REG_RDDATA_15_8_MASK GENMASK(7, 4)
+
+static const char * const eusb2_hsphy_vreg_names[] = {
+ "vdd", "vdda12",
+};
+
+#define EUSB2_NUM_VREGS ARRAY_SIZE(eusb2_hsphy_vreg_names)
+
+struct qcom_snps_eusb2_hsphy {
+ struct phy *phy;
+ void __iomem *base;
+
+ struct clk *ref_clk;
+ struct reset_control *phy_reset;
+
+ struct regulator_bulk_data vregs[EUSB2_NUM_VREGS];
+
+ enum phy_mode mode;
+
+ struct phy *repeater;
+};
+
+static int qcom_snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode)
+{
+ struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
+
+ phy->mode = mode;
+
+ return phy_set_mode_ext(phy->repeater, mode, submode);
+}
+
+static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
+ u32 mask, u32 val)
+{
+ u32 reg;
+
+ reg = readl_relaxed(base + offset);
+ reg &= ~mask;
+ reg |= val & mask;
+ writel_relaxed(reg, base + offset);
+
+ /* Ensure above write is completed */
+ readl_relaxed(base + offset);
+}
+
+static void qcom_eusb2_default_parameters(struct qcom_snps_eusb2_hsphy *phy)
+{
+ /* default parameters: tx pre-emphasis */
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
+ PHY_CFG_TX_PREEMP_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0));
+
+ /* tx rise/fall time */
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
+ PHY_CFG_TX_RISE_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2));
+
+ /* source impedance adjustment */
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
+ PHY_CFG_TX_RES_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1));
+
+ /* dc voltage level adjustement */
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8,
+ PHY_CFG_TX_HS_VREF_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3));
+
+ /* transmitter HS crossover adjustement */
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8,
+ PHY_CFG_TX_HS_XV_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0));
+}
+
+static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy)
+{
+ unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk);
+
+ switch (ref_clk_freq) {
+ case 19200000:
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
+ FSEL_MASK,
+ FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2,
+ PHY_CFG_PLL_FB_DIV_7_0_MASK,
+ DIV_7_0_19_2_MHZ_VAL);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
+ PHY_CFG_PLL_FB_DIV_11_8_MASK,
+ DIV_11_8_19_2_MHZ_VAL);
+ break;
+
+ case 38400000:
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
+ FSEL_MASK,
+ FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2,
+ PHY_CFG_PLL_FB_DIV_7_0_MASK,
+ DIV_7_0_38_4_MHZ_VAL);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
+ PHY_CFG_PLL_FB_DIV_11_8_MASK,
+ DIV_11_8_38_4_MHZ_VAL);
+ break;
+
+ default:
+ dev_err(&phy->phy->dev, "unsupported ref_clk_freq:%lu\n", ref_clk_freq);
+ return -EINVAL;
+ }
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
+ PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL);
+
+ return 0;
+}
+
+static int qcom_snps_eusb2_hsphy_init(struct phy *p)
+{
+ struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs);
+ if (ret)
+ return ret;
+
+ ret = phy_init(phy->repeater);
+ if (ret) {
+ dev_err(&p->dev, "repeater init failed. %d\n", ret);
+ goto disable_vreg;
+ }
+
+ ret = clk_prepare_enable(phy->ref_clk);
+ if (ret) {
+ dev_err(&p->dev, "failed to enable ref clock, %d\n", ret);
+ goto disable_vreg;
+ }
+
+ ret = reset_control_assert(phy->phy_reset);
+ if (ret) {
+ dev_err(&p->dev, "failed to assert phy_reset, %d\n", ret);
+ goto disable_ref_clk;
+ }
+
+ usleep_range(100, 150);
+
+ ret = reset_control_deassert(phy->phy_reset);
+ if (ret) {
+ dev_err(&p->dev, "failed to de-assert phy_reset, %d\n", ret);
+ goto disable_ref_clk;
+ }
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG0,
+ CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, POR);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
+ PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_APB_ACCESS_CMD,
+ APB_LOGIC_RESET, APB_LOGIC_RESET);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_FSEL_SEL,
+ FSEL_SEL, FSEL_SEL);
+
+ /* update ref_clk related registers */
+ ret = qcom_eusb2_ref_clk_init(phy);
+ if (ret)
+ goto disable_ref_clk;
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_1,
+ PHY_CFG_PLL_CPBIAS_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4,
+ PHY_CFG_PLL_INT_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4,
+ PHY_CFG_PLL_GMP_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5,
+ PHY_CFG_PLL_PROP_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_6,
+ PHY_CFG_PLL_VCO_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5,
+ PHY_CFG_PLL_VREF_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1));
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
+ VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL);
+
+ /* set default parameters */
+ qcom_eusb2_default_parameters(phy);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
+ USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
+ USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
+ SIDDQ_SEL, SIDDQ_SEL);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
+ SIDDQ, 0);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, 0);
+
+ qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
+ USB2_SUSPEND_N_SEL, 0);
+
+ return 0;
+
+disable_ref_clk:
+ clk_disable_unprepare(phy->ref_clk);
+
+disable_vreg:
+ regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs);
+
+ return ret;
+}
+
+static int qcom_snps_eusb2_hsphy_exit(struct phy *p)
+{
+ struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
+
+ clk_disable_unprepare(phy->ref_clk);
+
+ regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs);
+
+ phy_exit(phy->repeater);
+
+ return 0;
+}
+
+static const struct phy_ops qcom_snps_eusb2_hsphy_ops = {
+ .init = qcom_snps_eusb2_hsphy_init,
+ .exit = qcom_snps_eusb2_hsphy_exit,
+ .set_mode = qcom_snps_eusb2_hsphy_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct qcom_snps_eusb2_hsphy *phy;
+ struct phy_provider *phy_provider;
+ struct phy *generic_phy;
+ int ret, i;
+ int num;
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ phy->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(phy->base))
+ return PTR_ERR(phy->base);
+
+ phy->phy_reset = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(phy->phy_reset))
+ return PTR_ERR(phy->phy_reset);
+
+ phy->ref_clk = devm_clk_get(dev, "ref");
+ if (IS_ERR(phy->ref_clk))
+ return dev_err_probe(dev, PTR_ERR(phy->ref_clk),
+ "failed to get ref clk\n");
+
+ num = ARRAY_SIZE(phy->vregs);
+ for (i = 0; i < num; i++)
+ phy->vregs[i].supply = eusb2_hsphy_vreg_names[i];
+
+ ret = devm_regulator_bulk_get(dev, num, phy->vregs);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to get regulator supplies\n");
+
+ phy->repeater = devm_of_phy_get_by_index(dev, np, 0);
+ if (IS_ERR(phy->repeater))
+ return dev_err_probe(dev, PTR_ERR(phy->repeater),
+ "failed to get repeater\n");
+
+ generic_phy = devm_phy_create(dev, NULL, &qcom_snps_eusb2_hsphy_ops);
+ if (IS_ERR(generic_phy)) {
+ dev_err(dev, "failed to create phy %d\n", ret);
+ return PTR_ERR(generic_phy);
+ }
+
+ dev_set_drvdata(dev, phy);
+ phy_set_drvdata(generic_phy, phy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider))
+ return PTR_ERR(phy_provider);
+
+ dev_info(dev, "Registered Qcom-eUSB2 phy\n");
+
+ return 0;
+}
+
+static const struct of_device_id qcom_snps_eusb2_hsphy_of_match_table[] = {
+ { .compatible = "qcom,sm8550-snps-eusb2-phy", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, qcom_snps_eusb2_hsphy_of_match_table);
+
+static struct platform_driver qcom_snps_eusb2_hsphy_driver = {
+ .probe = qcom_snps_eusb2_hsphy_probe,
+ .driver = {
+ .name = "qcom-snps-eusb2-hsphy",
+ .of_match_table = qcom_snps_eusb2_hsphy_of_match_table,
+ },
+};
+
+module_platform_driver(qcom_snps_eusb2_hsphy_driver);
+MODULE_DESCRIPTION("Qualcomm SNPS eUSB2 HS PHY driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c
index e7588a940d69..c5206ef9195b 100644
--- a/drivers/phy/renesas/r8a779f0-ether-serdes.c
+++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c
@@ -18,7 +18,6 @@
#define R8A779F0_ETH_SERDES_BANK_SELECT 0x03fc
#define R8A779F0_ETH_SERDES_TIMEOUT_US 100000
#define R8A779F0_ETH_SERDES_NUM_RETRY_LINKUP 3
-#define R8A779F0_ETH_SERDES_NUM_RETRY_INIT 3
struct r8a779f0_eth_serdes_drv_data;
struct r8a779f0_eth_serdes_channel {
@@ -242,51 +241,46 @@ static int r8a779f0_eth_serdes_hw_init(struct r8a779f0_eth_serdes_channel *chann
if (ret)
return ret;
- ret = r8a779f0_eth_serdes_reg_wait(&dd->channel[0], 0x0000, 0x380, BIT(15), 0);
+ return r8a779f0_eth_serdes_reg_wait(&dd->channel[0], 0x0000, 0x380, BIT(15), 0);
+}
+
+static int r8a779f0_eth_serdes_init(struct phy *p)
+{
+ struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
+ int ret;
+
+ ret = r8a779f0_eth_serdes_hw_init(channel);
+ if (!ret)
+ channel->dd->initialized = true;
+
+ return ret;
+}
+
+static int r8a779f0_eth_serdes_hw_init_late(struct r8a779f0_eth_serdes_channel
+*channel)
+{
+ int ret;
+
+ ret = r8a779f0_eth_serdes_chan_setting(channel);
if (ret)
return ret;
- for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
- ret = r8a779f0_eth_serdes_chan_setting(&dd->channel[i]);
- if (ret)
- return ret;
- }
-
- for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
- ret = r8a779f0_eth_serdes_chan_speed(&dd->channel[i]);
- if (ret)
- return ret;
- }
+ ret = r8a779f0_eth_serdes_chan_speed(channel);
+ if (ret)
+ return ret;
- for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++)
- r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03c0, 0x380, 0x0000);
- for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++)
- r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03d0, 0x380, 0x0000);
+ r8a779f0_eth_serdes_write32(channel->addr, 0x03c0, 0x380, 0x0000);
- for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
- ret = r8a779f0_eth_serdes_monitor_linkup(&dd->channel[i]);
- if (ret)
- return ret;
- }
+ r8a779f0_eth_serdes_write32(channel->addr, 0x03d0, 0x380, 0x0000);
- return 0;
+ return r8a779f0_eth_serdes_monitor_linkup(channel);
}
-static int r8a779f0_eth_serdes_init(struct phy *p)
+static int r8a779f0_eth_serdes_power_on(struct phy *p)
{
struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
- int i, ret;
- for (i = 0; i < R8A779F0_ETH_SERDES_NUM_RETRY_INIT; i++) {
- ret = r8a779f0_eth_serdes_hw_init(channel);
- if (!ret) {
- channel->dd->initialized = true;
- break;
- }
- usleep_range(1000, 2000);
- }
-
- return ret;
+ return r8a779f0_eth_serdes_hw_init_late(channel);
}
static int r8a779f0_eth_serdes_set_mode(struct phy *p, enum phy_mode mode,
@@ -319,6 +313,7 @@ static int r8a779f0_eth_serdes_set_speed(struct phy *p, int speed)
static const struct phy_ops r8a779f0_eth_serdes_ops = {
.init = r8a779f0_eth_serdes_init,
+ .power_on = r8a779f0_eth_serdes_power_on,
.set_mode = r8a779f0_eth_serdes_set_mode,
.set_speed = r8a779f0_eth_serdes_set_speed,
};
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index d76440ae10ff..39db8acde61a 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -808,9 +808,8 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
struct extcon_dev *edev = tcphy->extcon;
union extcon_property_value property;
unsigned int id;
- bool ufp, dp;
u8 mode;
- int ret;
+ int ret, ufp, dp;
if (!edev)
return MODE_DFP_USB;
@@ -821,10 +820,10 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
mode = MODE_DFP_USB;
id = EXTCON_USB_HOST;
- if (ufp) {
+ if (ufp > 0) {
mode = MODE_UFP_USB;
id = EXTCON_USB;
- } else if (dp) {
+ } else if (dp > 0) {
mode = MODE_DFP_DP;
id = EXTCON_DISP_DP;
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 3707a0b5c1ae..78045bd6c214 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -718,6 +718,22 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
return err;
}
+static void tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
+{
+ enum usb_role role = USB_ROLE_NONE;
+ enum usb_dr_mode mode = usb_get_role_switch_default_mode(&port->dev);
+
+ if (mode == USB_DR_MODE_HOST)
+ role = USB_ROLE_HOST;
+ else if (mode == USB_DR_MODE_PERIPHERAL)
+ role = USB_ROLE_DEVICE;
+
+ if (role != USB_ROLE_NONE) {
+ usb_role_switch_set_role(port->usb_role_sw, role);
+ dev_dbg(&port->dev, "usb role default mode is %s", modes[mode]);
+ }
+}
+
static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
{
struct tegra_xusb_port *port = &usb2->base;
@@ -747,6 +763,7 @@ static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
err = tegra_xusb_setup_usb_role_switch(port);
if (err < 0)
return err;
+ tegra_xusb_parse_usb_role_default_mode(port);
} else {
dev_err(&port->dev, "usb-role-switch not found for %s mode",
modes[usb2->mode]);
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index ddce5ef7711c..1b83c98a78f0 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -58,6 +58,14 @@ enum wiz_lane_standard_mode {
LANE_MODE_GEN4,
};
+/*
+ * List of master lanes used for lane swapping
+ */
+enum wiz_typec_master_lane {
+ LANE0 = 0,
+ LANE2 = 2,
+};
+
enum wiz_refclk_mux_sel {
PLL0_REFCLK,
PLL1_REFCLK,
@@ -194,6 +202,9 @@ static const struct reg_field p_mac_div_sel1[WIZ_MAX_LANES] = {
static const struct reg_field typec_ln10_swap =
REG_FIELD(WIZ_SERDES_TYPEC, 30, 30);
+static const struct reg_field typec_ln23_swap =
+ REG_FIELD(WIZ_SERDES_TYPEC, 31, 31);
+
struct wiz_clk_mux {
struct clk_hw hw;
struct regmap_field *field;
@@ -367,6 +378,7 @@ struct wiz {
struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS];
struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G];
struct regmap_field *typec_ln10_swap;
+ struct regmap_field *typec_ln23_swap;
struct regmap_field *sup_legacy_clk_override;
struct device *dev;
@@ -376,6 +388,7 @@ struct wiz {
struct gpio_desc *gpio_typec_dir;
int typec_dir_delay;
u32 lane_phy_type[WIZ_MAX_LANES];
+ u32 master_lane_num[WIZ_MAX_LANES];
struct clk *input_clks[WIZ_MAX_INPUT_CLOCKS];
struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS];
struct clk_onecell_data clk_data;
@@ -675,6 +688,13 @@ static int wiz_regfield_init(struct wiz *wiz)
return PTR_ERR(wiz->typec_ln10_swap);
}
+ wiz->typec_ln23_swap = devm_regmap_field_alloc(dev, regmap,
+ typec_ln23_swap);
+ if (IS_ERR(wiz->typec_ln23_swap)) {
+ dev_err(dev, "LN23_SWAP reg field init failed\n");
+ return PTR_ERR(wiz->typec_ln23_swap);
+ }
+
wiz->phy_en_refclk = devm_regmap_field_alloc(dev, regmap, phy_en_refclk);
if (IS_ERR(wiz->phy_en_refclk)) {
dev_err(dev, "PHY_EN_REFCLK reg field init failed\n");
@@ -1234,15 +1254,39 @@ static int wiz_phy_reset_deassert(struct reset_controller_dev *rcdev,
struct wiz *wiz = dev_get_drvdata(dev);
int ret;
- /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
- if (id == 0 && wiz->gpio_typec_dir) {
- if (wiz->typec_dir_delay)
- msleep_interruptible(wiz->typec_dir_delay);
-
- if (gpiod_get_value_cansleep(wiz->gpio_typec_dir))
- regmap_field_write(wiz->typec_ln10_swap, 1);
- else
- regmap_field_write(wiz->typec_ln10_swap, 0);
+ if (id == 0) {
+ /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
+ if (wiz->gpio_typec_dir) {
+ if (wiz->typec_dir_delay)
+ msleep_interruptible(wiz->typec_dir_delay);
+
+ if (gpiod_get_value_cansleep(wiz->gpio_typec_dir))
+ regmap_field_write(wiz->typec_ln10_swap, 1);
+ else
+ regmap_field_write(wiz->typec_ln10_swap, 0);
+ } else {
+ /* if no typec-dir gpio is specified and PHY type is USB3
+ * with master lane number is '0' or '2', then set LN10 or
+ * LN23 SWAP bit to '1' respectively.
+ */
+ u32 num_lanes = wiz->num_lanes;
+ int i;
+
+ for (i = 0; i < num_lanes; i++) {
+ if (wiz->lane_phy_type[i] == PHY_TYPE_USB3) {
+ switch (wiz->master_lane_num[i]) {
+ case LANE0:
+ regmap_field_write(wiz->typec_ln10_swap, 1);
+ break;
+ case LANE2:
+ regmap_field_write(wiz->typec_ln23_swap, 1);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
}
if (id == 0) {
@@ -1386,8 +1430,10 @@ static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__,
reg, reg + num_lanes - 1, phy_type);
- for (i = reg; i < reg + num_lanes; i++)
+ for (i = reg; i < reg + num_lanes; i++) {
+ wiz->master_lane_num[i] = reg;
wiz->lane_phy_type[i] = phy_type;
+ }
}
return 0;
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index a333231616f4..47c9f06c3d84 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -80,19 +80,11 @@ static int exynos_ehci_get_phy(struct device *dev,
return -EINVAL;
}
- phy = devm_of_phy_get(dev, child, NULL);
+ phy = devm_of_phy_optional_get(dev, child, NULL);
exynos_ehci->phy[phy_number] = phy;
if (IS_ERR(phy)) {
- ret = PTR_ERR(phy);
- if (ret == -EPROBE_DEFER) {
- of_node_put(child);
- return ret;
- } else if (ret != -ENOSYS && ret != -ENODEV) {
- dev_err(dev,
- "Error retrieving usb2 phy: %d\n", ret);
- of_node_put(child);
- return ret;
- }
+ of_node_put(child);
+ return PTR_ERR(phy);
}
}
@@ -108,12 +100,10 @@ static int exynos_ehci_phy_enable(struct device *dev)
int ret = 0;
for (i = 0; ret == 0 && i < PHY_NUMBER; i++)
- if (!IS_ERR(exynos_ehci->phy[i]))
- ret = phy_power_on(exynos_ehci->phy[i]);
+ ret = phy_power_on(exynos_ehci->phy[i]);
if (ret)
for (i--; i >= 0; i--)
- if (!IS_ERR(exynos_ehci->phy[i]))
- phy_power_off(exynos_ehci->phy[i]);
+ phy_power_off(exynos_ehci->phy[i]);
return ret;
}
@@ -125,8 +115,7 @@ static void exynos_ehci_phy_disable(struct device *dev)
int i;
for (i = 0; i < PHY_NUMBER; i++)
- if (!IS_ERR(exynos_ehci->phy[i]))
- phy_power_off(exynos_ehci->phy[i]);
+ phy_power_off(exynos_ehci->phy[i]);
}
static void exynos_setup_vbus_gpio(struct device *dev)
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 8d7977fd5d3b..8af17c1ee5cc 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -69,19 +69,11 @@ static int exynos_ohci_get_phy(struct device *dev,
return -EINVAL;
}
- phy = devm_of_phy_get(dev, child, NULL);
+ phy = devm_of_phy_optional_get(dev, child, NULL);
exynos_ohci->phy[phy_number] = phy;
if (IS_ERR(phy)) {
- ret = PTR_ERR(phy);
- if (ret == -EPROBE_DEFER) {
- of_node_put(child);
- return ret;
- } else if (ret != -ENOSYS && ret != -ENODEV) {
- dev_err(dev,
- "Error retrieving usb2 phy: %d\n", ret);
- of_node_put(child);
- return ret;
- }
+ of_node_put(child);
+ return PTR_ERR(phy);
}
}
@@ -97,12 +89,10 @@ static int exynos_ohci_phy_enable(struct device *dev)
int ret = 0;
for (i = 0; ret == 0 && i < PHY_NUMBER; i++)
- if (!IS_ERR(exynos_ohci->phy[i]))
- ret = phy_power_on(exynos_ohci->phy[i]);
+ ret = phy_power_on(exynos_ohci->phy[i]);
if (ret)
for (i--; i >= 0; i--)
- if (!IS_ERR(exynos_ohci->phy[i]))
- phy_power_off(exynos_ohci->phy[i]);
+ phy_power_off(exynos_ohci->phy[i]);
return ret;
}
@@ -114,8 +104,7 @@ static void exynos_ohci_phy_disable(struct device *dev)
int i;
for (i = 0; i < PHY_NUMBER; i++)
- if (!IS_ERR(exynos_ohci->phy[i]))
- phy_power_off(exynos_ohci->phy[i]);
+ phy_power_off(exynos_ohci->phy[i]);
}
static int exynos_ohci_probe(struct platform_device *pdev)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index b1413757fcc3..3a570bc59fc7 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -250,11 +250,12 @@ static inline void phy_set_bus_width(struct phy *phy, int bus_width)
phy->attrs.bus_width = bus_width;
}
struct phy *phy_get(struct device *dev, const char *string);
-struct phy *phy_optional_get(struct device *dev, const char *string);
struct phy *devm_phy_get(struct device *dev, const char *string);
struct phy *devm_phy_optional_get(struct device *dev, const char *string);
struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
const char *con_id);
+struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
+ const char *con_id);
struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
int index);
void of_phy_put(struct phy *phy);
@@ -426,12 +427,6 @@ static inline struct phy *phy_get(struct device *dev, const char *string)
return ERR_PTR(-ENOSYS);
}
-static inline struct phy *phy_optional_get(struct device *dev,
- const char *string)
-{
- return ERR_PTR(-ENOSYS);
-}
-
static inline struct phy *devm_phy_get(struct device *dev, const char *string)
{
return ERR_PTR(-ENOSYS);
@@ -450,6 +445,13 @@ static inline struct phy *devm_of_phy_get(struct device *dev,
return ERR_PTR(-ENOSYS);
}
+static inline struct phy *devm_of_phy_optional_get(struct device *dev,
+ struct device_node *np,
+ const char *con_id)
+{
+ return NULL;
+}
+
static inline struct phy *devm_of_phy_get_by_index(struct device *dev,
struct device_node *np,
int index)