* [PATCH v3 01/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie: Change to PCIe/USB3 combo PHY
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-28 10:09 ` Krzysztof Kozlowski
2026-08-25 12:37 ` [PATCH v3 02/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie-usb3: Document the IPQ5018 USB3 PHY George Moussalem via B4 Relay
` (11 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
This PHY is a PCIE/USB3 multi-purpose PHY. Initial support was added for
PCIe only, so rename the binding and add support for USB3 PHY mode.
The PCIe and USB physical pads are muxed and selection is done via a
control register in TCSR. Add a new property to the binding to enable
switching the default PCIe mux selection to USB3 mode.
In addition, USB3 mode requires a 5V supply, so add a vdd-supply
property for it.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml | 109 ----------------
.../phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml | 141 +++++++++++++++++++++
include/dt-bindings/phy/phy-qcom-qmp.h | 4 +
3 files changed, 145 insertions(+), 109 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
deleted file mode 100644
index 6e9df81441e9..000000000000
--- a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
+++ /dev/null
@@ -1,109 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/phy/qcom,ipq5332-uniphy-pcie-phy.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Qualcomm UNIPHY PCIe 28LP PHY
-
-maintainers:
- - Nitheesh Sekar <quic_nsekar@quicinc.com>
- - Varadarajan Narayanan <quic_varada@quicinc.com>
-
-description:
- PCIe and USB combo PHY found in Qualcomm IPQ5018 & IPQ5332 SoCs
-
-properties:
- compatible:
- enum:
- - qcom,ipq5018-uniphy-pcie-phy
- - qcom,ipq5332-uniphy-pcie-phy
-
- reg:
- maxItems: 1
-
- clocks:
- minItems: 1
- maxItems: 2
-
- resets:
- minItems: 2
- maxItems: 3
-
- "#phy-cells":
- const: 0
-
- "#clock-cells":
- const: 0
-
- num-lanes:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [1, 2]
-
-required:
- - compatible
- - reg
- - clocks
- - resets
- - "#phy-cells"
- - "#clock-cells"
- - num-lanes
-
-additionalProperties: false
-
-allOf:
- - if:
- properties:
- compatible:
- contains:
- enum:
- - qcom,ipq5018-uniphy-pcie-phy
- then:
- properties:
- clocks:
- items:
- - description: pcie pipe clock
- resets:
- items:
- - description: phy reset
- - description: cfg reset
-
- - if:
- properties:
- compatible:
- contains:
- enum:
- - qcom,ipq5332-uniphy-pcie-phy
- then:
- properties:
- clocks:
- items:
- - description: pcie pipe clock
- - description: pcie ahb clock
- resets:
- items:
- - description: phy reset
- - description: ahb reset
- - description: cfg reset
-
-examples:
- - |
- #include <dt-bindings/clock/qcom,ipq5332-gcc.h>
-
- pcie0_phy: phy@4b0000 {
- compatible = "qcom,ipq5332-uniphy-pcie-phy";
- reg = <0x004b0000 0x800>;
-
- clocks = <&gcc GCC_PCIE3X1_0_PIPE_CLK>,
- <&gcc GCC_PCIE3X1_PHY_AHB_CLK>;
-
- resets = <&gcc GCC_PCIE3X1_0_PHY_BCR>,
- <&gcc GCC_PCIE3X1_PHY_AHB_CLK_ARES>,
- <&gcc GCC_PCIE3X1_0_PHY_PHY_BCR>;
-
- #clock-cells = <0>;
-
- #phy-cells = <0>;
-
- num-lanes = <1>;
- };
diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml
new file mode 100644
index 000000000000..0d9d0fb405b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm IPQ5332 UNIPHY PCIe/USB3 28LP PHY controller
+
+maintainers:
+ - Nitheesh Sekar <quic_nsekar@quicinc.com>
+ - Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
+
+description:
+ The QMP PHY controller supports physical layer functionality for PCIe and USB
+ controllers on Qualcomm IPQ5018 & IPQ5332 chipsets.
+
+properties:
+ compatible:
+ enum:
+ - qcom,ipq5018-uniphy-pcie-phy
+ - qcom,ipq5332-uniphy-pcie-phy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 4
+
+ clock-names:
+ maxItems: 4
+
+ resets:
+ minItems: 1
+ maxItems: 4
+
+ reset-names:
+ maxItems: 4
+
+ num-lanes:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1, 2]
+
+ vdd-supply:
+ description:
+ Phandle to 5V regulator supply to PHY digital circuit.
+
+ qcom,phy-usb-mux-sel:
+ description:
+ TCSR register address for mux selection control for PCIe / USB3 mode.
+ If the property is set, the driver will configure USB3 mux selection.
+ If not set, the setting defaults to PCIe mux selection (BIT(0) = 0).
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle of TCSR syscon
+ - description: offset of PHY mux selection register
+
+ "#clock-cells":
+ enum: [0, 1]
+
+ "#phy-cells":
+ enum: [0, 1]
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - "#clock-cells"
+ - "#phy-cells"
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5018-uniphy-pcie-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: pcie pipe clock
+ resets:
+ items:
+ - description: pcie phy reset
+ - description: pcie cfg reset
+ "#clock-cells":
+ const: 0
+ "#phy-cells":
+ const: 0
+ required:
+ - num-lanes
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5332-uniphy-pcie-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: pcie pipe clock
+ - description: pcie ahb clock
+ resets:
+ items:
+ - description: pcie phy reset
+ - description: pcie ahb reset
+ - description: pcie cfg reset
+ "#clock-cells":
+ const: 0
+ "#phy-cells":
+ const: 0
+ required:
+ - num-lanes
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,ipq5332-gcc.h>
+
+ pcie1_phy: phy@4b1000 {
+ compatible = "qcom,ipq5332-uniphy-pcie-phy";
+ reg = <0x004b1000 0x800>;
+
+ clocks = <&gcc GCC_PCIE3X2_PIPE_CLK>,
+ <&gcc GCC_PCIE3X2_PHY_AHB_CLK>;
+
+ resets = <&gcc GCC_PCIE3X2_PHY_BCR>,
+ <&gcc GCC_PCIE3X2_PHY_AHB_CLK_ARES>,
+ <&gcc GCC_PCIE3X2PHY_PHY_BCR>;
+
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+
+ num-lanes = <2>;
+ };
diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/phy/phy-qcom-qmp.h
index 6b43ea9e0051..a19f7376b15e 100644
--- a/include/dt-bindings/phy/phy-qcom-qmp.h
+++ b/include/dt-bindings/phy/phy-qcom-qmp.h
@@ -21,4 +21,8 @@
#define QMP_PCIE_PIPE_CLK 0
#define QMP_PCIE_PHY_AUX_CLK 1
+/* QMP PHY MUX */
+#define QMP_PHY_MUX_PCIE 0
+#define QMP_PHY_MUX_USB3 1
+
#endif /* _DT_BINDINGS_PHY_QMP */
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 01/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie: Change to PCIe/USB3 combo PHY
2026-08-25 12:37 ` [PATCH v3 01/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie: Change to PCIe/USB3 combo PHY George Moussalem via B4 Relay
@ 2026-08-28 10:09 ` Krzysztof Kozlowski
2026-08-28 10:51 ` George Moussalem
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-08-28 10:09 UTC (permalink / raw)
To: George Moussalem
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam,
linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb
On Tue, Aug 25, 2026 at 04:37:18PM +0400, George Moussalem wrote:
> This PHY is a PCIE/USB3 multi-purpose PHY. Initial support was added for
> PCIe only, so rename the binding and add support for USB3 PHY mode.
>
> The PCIe and USB physical pads are muxed and selection is done via a
> control register in TCSR. Add a new property to the binding to enable
> switching the default PCIe mux selection to USB3 mode.
>
> In addition, USB3 mode requires a 5V supply, so add a vdd-supply
> property for it.
>
> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
> ---
> .../bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml | 109 ----------------
> .../phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml | 141 +++++++++++++++++++++
> include/dt-bindings/phy/phy-qcom-qmp.h | 4 +
> 3 files changed, 145 insertions(+), 109 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
> deleted file mode 100644
> index 6e9df81441e9..000000000000
Please do not rename the binding. Old name was correct. New one is not,
otherwise please point me to the compatible like that.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 01/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie: Change to PCIe/USB3 combo PHY
2026-08-28 10:09 ` Krzysztof Kozlowski
@ 2026-08-28 10:51 ` George Moussalem
0 siblings, 0 replies; 16+ messages in thread
From: George Moussalem @ 2026-08-28 10:51 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam,
linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb
On 8/28/26 14:09, Krzysztof Kozlowski wrote:
> On Tue, Aug 25, 2026 at 04:37:18PM +0400, George Moussalem wrote:
>> This PHY is a PCIE/USB3 multi-purpose PHY. Initial support was added for
>> PCIe only, so rename the binding and add support for USB3 PHY mode.
>>
>> The PCIe and USB physical pads are muxed and selection is done via a
>> control register in TCSR. Add a new property to the binding to enable
>> switching the default PCIe mux selection to USB3 mode.
>>
>> In addition, USB3 mode requires a 5V supply, so add a vdd-supply
>> property for it.
>>
>> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
>> ---
>> .../bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml | 109 ----------------
>> .../phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml | 141 +++++++++++++++++++++
>> include/dt-bindings/phy/phy-qcom-qmp.h | 4 +
>> 3 files changed, 145 insertions(+), 109 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
>> deleted file mode 100644
>> index 6e9df81441e9..000000000000
>
> Please do not rename the binding. Old name was correct. New one is not,
> otherwise please point me to the compatible like that.
I thought we had come to the conclusion it's the same device in the
discussion in v2:
https://lore.kernel.org/all/gn43qixdtbq5iyfqvzibdtx4lmwpkt2ieahr7oqsxxjfpldb6d@xbxhbdrq4e6b/
I've split up this series into 3 as in the cover letter:
1. Flatten USB Controller Nodes on IPQ SoCs
link:
https://lore.kernel.org/r/20260825-ipq-flatten-usb-v1-0-5c1f3170bbe9@outlook.com
2. Enable USB3 for Qualcomm IPQ5018 (this patch series)
3. Enable USB3 for Qualcomm IPQ5332 (to be submitted)
Since 2 is dependent on 1, I thought I'd wait for the feedback first on
1, then submit 3 which is dependent on 2.
But eventually, the IPQ5332 combo PHY looks like:
pcie0_phy: phy@4b0000 {
compatible = "qcom,ipq5332-uniphy-pcie-usb3-phy";
reg = <0x004b0000 0x800>;
clocks = <&gcc GCC_PCIE3X1_0_PIPE_CLK>,
<&gcc GCC_PCIE3X1_PHY_AHB_CLK>,
<&gcc GCC_USB0_PIPE_CLK>,
<&gcc GCC_USB0_PHY_CFG_AHB_CLK>;
clock-names = "pcie-pipe",
"pcie-ahb",
"usb3-pipe",
"usb3-cfg-ahb";
resets = <&gcc GCC_PCIE3X1_0_PHY_BCR>,
<&gcc GCC_PCIE3X1_PHY_AHB_CLK_ARES>,
<&gcc GCC_PCIE3X1_0_PHY_PHY_BCR>,
<&gcc GCC_USB0_PHY_BCR>;
reset-names = "pcie-phy",
"pcie-ahb",
"pcie-cfg",
"usb3-phy";
#clock-cells = <1>;
#phy-cells = <1>;
num-lanes = <1>;
status = "disabled";
};
I have the patches ready. Let me know if you'd like them submitted.
The idea was to prepare the binding for both IPQ5018 USB3 and IPQ5332
PCIe/USB3, hence the rename from pcie -> pcie-usb3
>
> Best regards,
> Krzysztof
>
Best regards,
George
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 02/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie-usb3: Document the IPQ5018 USB3 PHY
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 01/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie: Change to PCIe/USB3 combo PHY George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 03/12] phy: qualcomm: qcom-uniphy-pcie-28lp: Convert to PCIe/USB3 combo PHY driver George Moussalem via B4 Relay
` (10 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Describe the USB3 PHY found in the IPQ5018 SoC so add the compatible
string for it as well as the required resources (clocks and resets).
The PCIe and USB physical pads are muxed and selection is done via a
control register in TCSR. By default, PCIe mode is selected, hence make
the property for USB mux selection required.
In addition, the PHY requires a 5V supply for USB3 mode operation.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml
index 0d9d0fb405b6..1cd5392a1a0f 100644
--- a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-usb3-phy.yaml
@@ -18,6 +18,7 @@ properties:
compatible:
enum:
- qcom,ipq5018-uniphy-pcie-phy
+ - qcom,ipq5018-uniphy-usb3-phy
- qcom,ipq5332-uniphy-pcie-phy
reg:
@@ -93,6 +94,29 @@ allOf:
required:
- num-lanes
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5018-uniphy-usb3-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: usb3 pipe clock
+ - description: usb3 cfg ahb clock
+ resets:
+ items:
+ - description: usb3 phy reset
+ "#clock-cells":
+ const: 0
+ "#phy-cells":
+ const: 0
+ required:
+ - vdd-supply
+ - qcom,phy-usb-mux-sel
+
- if:
properties:
compatible:
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 03/12] phy: qualcomm: qcom-uniphy-pcie-28lp: Convert to PCIe/USB3 combo PHY driver
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 01/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie: Change to PCIe/USB3 combo PHY George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 02/12] dt-bindings: phy: qcom,ipq5332-uniphy-pcie-usb3: Document the IPQ5018 USB3 PHY George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 04/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Refactor init regs table definitions George Moussalem via B4 Relay
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
This PHY found in IPQ5332 and IPQ5018 SoCs is actually a multi-purpose
PCIe/USB3 combo PHY. The driver was initially created for PCIe PHY
support only. As such, rename the driver and generalize function and
struct names to reflect that it is a PCIe and USB3 combo PHY driver so
that USB3 support can be added in subsequent patches.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
drivers/phy/qualcomm/Kconfig | 24 +++---
drivers/phy/qualcomm/Makefile | 2 +-
...cie-28lp.c => phy-qcom-uniphy-pcie-usb3-28lp.c} | 87 +++++++++++-----------
3 files changed, 55 insertions(+), 58 deletions(-)
diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index d910a5d1a1ac..6872aa919cf2 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -155,19 +155,6 @@ config PHY_QCOM_M31_USB
management. This driver is required even for peripheral only or
host only mode configurations.
-config PHY_QCOM_UNIPHY_PCIE_28LP
- bool "PCIE UNIPHY 28LP PHY driver"
- depends on ARCH_QCOM
- depends on COMMON_CLK
- depends on HAS_IOMEM
- depends on OF
- select GENERIC_PHY
- help
- Enable this to support the PCIe UNIPHY 28LP phy transceiver that
- is used with PCIe controllers on Qualcomm IPQ5332 chips. It
- handles PHY initialization, clock management required after
- resetting the hardware and power management.
-
config PHY_QCOM_M31_EUSB
tristate "Qualcomm M31 eUSB2 PHY driver support"
depends on USB && (ARCH_QCOM || COMPILE_TEST)
@@ -178,6 +165,17 @@ config PHY_QCOM_M31_EUSB
up of the associated USB repeater that is paired with the eUSB2
PHY.
+config PHY_QCOM_UNIPHY_PCIE_USB3_28LP
+ bool "Qualcomm IPQ5332 UNIPHY PCIe USB3 28LP PHY driver"
+ depends on OF && (ARCH_QCOM || COMPILE_TEST)
+ select GENERIC_PHY
+ select MFD_SYSCON
+ help
+ Enable this to support the Qualcomm USB Super-Speed UNIPHY transceiver
+ that is used on Qualcomm IPQ5018 and IPQ5332 SoCs with DWC3 USB core.
+ It handles PHY initialization, clock management required after
+ resetting the hardware and power management.
+
config PHY_QCOM_USB_HS
tristate "Qualcomm USB HS PHY module"
depends on USB_ULPI_BUS
diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile
index 8bf887d58ee4..6e2e9737e387 100644
--- a/drivers/phy/qualcomm/Makefile
+++ b/drivers/phy/qualcomm/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_PHY_QCOM_QMP_USB_LEGACY) += phy-qcom-qmp-usb-legacy.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_EUSB2_REPEATER) += phy-qcom-eusb2-repeater.o
-obj-$(CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP) += phy-qcom-uniphy-pcie-28lp.o
+obj-$(CONFIG_PHY_QCOM_UNIPHY_PCIE_USB3_28LP) += phy-qcom-uniphy-pcie-usb3-28lp.o
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
similarity index 75%
rename from drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
rename to drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
index 324c0a5d658e..aeb8f7ddbd7a 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
@@ -43,29 +43,29 @@
#define PHY_CFG_EIOS_DTCT_REG 0x3e4
#define PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME 0x3e8
-enum qcom_uniphy_pcie_type {
+enum qcom_uniphy_type {
PHY_TYPE_PCIE = 1,
PHY_TYPE_PCIE_GEN2,
PHY_TYPE_PCIE_GEN3,
};
-struct qcom_uniphy_pcie_regs {
+struct qcom_uniphy_regs {
u32 offset;
u32 val;
};
-struct qcom_uniphy_pcie_data {
+struct qcom_uniphy_data {
int lane_offset; /* offset between the lane register bases */
u32 phy_type;
- const struct qcom_uniphy_pcie_regs *init_seq;
+ const struct qcom_uniphy_regs *init_seq;
u32 init_seq_num;
u32 pipe_clk_rate;
};
-struct qcom_uniphy_pcie {
+struct qcom_uniphy {
struct phy phy;
struct device *dev;
- const struct qcom_uniphy_pcie_data *data;
+ const struct qcom_uniphy_data *data;
struct clk_bulk_data *clks;
int num_clks;
struct reset_control *resets;
@@ -73,9 +73,9 @@ struct qcom_uniphy_pcie {
int lanes;
};
-#define phy_to_dw_phy(x) container_of((x), struct qca_uni_pcie_phy, phy)
+#define phy_to_dw_phy(x) container_of((x), struct qcom_uniphy, phy)
-static const struct qcom_uniphy_pcie_regs ipq5018_regs[] = {
+static const struct qcom_uniphy_regs ipq5018_pcie_regs[] = {
{
.offset = SSCG_CTRL_REG_4,
.val = 0x1cb9,
@@ -109,7 +109,7 @@ static const struct qcom_uniphy_pcie_regs ipq5018_regs[] = {
},
};
-static const struct qcom_uniphy_pcie_regs ipq5332_regs[] = {
+static const struct qcom_uniphy_regs ipq5332_pcie_regs[] = {
{
.offset = PHY_CFG_PLLCFG,
.val = 0x30,
@@ -122,26 +122,26 @@ static const struct qcom_uniphy_pcie_regs ipq5332_regs[] = {
},
};
-static const struct qcom_uniphy_pcie_data ipq5018_data = {
+static const struct qcom_uniphy_data ipq5018_data = {
.lane_offset = 0x800,
.phy_type = PHY_TYPE_PCIE_GEN2,
- .init_seq = ipq5018_regs,
- .init_seq_num = ARRAY_SIZE(ipq5018_regs),
+ .init_seq = ipq5018_pcie_regs,
+ .init_seq_num = ARRAY_SIZE(ipq5018_pcie_regs),
.pipe_clk_rate = 125 * MEGA,
};
-static const struct qcom_uniphy_pcie_data ipq5332_data = {
+static const struct qcom_uniphy_data ipq5332_data = {
.lane_offset = 0x800,
.phy_type = PHY_TYPE_PCIE_GEN3,
- .init_seq = ipq5332_regs,
- .init_seq_num = ARRAY_SIZE(ipq5332_regs),
+ .init_seq = ipq5332_pcie_regs,
+ .init_seq_num = ARRAY_SIZE(ipq5332_pcie_regs),
.pipe_clk_rate = 250 * MEGA,
};
-static void qcom_uniphy_pcie_init(struct qcom_uniphy_pcie *phy)
+static void qcom_uniphy_pcie_usb3_init(struct qcom_uniphy *phy)
{
- const struct qcom_uniphy_pcie_data *data = phy->data;
- const struct qcom_uniphy_pcie_regs *init_seq;
+ const struct qcom_uniphy_data *data = phy->data;
+ const struct qcom_uniphy_regs *init_seq;
void __iomem *base = phy->base;
int lane, i;
@@ -155,18 +155,18 @@ static void qcom_uniphy_pcie_init(struct qcom_uniphy_pcie *phy)
}
}
-static int qcom_uniphy_pcie_power_off(struct phy *x)
+static int qcom_uniphy_pcie_usb3_power_off(struct phy *x)
{
- struct qcom_uniphy_pcie *phy = phy_get_drvdata(x);
+ struct qcom_uniphy *phy = phy_get_drvdata(x);
clk_bulk_disable_unprepare(phy->num_clks, phy->clks);
return reset_control_assert(phy->resets);
}
-static int qcom_uniphy_pcie_power_on(struct phy *x)
+static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
{
- struct qcom_uniphy_pcie *phy = phy_get_drvdata(x);
+ struct qcom_uniphy *phy = phy_get_drvdata(x);
int ret;
ret = reset_control_assert(phy->resets);
@@ -193,13 +193,13 @@ static int qcom_uniphy_pcie_power_on(struct phy *x)
usleep_range(CLK_EN_DELAY_MIN_US, CLK_EN_DELAY_MAX_US);
- qcom_uniphy_pcie_init(phy);
+ qcom_uniphy_pcie_usb3_init(phy);
return 0;
}
-static inline int qcom_uniphy_pcie_get_resources(struct platform_device *pdev,
- struct qcom_uniphy_pcie *phy)
+static inline int qcom_uniphy_pcie_usb3_get_resources(struct platform_device *pdev,
+ struct qcom_uniphy *phy)
{
struct resource *res;
@@ -236,9 +236,9 @@ static inline int qcom_uniphy_pcie_get_resources(struct platform_device *pdev,
* clk | +-------+ | +-----+
* +---------------+
*/
-static inline int phy_pipe_clk_register(struct qcom_uniphy_pcie *phy, int id)
+static inline int phy_pipe_clk_register(struct qcom_uniphy *phy, int id)
{
- const struct qcom_uniphy_pcie_data *data = phy->data;
+ const struct qcom_uniphy_data *data = phy->data;
struct clk_hw *hw;
char name[64];
@@ -252,30 +252,29 @@ static inline int phy_pipe_clk_register(struct qcom_uniphy_pcie *phy, int id)
return devm_of_clk_add_hw_provider(phy->dev, of_clk_hw_simple_get, hw);
}
-static const struct of_device_id qcom_uniphy_pcie_id_table[] = {
+static const struct of_device_id qcom_uniphy_pcie_usb3_id_table[] = {
{
.compatible = "qcom,ipq5018-uniphy-pcie-phy",
.data = &ipq5018_data,
}, {
.compatible = "qcom,ipq5332-uniphy-pcie-phy",
.data = &ipq5332_data,
- }, {
- /* Sentinel */
},
+ { },
};
-MODULE_DEVICE_TABLE(of, qcom_uniphy_pcie_id_table);
+MODULE_DEVICE_TABLE(of, qcom_uniphy_pcie_usb3_id_table);
-static const struct phy_ops pcie_ops = {
- .power_on = qcom_uniphy_pcie_power_on,
- .power_off = qcom_uniphy_pcie_power_off,
+static const struct phy_ops qcom_uniphy_ops = {
+ .power_on = qcom_uniphy_pcie_usb3_power_on,
+ .power_off = qcom_uniphy_pcie_usb3_power_off,
.owner = THIS_MODULE,
};
-static int qcom_uniphy_pcie_probe(struct platform_device *pdev)
+static int qcom_uniphy_pcie_usb3_probe(struct platform_device *pdev)
{
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
- struct qcom_uniphy_pcie *phy;
+ struct qcom_uniphy *phy;
struct phy *generic_phy;
int ret;
@@ -294,12 +293,12 @@ static int qcom_uniphy_pcie_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Couldn't read num-lanes\n");
- ret = qcom_uniphy_pcie_get_resources(pdev, phy);
+ ret = qcom_uniphy_pcie_usb3_get_resources(pdev, phy);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"failed to get resources: %d\n", ret);
- generic_phy = devm_phy_create(phy->dev, NULL, &pcie_ops);
+ generic_phy = devm_phy_create(phy->dev, NULL, &qcom_uniphy_ops);
if (IS_ERR(generic_phy))
return PTR_ERR(generic_phy);
@@ -317,15 +316,15 @@ static int qcom_uniphy_pcie_probe(struct platform_device *pdev)
return 0;
}
-static struct platform_driver qcom_uniphy_pcie_driver = {
- .probe = qcom_uniphy_pcie_probe,
+static struct platform_driver qcom_uniphy_pcie_usb3_driver = {
+ .probe = qcom_uniphy_pcie_usb3_probe,
.driver = {
- .name = "qcom-uniphy-pcie",
- .of_match_table = qcom_uniphy_pcie_id_table,
+ .name = "qcom-uniphy-pcie-usb3-28lp",
+ .of_match_table = qcom_uniphy_pcie_usb3_id_table,
},
};
-module_platform_driver(qcom_uniphy_pcie_driver);
+module_platform_driver(qcom_uniphy_pcie_usb3_driver);
-MODULE_DESCRIPTION("PCIE QCOM UNIPHY driver");
+MODULE_DESCRIPTION("Qualcomm IPQ5332 UNIPHY PCIe USB3 28LP PHY driver");
MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 04/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Refactor init regs table definitions
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (2 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 03/12] phy: qualcomm: qcom-uniphy-pcie-28lp: Convert to PCIe/USB3 combo PHY driver George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 05/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Use bulk reset_control API George Moussalem via B4 Relay
` (8 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Refactor the IPQ5018/IPQ5332 UNIPHY PCIe init data by introducing a
helper macro for register/value entries and converting open-coded struct
initializers to the compact form.
Also remove an unused include, drop unused macro register definitions,
and rename the IPQ5332-specific PHY CFG register macros to make their
combo PCIe/USB3 scope explicit.
No functional change intended.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c | 94 ++++++++--------------
1 file changed, 33 insertions(+), 61 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
index aeb8f7ddbd7a..44ab8f440b8a 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
@@ -10,7 +10,6 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
@@ -24,24 +23,21 @@
#define PIPE_CLK_DELAY_MAX_US 5100
#define CLK_EN_DELAY_MIN_US 30
#define CLK_EN_DELAY_MAX_US 50
-#define CDR_CTRL_REG_1 0x80
-#define CDR_CTRL_REG_2 0x84
-#define CDR_CTRL_REG_3 0x88
-#define CDR_CTRL_REG_4 0x8c
-#define CDR_CTRL_REG_5 0x90
-#define CDR_CTRL_REG_6 0x94
-#define CDR_CTRL_REG_7 0x98
-#define SSCG_CTRL_REG_1 0x9c
-#define SSCG_CTRL_REG_2 0xa0
-#define SSCG_CTRL_REG_3 0xa4
-#define SSCG_CTRL_REG_4 0xa8
-#define SSCG_CTRL_REG_5 0xac
-#define SSCG_CTRL_REG_6 0xb0
-#define PCS_INTERNAL_CONTROL_2 0x2d8
-
-#define PHY_CFG_PLLCFG 0x220
-#define PHY_CFG_EIOS_DTCT_REG 0x3e4
-#define PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME 0x3e8
+
+#define CDR_CTRL_REG_1 0x80
+#define CDR_CTRL_REG_2 0x84
+#define CDR_CTRL_REG_4 0x8c
+#define CDR_CTRL_REG_5 0x90
+#define SSCG_CTRL_REG_1 0x9c
+#define SSCG_CTRL_REG_2 0xa0
+#define SSCG_CTRL_REG_3 0xa4
+#define SSCG_CTRL_REG_4 0xa8
+#define SSCG_CTRL_REG_5 0xac
+
+#define PCIE_USB_COMBO_PHY_CFG_PLLCFG 0x220
+#define PCIE_USB_COMBO_PHY_CFG_PCS_INTERNAL_CONTROL_2 0x2d8
+#define PCIE_USB_COMBO_PHY_CFG_EIOS_DTCT_REG 0x3e4
+#define PCIE_USB_COMBO_PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME 0x3e8
enum qcom_uniphy_type {
PHY_TYPE_PCIE = 1,
@@ -73,53 +69,29 @@ struct qcom_uniphy {
int lanes;
};
-#define phy_to_dw_phy(x) container_of((x), struct qcom_uniphy, phy)
+#define PHY_INIT_CFG(o, v) \
+ { \
+ .offset = o, \
+ .val = v, \
+ }
static const struct qcom_uniphy_regs ipq5018_pcie_regs[] = {
- {
- .offset = SSCG_CTRL_REG_4,
- .val = 0x1cb9,
- }, {
- .offset = SSCG_CTRL_REG_5,
- .val = 0x023a,
- }, {
- .offset = SSCG_CTRL_REG_3,
- .val = 0xd360,
- }, {
- .offset = SSCG_CTRL_REG_1,
- .val = 0x1,
- }, {
- .offset = SSCG_CTRL_REG_2,
- .val = 0xeb,
- }, {
- .offset = CDR_CTRL_REG_4,
- .val = 0x3f9,
- }, {
- .offset = CDR_CTRL_REG_5,
- .val = 0x1c9,
- }, {
- .offset = CDR_CTRL_REG_2,
- .val = 0x419,
- }, {
- .offset = CDR_CTRL_REG_1,
- .val = 0x200,
- }, {
- .offset = PCS_INTERNAL_CONTROL_2,
- .val = 0xf101,
- },
+ PHY_INIT_CFG(SSCG_CTRL_REG_4, 0x1cb9),
+ PHY_INIT_CFG(SSCG_CTRL_REG_5, 0x023a),
+ PHY_INIT_CFG(SSCG_CTRL_REG_3, 0xd360),
+ PHY_INIT_CFG(SSCG_CTRL_REG_1, 0x1),
+ PHY_INIT_CFG(SSCG_CTRL_REG_2, 0xeb),
+ PHY_INIT_CFG(CDR_CTRL_REG_4, 0x3f9),
+ PHY_INIT_CFG(CDR_CTRL_REG_5, 0x1c9),
+ PHY_INIT_CFG(CDR_CTRL_REG_2, 0x419),
+ PHY_INIT_CFG(CDR_CTRL_REG_1, 0x200),
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_PCS_INTERNAL_CONTROL_2, 0xf101),
};
static const struct qcom_uniphy_regs ipq5332_pcie_regs[] = {
- {
- .offset = PHY_CFG_PLLCFG,
- .val = 0x30,
- }, {
- .offset = PHY_CFG_EIOS_DTCT_REG,
- .val = 0x53ef,
- }, {
- .offset = PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME,
- .val = 0xcf,
- },
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_PLLCFG, 0x30),
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_EIOS_DTCT_REG, 0x53ef),
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME, 0xcf),
};
static const struct qcom_uniphy_data ipq5018_data = {
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 05/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Use bulk reset_control API
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (3 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 04/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Refactor init regs table definitions George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 06/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Improve error handling in power_on George Moussalem via B4 Relay
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Switch to using bulk reset_control functions to prepare the driver for
managing multiple resets, acquiring reset controls by name, and
uniformly storing resets in the private data structure to enable support
for future combo PHY functionality requiring multiple resets.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c | 31 ++++++++++++++++------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
index 44ab8f440b8a..671bb805057f 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
@@ -64,7 +64,8 @@ struct qcom_uniphy {
const struct qcom_uniphy_data *data;
struct clk_bulk_data *clks;
int num_clks;
- struct reset_control *resets;
+ struct reset_control_bulk_data *resets;
+ int num_resets;
void __iomem *base;
int lanes;
};
@@ -133,7 +134,7 @@ static int qcom_uniphy_pcie_usb3_power_off(struct phy *x)
clk_bulk_disable_unprepare(phy->num_clks, phy->clks);
- return reset_control_assert(phy->resets);
+ return reset_control_bulk_assert(phy->num_resets, phy->resets);
}
static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
@@ -141,7 +142,7 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
struct qcom_uniphy *phy = phy_get_drvdata(x);
int ret;
- ret = reset_control_assert(phy->resets);
+ ret = reset_control_bulk_assert(phy->num_resets, phy->resets);
if (ret) {
dev_err(phy->dev, "reset assert failed (%d)\n", ret);
return ret;
@@ -149,7 +150,7 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
usleep_range(RST_ASSERT_DELAY_MIN_US, RST_ASSERT_DELAY_MAX_US);
- ret = reset_control_deassert(phy->resets);
+ ret = reset_control_bulk_deassert(phy->num_resets, phy->resets);
if (ret) {
dev_err(phy->dev, "reset deassert failed (%d)\n", ret);
return ret;
@@ -173,19 +174,33 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
static inline int qcom_uniphy_pcie_usb3_get_resources(struct platform_device *pdev,
struct qcom_uniphy *phy)
{
+ struct device *dev = phy->dev;
struct resource *res;
+ int i, count;
phy->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(phy->base))
return PTR_ERR(phy->base);
- phy->num_clks = devm_clk_bulk_get_all(phy->dev, &phy->clks);
+ phy->num_clks = devm_clk_bulk_get_all(dev, &phy->clks);
if (phy->num_clks < 0)
return phy->num_clks;
- phy->resets = devm_reset_control_array_get_exclusive(phy->dev);
- if (IS_ERR(phy->resets))
- return PTR_ERR(phy->resets);
+ count = of_count_phandle_with_args(dev->of_node, "resets", "#reset-cells");
+ if (count < 0)
+ return count;
+
+ phy->resets = devm_kcalloc(dev, count, sizeof(*phy->resets), GFP_KERNEL);
+ if (!phy->resets)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ phy->resets[i].rstc = devm_reset_control_get_exclusive_by_index(dev, i);
+ if (IS_ERR(phy->resets[i].rstc))
+ return PTR_ERR(phy->resets[i].rstc);
+ }
+
+ phy->num_resets = count;
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 06/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Improve error handling in power_on
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (4 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 05/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Use bulk reset_control API George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 07/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Add support for USB3 PHY on IPQ5018 George Moussalem via B4 Relay
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
When the PHY fails the enable clocks, it leaves the PHY out of reset.
Fix this by asserting the reset before returning the error.
In addition, language correct the error messages.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
index 671bb805057f..d25ae9d8b9e7 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
@@ -144,7 +144,7 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
ret = reset_control_bulk_assert(phy->num_resets, phy->resets);
if (ret) {
- dev_err(phy->dev, "reset assert failed (%d)\n", ret);
+ dev_err(phy->dev, "failed to assert reset: %d\n", ret);
return ret;
}
@@ -152,7 +152,7 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
ret = reset_control_bulk_deassert(phy->num_resets, phy->resets);
if (ret) {
- dev_err(phy->dev, "reset deassert failed (%d)\n", ret);
+ dev_err(phy->dev, "failed to deassert reset: %d\n", ret);
return ret;
}
@@ -160,8 +160,8 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
ret = clk_bulk_prepare_enable(phy->num_clks, phy->clks);
if (ret) {
- dev_err(phy->dev, "clk prepare and enable failed %d\n", ret);
- return ret;
+ dev_err(phy->dev, "failed to enable clocks: %d\n", ret);
+ goto err_assert_resets;
}
usleep_range(CLK_EN_DELAY_MIN_US, CLK_EN_DELAY_MAX_US);
@@ -169,6 +169,11 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
qcom_uniphy_pcie_usb3_init(phy);
return 0;
+
+err_assert_resets:
+ reset_control_bulk_assert(phy->num_resets, phy->resets);
+
+ return ret;
}
static inline int qcom_uniphy_pcie_usb3_get_resources(struct platform_device *pdev,
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 07/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Add support for USB3 PHY on IPQ5018
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (5 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 06/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Improve error handling in power_on George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 08/12] arm64: dts: qcom: ipq5018: Add USB Super-Speed PHY node George Moussalem via B4 Relay
` (5 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Add support for the USB3 PHY on IPQ5018 chipsets.
The PHY outputs a 250MHz PIPE clock routed to and gated by the GCC, so
register a fixed rate clock. In addition, add the register/value pairs
for the PHY initialization sequence.
The PHY requires a 5V supply, so acquire the regulator from the
devicetree and enable it on power on and disable it on power off.
The code to acquire clocks and resets is the same as for PCIe so no
changes are needed.
Power on/off sequences for PCIE and USB3 are similar except for the
delay timings and USB3 requirement for the PHY supply.
Lastly, the PCIe and USB3 pads are muxed so select USB3 mode in TCSR
which needs to occur before the DWC3 USB3 controller resets.
Otherwise, the SS link doesn't train and remains stuck in RX.Detect.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c | 154 +++++++++++++++++----
1 file changed, 127 insertions(+), 27 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
index d25ae9d8b9e7..84df331fce74 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-usb3-28lp.c
@@ -14,15 +14,21 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/units.h>
-#define RST_ASSERT_DELAY_MIN_US 100
-#define RST_ASSERT_DELAY_MAX_US 150
-#define PIPE_CLK_DELAY_MIN_US 5000
-#define PIPE_CLK_DELAY_MAX_US 5100
-#define CLK_EN_DELAY_MIN_US 30
-#define CLK_EN_DELAY_MAX_US 50
+#define PCIE_RST_ASSERT_DELAY_MIN_US 100
+#define PCIE_RST_ASSERT_DELAY_MAX_US 150
+#define PCIE_PIPE_CLK_DELAY_MIN_US 5000
+#define PCIE_PIPE_CLK_DELAY_MAX_US 5100
+#define PCIE_CLK_EN_DELAY_MIN_US 30
+#define PCIE_CLK_EN_DELAY_MAX_US 50
+
+#define USB3_RST_ASSERT_DELAY_MIN_US 1
+#define USB3_RST_ASSERT_DELAY_MAX_US 5
+#define USB3_CLK_EN_DELAY_MIN_US 35
+#define USB3_CLK_EN_DELAY_MAX_US 40
#define CDR_CTRL_REG_1 0x80
#define CDR_CTRL_REG_2 0x84
@@ -39,10 +45,13 @@
#define PCIE_USB_COMBO_PHY_CFG_EIOS_DTCT_REG 0x3e4
#define PCIE_USB_COMBO_PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME 0x3e8
+#define TCSR_USB_MUX_SEL BIT(0)
+
+#define PHY_IS_USB3(phy) ((phy)->data->phy_type == PHY_TYPE_USB3)
+
enum qcom_uniphy_type {
PHY_TYPE_PCIE = 1,
- PHY_TYPE_PCIE_GEN2,
- PHY_TYPE_PCIE_GEN3,
+ PHY_TYPE_USB3,
};
struct qcom_uniphy_regs {
@@ -68,6 +77,9 @@ struct qcom_uniphy {
int num_resets;
void __iomem *base;
int lanes;
+ struct regulator *vreg;
+ struct regmap *tcsr;
+ unsigned int mux_offset;
};
#define PHY_INIT_CFG(o, v) \
@@ -89,23 +101,39 @@ static const struct qcom_uniphy_regs ipq5018_pcie_regs[] = {
PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_PCS_INTERNAL_CONTROL_2, 0xf101),
};
+static const struct qcom_uniphy_regs ipq5018_usb_regs[] = {
+ PHY_INIT_CFG(SSCG_CTRL_REG_4, 0x1cb9),
+ PHY_INIT_CFG(SSCG_CTRL_REG_5, 0x023a),
+ PHY_INIT_CFG(SSCG_CTRL_REG_3, 0xd360),
+ PHY_INIT_CFG(SSCG_CTRL_REG_1, 0x1),
+ PHY_INIT_CFG(SSCG_CTRL_REG_2, 0xeb),
+};
+
static const struct qcom_uniphy_regs ipq5332_pcie_regs[] = {
PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_PLLCFG, 0x30),
PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_EIOS_DTCT_REG, 0x53ef),
PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME, 0xcf),
};
-static const struct qcom_uniphy_data ipq5018_data = {
+static const struct qcom_uniphy_data ipq5018_pcie_data = {
.lane_offset = 0x800,
- .phy_type = PHY_TYPE_PCIE_GEN2,
+ .phy_type = PHY_TYPE_PCIE,
.init_seq = ipq5018_pcie_regs,
.init_seq_num = ARRAY_SIZE(ipq5018_pcie_regs),
.pipe_clk_rate = 125 * MEGA,
};
-static const struct qcom_uniphy_data ipq5332_data = {
+static const struct qcom_uniphy_data ipq5018_usb_data = {
.lane_offset = 0x800,
- .phy_type = PHY_TYPE_PCIE_GEN3,
+ .phy_type = PHY_TYPE_USB3,
+ .init_seq = ipq5018_usb_regs,
+ .init_seq_num = ARRAY_SIZE(ipq5018_usb_regs),
+ .pipe_clk_rate = 250 * MEGA,
+};
+
+static const struct qcom_uniphy_data ipq5332_pcie_data = {
+ .lane_offset = 0x800,
+ .phy_type = PHY_TYPE_PCIE,
.init_seq = ipq5332_pcie_regs,
.init_seq_num = ARRAY_SIZE(ipq5332_pcie_regs),
.pipe_clk_rate = 250 * MEGA,
@@ -134,29 +162,49 @@ static int qcom_uniphy_pcie_usb3_power_off(struct phy *x)
clk_bulk_disable_unprepare(phy->num_clks, phy->clks);
- return reset_control_bulk_assert(phy->num_resets, phy->resets);
+ reset_control_bulk_assert(phy->num_resets, phy->resets);
+
+ if (PHY_IS_USB3(phy))
+ regulator_disable(phy->vreg);
+
+ return 0;
}
static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
{
struct qcom_uniphy *phy = phy_get_drvdata(x);
+ bool is_usb3 = PHY_IS_USB3(phy);
int ret;
+ if (is_usb3) {
+ ret = regulator_enable(phy->vreg);
+ if (ret) {
+ dev_err(phy->dev, "failed to enable regulator: %d\n", ret);
+ return ret;
+ }
+ }
+
ret = reset_control_bulk_assert(phy->num_resets, phy->resets);
if (ret) {
dev_err(phy->dev, "failed to assert reset: %d\n", ret);
- return ret;
+ goto err_disable_regulator;
}
- usleep_range(RST_ASSERT_DELAY_MIN_US, RST_ASSERT_DELAY_MAX_US);
+ if (is_usb3)
+ usleep_range(USB3_RST_ASSERT_DELAY_MIN_US,
+ USB3_RST_ASSERT_DELAY_MAX_US);
+ else
+ usleep_range(PCIE_RST_ASSERT_DELAY_MIN_US,
+ PCIE_RST_ASSERT_DELAY_MAX_US);
ret = reset_control_bulk_deassert(phy->num_resets, phy->resets);
if (ret) {
dev_err(phy->dev, "failed to deassert reset: %d\n", ret);
- return ret;
+ goto err_disable_regulator;
}
- usleep_range(PIPE_CLK_DELAY_MIN_US, PIPE_CLK_DELAY_MAX_US);
+ if (!is_usb3)
+ usleep_range(PCIE_PIPE_CLK_DELAY_MIN_US, PCIE_PIPE_CLK_DELAY_MAX_US);
ret = clk_bulk_prepare_enable(phy->num_clks, phy->clks);
if (ret) {
@@ -164,7 +212,10 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
goto err_assert_resets;
}
- usleep_range(CLK_EN_DELAY_MIN_US, CLK_EN_DELAY_MAX_US);
+ if (is_usb3)
+ usleep_range(USB3_CLK_EN_DELAY_MIN_US, USB3_CLK_EN_DELAY_MAX_US);
+ else
+ usleep_range(PCIE_CLK_EN_DELAY_MIN_US, PCIE_CLK_EN_DELAY_MAX_US);
qcom_uniphy_pcie_usb3_init(phy);
@@ -172,6 +223,9 @@ static int qcom_uniphy_pcie_usb3_power_on(struct phy *x)
err_assert_resets:
reset_control_bulk_assert(phy->num_resets, phy->resets);
+err_disable_regulator:
+ if (is_usb3)
+ regulator_disable(phy->vreg);
return ret;
}
@@ -181,7 +235,7 @@ static inline int qcom_uniphy_pcie_usb3_get_resources(struct platform_device *pd
{
struct device *dev = phy->dev;
struct resource *res;
- int i, count;
+ int i, count, ret;
phy->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(phy->base))
@@ -207,6 +261,33 @@ static inline int qcom_uniphy_pcie_usb3_get_resources(struct platform_device *pd
phy->num_resets = count;
+ if (PHY_IS_USB3(phy)) {
+ phy->vreg = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(phy->vreg)) {
+ dev_err(dev, "failed to get regulator: %ld\n",
+ PTR_ERR(phy->vreg));
+ return PTR_ERR(phy->vreg);
+ }
+
+ phy->tcsr = syscon_regmap_lookup_by_phandle_args(dev->of_node,
+ "qcom,phy-usb-mux-sel",
+ 1, &phy->mux_offset);
+ if (IS_ERR(phy->tcsr)) {
+ ret = PTR_ERR(phy->tcsr);
+ dev_err(dev, "failed to get regmap: %d\n", ret);
+ return ret;
+ }
+
+ phy->lanes = 1;
+ } else {
+ ret = of_property_read_u32(dev_of_node(dev), "num-lanes",
+ &phy->lanes);
+ if (ret) {
+ dev_err(dev, "Couldn't read num-lanes: %d\n", ret);
+ return ret;
+ }
+ }
+
return 0;
}
@@ -234,7 +315,8 @@ static inline int phy_pipe_clk_register(struct qcom_uniphy *phy, int id)
struct clk_hw *hw;
char name[64];
- snprintf(name, sizeof(name), "phy%d_pipe_clk_src", id);
+ snprintf(name, sizeof(name), "%sphy%d_pipe_clk_src",
+ (PHY_IS_USB3(phy)) ? "usb" : "", id);
hw = devm_clk_hw_register_fixed_rate(phy->dev, name, NULL, 0,
data->pipe_clk_rate);
if (IS_ERR(hw))
@@ -244,15 +326,25 @@ static inline int phy_pipe_clk_register(struct qcom_uniphy *phy, int id)
return devm_of_clk_add_hw_provider(phy->dev, of_clk_hw_simple_get, hw);
}
+static int qcom_uniphy_usb_mux_select(struct qcom_uniphy *phy, bool enable)
+{
+ return regmap_update_bits(phy->tcsr, phy->mux_offset,
+ TCSR_USB_MUX_SEL,
+ enable ? TCSR_USB_MUX_SEL : 0);
+}
+
static const struct of_device_id qcom_uniphy_pcie_usb3_id_table[] = {
{
.compatible = "qcom,ipq5018-uniphy-pcie-phy",
- .data = &ipq5018_data,
+ .data = &ipq5018_pcie_data,
+ }, {
+ .compatible = "qcom,ipq5018-uniphy-usb3-phy",
+ .data = &ipq5018_usb_data,
}, {
.compatible = "qcom,ipq5332-uniphy-pcie-phy",
- .data = &ipq5332_data,
+ .data = &ipq5332_pcie_data,
},
- { },
+ { }
};
MODULE_DEVICE_TABLE(of, qcom_uniphy_pcie_usb3_id_table);
@@ -281,10 +373,6 @@ static int qcom_uniphy_pcie_usb3_probe(struct platform_device *pdev)
if (!phy->data)
return -EINVAL;
- ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &phy->lanes);
- if (ret)
- return dev_err_probe(dev, ret, "Couldn't read num-lanes\n");
-
ret = qcom_uniphy_pcie_usb3_get_resources(pdev, phy);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
@@ -305,6 +393,18 @@ static int qcom_uniphy_pcie_usb3_probe(struct platform_device *pdev)
if (IS_ERR(phy_provider))
return PTR_ERR(phy_provider);
+ /*
+ * Select USB mux before the controller comes out of reset. Selecting it
+ * later in .power_on leaves the SuperSpeed pads muxed away while the
+ * controller resets, and the SS link training remains in Rx.Detect
+ */
+ if (PHY_IS_USB3(phy)) {
+ ret = qcom_uniphy_usb_mux_select(phy, true);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to select usb mux\n");
+ }
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 08/12] arm64: dts: qcom: ipq5018: Add USB Super-Speed PHY node
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (6 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 07/12] phy: qualcomm: qcom-uniphy-pcie-usb3-28lp: Add support for USB3 PHY on IPQ5018 George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 09/12] dt-bindings: usb: qcom,snps-dwc3: Add clocks for USB3 on Qualcomm IPQ5018 George Moussalem via B4 Relay
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Add the USB3 PHY node and populate the USB DT clock on the GCC node for
the GCC to gate the PIPE clock supplied by the USB3 PHY.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
index 71834606535e..7638299671d8 100644
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -179,6 +179,23 @@ usbphy0: phy@5b000 {
status = "disabled";
};
+ usbphy1: phy@5d000 {
+ compatible = "qcom,ipq5018-uniphy-usb3-phy";
+ reg = <0x0005d000 0x800>;
+
+ clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>,
+ <&gcc GCC_USB0_PIPE_CLK>;
+
+ resets = <&gcc GCC_USB0_PHY_BCR>;
+
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+
+ qcom,phy-usb-mux-sel = <&tcsr 0x10540>;
+
+ status = "disabled";
+ };
+
pcie1_phy: phy@7e000 {
compatible = "qcom,ipq5018-uniphy-pcie-phy";
reg = <0x0007e000 0x800>;
@@ -436,7 +453,7 @@ gcc: clock-controller@1800000 {
<&sleep_clk>,
<&pcie0_phy>,
<&pcie1_phy>,
- <0>,
+ <&usbphy1>,
<&gephy_rx_clk>,
<&gephy_tx_clk>,
<0>,
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 09/12] dt-bindings: usb: qcom,snps-dwc3: Add clocks for USB3 on Qualcomm IPQ5018
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (7 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 08/12] arm64: dts: qcom: ipq5018: Add USB Super-Speed PHY node George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 10/12] arm64: dts: qcom: ipq5018: Add clocks required for USB3 support George Moussalem via B4 Relay
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
Krzysztof Kozlowski, George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Add aux and lfps clocks in Qualcomm IPQ5018. These clocks are required
only for USB Super-Speed support.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../devicetree/bindings/usb/qcom,snps-dwc3.yaml | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
index aa263dfd42a1..97dd0cefd732 100644
--- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
@@ -194,6 +194,26 @@ allOf:
- const: sleep
- const: mock_utmi
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5018-dwc3
+ then:
+ properties:
+ clocks:
+ minItems: 6
+ maxItems: 6
+ clock-names:
+ items:
+ - const: core
+ - const: iface
+ - const: sleep
+ - const: mock_utmi
+ - const: aux
+ - const: lfps
+
- if:
properties:
compatible:
@@ -295,7 +315,6 @@ allOf:
compatible:
contains:
enum:
- - qcom,ipq5018-dwc3
- qcom,msm8994-dwc3
- qcom,qcs404-dwc3
then:
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 10/12] arm64: dts: qcom: ipq5018: Add clocks required for USB3 support
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (8 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 09/12] dt-bindings: usb: qcom,snps-dwc3: Add clocks for USB3 on Qualcomm IPQ5018 George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 11/12] arm64: dts: qcom: ipq5018: Add Super-Speed UNIPHY to USB node George Moussalem via B4 Relay
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
Dmitry Baryshkov, George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Add aux and lfps clocks to USB controller node for Super-Speed support.
These clocks are required for USB3 mode only and are not needed for USB2
mode.
In addition, set UTMI clock frequency to ensure it's parented correctly
and override the clock rate potentially set by the bootloader.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
index 7638299671d8..7f730c2ab763 100644
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -604,11 +604,15 @@ usb: usb@8a00000 {
clocks = <&gcc GCC_USB0_MASTER_CLK>,
<&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
<&gcc GCC_USB0_SLEEP_CLK>,
- <&gcc GCC_USB0_MOCK_UTMI_CLK>;
+ <&gcc GCC_USB0_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB0_AUX_CLK>,
+ <&gcc GCC_USB0_LFPS_CLK>;
clock-names = "core",
"iface",
"sleep",
- "mock_utmi";
+ "mock_utmi",
+ "aux",
+ "lfps";
assigned-clocks = <&gcc GCC_USB0_MOCK_UTMI_CLK>;
assigned-clock-rates = <60000000>;
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 11/12] arm64: dts: qcom: ipq5018: Add Super-Speed UNIPHY to USB node
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (9 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 10/12] arm64: dts: qcom: ipq5018: Add clocks required for USB3 support George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-25 12:37 ` [PATCH v3 12/12] arm64: dts: qcom: ipq5018: Enable USB Super-Speed PHY George Moussalem via B4 Relay
2026-08-27 19:06 ` [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 Stanislaw Pal
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Add the USB3 UNIPHY to the USB controller node for USB3 support.
In addition, switch to the pipe clock supplied by the USB3 UNIPHY
instead of the UTMI clock.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
index 7f730c2ab763..1f55b0ba5c9d 100644
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -627,10 +627,9 @@ usb: usb@8a00000 {
resets = <&gcc GCC_USB0_BCR>;
- phys = <&usbphy0>;
- phy-names = "usb2-phy";
+ phys = <&usbphy0>, <&usbphy1>;
+ phy-names = "usb2-phy", "usb3-phy";
- qcom,select-utmi-as-pipe-clk;
qcom,select-utmi-as-ref-clk;
tx-fifo-resize;
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v3 12/12] arm64: dts: qcom: ipq5018: Enable USB Super-Speed PHY
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (10 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 11/12] arm64: dts: qcom: ipq5018: Add Super-Speed UNIPHY to USB node George Moussalem via B4 Relay
@ 2026-08-25 12:37 ` George Moussalem via B4 Relay
2026-08-27 19:06 ` [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 Stanislaw Pal
12 siblings, 0 replies; 16+ messages in thread
From: George Moussalem via B4 Relay @ 2026-08-25 12:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Praveenkumar I, Philipp Zabel, Bjorn Andersson,
Konrad Dybcio, Greg Kroah-Hartman, Varadarajan Narayanan,
Nitheesh Sekar, Wesley Cheng, Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-usb,
George Moussalem
From: George Moussalem <george.moussalem@outlook.com>
Add the 5V supply regulator and enable USB Super-Speed PHY support.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts b/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts
index 8efb2b21ed9e..ca29f271e673 100644
--- a/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts
+++ b/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts
@@ -22,6 +22,14 @@ aliases {
chosen {
stdout-path = "serial0:115200n8";
};
+
+ regulator_fixed_5p0: regulator-s0500 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "fixed_5p0";
+ gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
+ };
};
&blsp1_uart1 {
@@ -119,6 +127,12 @@ &usbphy0 {
status = "okay";
};
+&usbphy1 {
+ vdd-supply = <®ulator_fixed_5p0>;
+
+ status = "okay";
+};
+
&xo_board_clk {
clock-div = <4>;
clock-mult = <1>;
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018
2026-08-25 12:37 [PATCH v3 00/12] Enable USB3 for Qualcomm IPQ5018 George Moussalem via B4 Relay
` (11 preceding siblings ...)
2026-08-25 12:37 ` [PATCH v3 12/12] arm64: dts: qcom: ipq5018: Enable USB Super-Speed PHY George Moussalem via B4 Relay
@ 2026-08-27 19:06 ` Stanislaw Pal
12 siblings, 0 replies; 16+ messages in thread
From: Stanislaw Pal @ 2026-08-27 19:06 UTC (permalink / raw)
To: George Moussalem, Vinod Koul, Neil Armstrong, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Praveenkumar I, Philipp Zabel,
Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
Varadarajan Narayanan, Nitheesh Sekar, Wesley Cheng,
Manivannan Sadhasivam
Cc: linux-arm-msm, linux-phy, devicetree, linux-usb, linux-kernel
Tested this revision on IPQ5018 hardware - a TP-Link Archer AX55 v1,
backported onto 6.18.44. Both radios on this board are on AHB and PCIe
is unused, so nothing else contends for the SS PHY; the combo driver is
exercised purely on its USB3 side here.
Two USB 3.2 gen 1 sticks, all enumerating SuperSpeed (speed=5000,
version=3.20, 5000M in lsusb -t):
- hot-plug, both sticks;
- warm reboot with the stick inserted - SuperSpeed 0.8 s after xHCI
registers;
- cold power-on with the stick inserted - same, no fall back to
480M;
- 130 MB/s sustained over a 3 GB raw read, unchanged from the
previous revision on the same stick;
- no USB or xHCI error in dmesg across the whole run.
I also exercised the vdd-supply path that patch 12 adds to the RDP432-C2,
since enable/disable sits in phy_init/phy_shutdown and that is the code
this revision rewrites: unbinding dwc3-qcom drops the port's 5 V rail and
the device disappears, re-binding brings it back at SuperSpeed 1.8 s
later. Works on this board too.
I do not have an IPQ5332, so the combo PHY's PCIe side and the 5332
instance are untested by me.
Tested-by: Stanislaw Pal <kuncy7@gmail.com>
^ permalink raw reply [flat|nested] 16+ messages in thread