phy-for-6.3

- Core support
 	- New devm_of_phy_optional_get() API with users and conversion
 
   - New support:
 	- Mediatek MT7986 tphy support
         - Qualcomm SM8550 UFS, PCIe, combo phy support, SM6115 / SM4250
           USB3 phy support, SM6350 combo phy support, SM6125 UFS PHY
 	  support amd SM8350 & SM8450 combo phy support
         - Qualcomm SNPS eUSB2 eUSB2 repeater drivers
 	- Allwinner F1C100s USB PHY support
 	- Tegra xusb support for Tegra234
 
   - Updates:
         - Yaml conversion for Qualcomm pcie2 phy and usb-hsic-phy
 	- G4 mode support in Qualcomm UFS phy and support for various SoCs
 	- Yaml conversion for Meson usb2 phy
 	- TI Type C support for usb phy for j721
 	- Yaml conversion for Tegra xusb binding
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmP4vg0ACgkQfBQHDyUj
 g0dJYxAA0DL9X6IFeK8U5blp/ZWmXBqbhRmnsf0KGsSRJMSgHkPruhOWfTCAvXnc
 2+xp8wiE0MdLI7xseJWZi7Q2r10f5LtU55rzbL3mI7MWd/g2WTlKiXCDrpa4fY/Z
 pxo+892vUJh3+I2+Sjf0JnIY89MV/sqSLXsFeKDtvp7J9lMjA98TV6m+YDVTXn22
 SW3hjaB8ochSQV1HEMdEJWsrZc3lmszLdQM+qz3PafyQRbhc1A98Vkf0X/sWR/Ot
 p0FCXlNnY3O272dnrU0V5yv7wwWqjVDN5+Q3vk3AbSlo9ERLVwchayUzxi8EIS7t
 cPmxhsyMoEmsSIPx4z47vLt1NQoqiaKNM7XCrn13Z0fE9fbTW8Trx8VBXcIUsE98
 hT6IxrjRFGJOta8koOssBqSjuwP4QBIZiwXL2YEujj3hGqyRefOCN5XBek7dVyDe
 ctwJsIKBCG8Wh87dFldYLrJgQKR9svZXDjxVADpYMUpPM2v02DCWhUyM50ODowZf
 Yl7bP8dXtn2UBIybbhNTZg29PbrATk73tcr73GZeX8JTOK2vpsZ3+fUsdxPYzed3
 lF2vw361E2ry1DtgmH7XMXevDFvKJ/aks5FIAKebc1tlAPPGYVIkBqyQprAQmlS3
 tDQ+6+jQLAr14iSaVQd9MC3obNqbJYHf1WEU3rKtDy3MB0flbqo=
 =2g27
 -----END PGP SIGNATURE-----

Merge tag 'phy-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy

Pull phy updates from Vinod Koul:
 "This features a bunch of new device support, a couple of new drivers,
  yaml conversion and updates of a few drivers.

  Core support:

   - New devm_of_phy_optional_get() API with users and conversion

  New hardware support:

   - Mediatek MT7986 phy support

   - Qualcomm SM8550 UFS, PCIe, combo phy support, SM6115 / SM4250 USB3
     phy support, SM6350 combo phy support, SM6125 UFS PHY support amd
     SM8350 & SM8450 combo phy support

   - Qualcomm SNPS eUSB2 eUSB2 repeater drivers

   - Allwinner F1C100s USB PHY support

   - Tegra xusb support for Tegra234

  Updates:

   - Yaml conversion for Qualcomm pcie2 phy and usb-hsic-phy

   - G4 mode support in Qualcomm UFS phy and support for various SoCs

   - Yaml conversion for Meson usb2 phy

   - TI Type C support for usb phy for j721

   - Yaml conversion for Tegra xusb binding"

* tag 'phy-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (106 commits)
  phy: qcom: phy-qcom-snps-eusb2: Add support for eUSB2 repeater
  phy: qcom: Add QCOM SNPS eUSB2 repeater driver
  dt-bindings: phy: qcom,snps-eusb2-phy: Add phys property for the repeater
  dt-bindings: phy: Add qcom,snps-eusb2-repeater schema file
  dt-bindings: phy: amlogic,g12a-usb3-pcie-phy: add missing optional phy-supply property
  phy: rockchip-typec: Fix unsigned comparison with less than zero
  phy: rockchip-typec: fix tcphy_get_mode error case
  phy: qcom: snps-eusb2: Add missing headers
  phy: qcom-qmp-combo: Add support for SM8550
  phy: qcom-qmp: Add v6 DP register offsets
  phy: qcom-qmp: pcs-usb: Add v6 register offsets
  dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp: Document SM8550 compatible
  phy: qcom: Add QCOM SNPS eUSB2 driver
  dt-bindings: phy: Add qcom,snps-eusb2-phy schema file
  phy: qcom-qmp-pcie: Add support for SM8550 g3x2 and g4x2 PCIEs
  phy: qcom-qmp: qserdes-lane-shared: Add v6 register offsets
  phy: qcom-qmp: qserdes-txrx: Add v6.20 register offsets
  phy: qcom-qmp: pcs-pcie: Add v6.20 register offsets
  phy: qcom-qmp: pcs-pcie: Add v6 register offsets
  phy: qcom-qmp: pcs: Add v6.20 register offsets
  ...
This commit is contained in:
Linus Torvalds 2023-02-24 17:22:11 -08:00
commit 8ff99ad04c
69 changed files with 6570 additions and 1491 deletions

View File

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

View File

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

View File

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

View File

@ -79,6 +79,7 @@ properties:
- enum:
- mediatek,mt2712-tphy
- mediatek,mt7629-tphy
- mediatek,mt7986-tphy
- mediatek,mt8183-tphy
- mediatek,mt8186-tphy
- mediatek,mt8192-tphy

View File

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

View File

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

View File

@ -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";
};
};
};

View File

@ -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";
};
};
};

View File

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

View File

@ -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";
};
};
};

View File

@ -75,6 +75,9 @@ patternProperties:
minItems: 3
maxItems: 6
"#clock-cells":
const: 1
"#phy-cells":
const: 0

View File

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

View File

@ -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>;
};
...

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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>;
};
};
...

View File

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

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@ properties:
compatible:
enum:
- nxp,tjr1443
- ti,tcan1042
- ti,tcan1043

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -766,27 +766,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
@ -879,6 +858,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

View File

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

View File

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

View File

@ -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");

View File

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

View File

@ -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");
@ -2789,10 +3471,26 @@ static const struct of_device_id qmp_combo_of_match_table[] = {
.compatible = "qcom,sdm845-qmp-usb3-dp-phy",
.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);

View File

@ -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[] = {

View File

@ -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;
@ -2719,12 +3189,24 @@ 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,
},
{ },
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -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,
@ -2622,6 +2618,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,

View File

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

View File

@ -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");

View File

@ -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,53 +241,48 @@ 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);
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;
}
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);
for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
ret = r8a779f0_eth_serdes_monitor_linkup(&dd->channel[i]);
if (ret)
return ret;
}
return 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 i, ret;
int 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);
}
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;
ret = r8a779f0_eth_serdes_chan_speed(channel);
if (ret)
return ret;
r8a779f0_eth_serdes_write32(channel->addr, 0x03c0, 0x380, 0x0000);
r8a779f0_eth_serdes_write32(channel->addr, 0x03d0, 0x380, 0x0000);
return r8a779f0_eth_serdes_monitor_linkup(channel);
}
static int r8a779f0_eth_serdes_power_on(struct phy *p)
{
struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
return r8a779f0_eth_serdes_hw_init_late(channel);
}
static int r8a779f0_eth_serdes_set_mode(struct phy *p, enum phy_mode mode,
int submode)
{
@ -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,
};

View File

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

View File

@ -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]);

View File

@ -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 (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);
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;

View File

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

View File

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

View File

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