qualcommax: ipq50xx: add support for USB3

Add driver support for the Qualcomm UNIPHY USB Super-Speed 22ULL PHY
found on IPQ5018/IPQ5332 SoCs. Add the PHY and required AUX and LFPS
clocks to the USB controller node currently supporting USB2 mode only to
add USB3 support.

Signed-off-by: George Moussalem <george.moussalem@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/24556
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
George Moussalem authored and Robert Marko committed 2026-08-18 14:57:47 +02:00
1 parent 6b98618527
commit 409bf967e4
11 files changed
+840 -3

No files matched your search

+1
View File
@@ -365,6 +365,7 @@ CONFIG_PHY_QCOM_QMP_USB=y
CONFIG_PHY_QCOM_QUSB2=y
# CONFIG_PHY_QCOM_SGMII_ETH is not set
# CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP is not set
# CONFIG_PHY_QCOM_UNIPHY_USB_22ULL is not set
# CONFIG_PHY_QCOM_USB_HS_28NM is not set
# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set
# CONFIG_PHY_QCOM_USB_SS is not set
@@ -12,6 +12,7 @@ CONFIG_NET_PTP_CLASSIFY=y
CONFIG_PCS_XPCS=y
CONFIG_PHY_QCOM_M31_USB=y
CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP=y
CONFIG_PHY_QCOM_UNIPHY_USB_22ULL=y
CONFIG_PINCTRL_IPQ5018=y
CONFIG_POLYNOMIAL=y
CONFIG_PPS=y
@@ -0,0 +1,55 @@
From db0635a30462f6dbdc7284a712f65ec5345a0caa Mon Sep 17 00:00:00 2001
From: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Date: Tue, 6 Jan 2026 19:50:13 +0100
Subject: [PATCH] dt-bindings: usb: qcom,dwc3: Correct IPQ5018 interrupts
According to reference manual, IPQ5018 does not have QUSB2 PHY and its
interrupts should rather match ones used in IPQ5332 (so power_event,
eud_dmse_int_mx, eud_dpse_int_mx).
Fixes: 53c6d854be4e ("dt-bindings: usb: dwc3: Clean up hs_phy_irq in binding")
Fixes: 6e762f7b8edc ("dt-bindings: usb: Introduce qcom,snps-dwc3")
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Link: https://patch.msgid.link/20260106185012.19551-3-krzysztof.kozlowski@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 2 +-
Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
@@ -406,7 +406,6 @@ allOf:
compatible:
contains:
enum:
- - qcom,ipq5018-dwc3
- qcom,ipq6018-dwc3
- qcom,ipq8074-dwc3
- qcom,msm8953-dwc3
@@ -451,6 +450,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,ipq5018-dwc3
- qcom,ipq5332-dwc3
then:
properties:
--- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
@@ -392,7 +392,6 @@ allOf:
compatible:
contains:
enum:
- - qcom,ipq5018-dwc3
- qcom,ipq6018-dwc3
- qcom,ipq8074-dwc3
- qcom,msm8953-dwc3
@@ -439,6 +438,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,ipq5018-dwc3
- qcom,ipq5332-dwc3
then:
properties:
@@ -0,0 +1,132 @@
From 4275b7e1114aaf6aadc020c8fd6c4626dd22c411 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <quic_ipkumar@quicinc.com>
Date: Wed, 12 Aug 2026 20:36:26 +0400
Subject: [PATCH v3 01/15] dt-bindings: phy: Document the Qualcomm IPQ5332 UNIPHY USB Super-speed PHY
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-1-5ea9cc800088@outlook.com>
Document the Qualcomm USB3 22ull UNIPHY present in the IPQ5018 and
IPQ5332 SoCs.
Signed-off-by: Praveenkumar I <quic_ipkumar@quicinc.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../phy/qcom,ipq5332-uniphy-usb-ss-phy.yaml | 111 +++++++++++++++++++++
1 file changed, 111 insertions(+)
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-usb-ss-phy.yaml
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,ipq5332-uniphy-usb-ss-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm UNIPHY USB Super-Speed 22ull PHY
+
+maintainers:
+ - Praveenkumar I <quic_ipkumar@quicinc.com>
+ - Varadarajan Narayanan <quic_varada@quicinc.com>
+
+description:
+ USB Super-Speed UNIPHY found in Qualcomm IPQ5018 & IPQ5332 SoCs.
+
+properties:
+ compatible:
+ enum:
+ - qcom,ipq5018-uniphy-usb-ss-phy
+ - qcom,ipq5332-uniphy-usb-ss-phy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 2
+ maxItems: 3
+
+ resets:
+ maxItems: 1
+
+ vdd-supply:
+ description:
+ Phandle to 5V regulator supply to PHY digital circuit.
+
+ qcom,phy-usb-mux-sel:
+ description: |
+ Mux selection for USB PHY. The USB3 and PCIe PHY pads are muxed and the
+ mux selection is done via a register in TCSR syscon.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle of TCSR syscon
+ - description: offset of PHY mux selection register
+
+ "#clock-cells":
+ const: 0
+
+ "#phy-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - vdd-supply
+ - qcom,phy-usb-mux-sel
+ - "#clock-cells"
+ - "#phy-cells"
+
+additionalProperties: false
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5018-uniphy-usb-ss-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: USB3 PHY CFG AHB clock
+ - description: USB3 pipe clock
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5332-uniphy-usb-ss-phy
+ then:
+ properties:
+ clocks:
+ items:
+ - description: Shared PCIe/USB3 PHY AHB clock
+ - description: USB3 PHY CFG AHB clock
+ - description: USB3 pipe clock
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,ipq5332-gcc.h>
+
+ phy@4b0000 {
+ compatible = "qcom,ipq5332-uniphy-usb-ss-phy";
+ reg = <0x4b0000 0x800>;
+
+ clocks = <&gcc GCC_PCIE3X1_PHY_AHB_CLK>,
+ <&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>;
+
+ vdd-supply = <&regulator_fixed_5p0>;
+ };
@@ -0,0 +1,362 @@
From 748ee8ce426246e43bd96b5df5f1d58f1dd0bb68 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <quic_ipkumar@quicinc.com>
Date: Wed, 12 Aug 2026 20:37:26 +0400
Subject: [PATCH v3 02/15] phy: qcom: Introduce Qualcomm IPQ5332 Super-Speed USB UNIPHY driver
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-2-9e9f617e231d@outlook.com>
Adds Qualcomm 22ull Super-Speed USB UNIPHY driver support which is
present in Qualcomm IPQ5018 & IPQ5332 SoCs.
This PHY is interfaced with SNPS DWC3 USB and SNPS DWC PCIe. Either one
of the interface can use the it and selection is done via mux present in
TCSR register. By default, the PHY is configured for PCIe interface and
needs this driver to configure the mux for USB.
Signed-off-by: Praveenkumar I <quic_ipkumar@quicinc.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
drivers/phy/qualcomm/Kconfig | 11 +
drivers/phy/qualcomm/Makefile | 1 +
.../phy/qualcomm/phy-qcom-uniphy-usb-ss-22ull.c | 304 +++++++++++++++++++++
3 files changed, 316 insertions(+)
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -158,6 +158,17 @@ config PHY_QCOM_UNIPHY_PCIE_28LP
handles PHY initialization, clock management required after
resetting the hardware and power management.
+config PHY_QCOM_UNIPHY_USB_22ULL
+ tristate "Qualcomm IPQ5332 UNIPHY USB Super-Speed 22ull driver"
+ depends on USB && (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_M31_EUSB
tristate "Qualcomm M31 eUSB2 PHY driver support"
depends on USB && (ARCH_QCOM || COMPILE_TEST)
--- a/drivers/phy/qualcomm/Makefile
+++ b/drivers/phy/qualcomm/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PHY_QCOM_QMP_USB_LEGACY) +=
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_USB_22ULL) += phy-qcom-uniphy-usb-ss-22ull.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
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-usb-ss-22ull.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+
+#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_MISC1 0x214
+#define PCIE_USB_COMBO_PHY_CFG_RX_AFE_2 0x7C4
+#define PCIE_USB_COMBO_PHY_CFG_RX_DLF_DEMUX_2 0x7E8
+
+#define TCSR_USB_MUX_SEL BIT(0)
+
+struct phy_init_tbl {
+ unsigned int offset;
+ unsigned int val;
+};
+
+struct uniphy_cfg {
+ const struct phy_init_tbl *init_seq;
+ int num_init_seq;
+ u32 pipe_clk_rate;
+};
+
+struct uniphy_usb {
+ struct device *dev;
+ const struct uniphy_cfg *cfg;
+ struct phy *phy;
+ void __iomem *base;
+ struct clk_bulk_data *clks;
+ unsigned int num_clks;
+ struct reset_control *reset;
+ struct regulator *vreg;
+ struct regmap *tcsr;
+ unsigned int mux_offset;
+};
+
+#define PHY_INIT_CFG(o, v) \
+ { \
+ .offset = o, \
+ .val = v, \
+ }
+
+static const struct phy_init_tbl ipq5018_usb_uniphy_init_tbl[] = {
+ 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 phy_init_tbl ipq5332_usb_uniphy_init_tbl[] = {
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_RX_AFE_2, 0x1076),
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_RX_DLF_DEMUX_2, 0x3142),
+ PHY_INIT_CFG(PCIE_USB_COMBO_PHY_CFG_MISC1, 0x3),
+};
+
+static const struct uniphy_cfg ipq5018_cfg = {
+ .init_seq = ipq5018_usb_uniphy_init_tbl,
+ .num_init_seq = ARRAY_SIZE(ipq5018_usb_uniphy_init_tbl),
+ .pipe_clk_rate = 250000000,
+};
+
+static const struct uniphy_cfg ipq5332_cfg = {
+ .init_seq = ipq5332_usb_uniphy_init_tbl,
+ .num_init_seq = ARRAY_SIZE(ipq5332_usb_uniphy_init_tbl),
+ .pipe_clk_rate = 250000000,
+};
+
+static int uniphy_usb_init(struct phy *phy)
+{
+ struct uniphy_usb *uniphy = phy_get_drvdata(phy);
+ const struct uniphy_cfg *cfg = uniphy->cfg;
+ const struct phy_init_tbl *tbl = cfg->init_seq;
+ void __iomem *base = uniphy->base;
+ struct device *dev = uniphy->dev;
+ int i, ret;
+
+ ret = regulator_enable(uniphy->vreg);
+ if (ret) {
+ dev_err(dev, "failed to enable regulator: %d\n", ret);
+ return ret;
+ }
+
+ /* Perform phy reset */
+ ret = reset_control_assert(uniphy->reset);
+ if (ret) {
+ dev_err(dev, "Failed to assert reset: %d\n", ret);
+ goto err_disable_regulator;
+ }
+
+ usleep_range(1, 5);
+
+ ret = reset_control_deassert(uniphy->reset);
+ if (ret) {
+ dev_err(dev, "Failed to deassert reset: %d\n", ret);
+ goto err_assert_reset;
+ }
+
+ ret = clk_bulk_prepare_enable(uniphy->num_clks, uniphy->clks);
+ if (ret) {
+ dev_err(dev, "failed to enable clocks: %d\n", ret);
+ goto err_assert_reset;
+ }
+
+ /* phy autoload delay */
+ usleep_range(35, 40);
+
+ for (i = 0; i < cfg->num_init_seq; i++)
+ writel(tbl[i].val, base + tbl[i].offset);
+
+ return 0;
+
+err_assert_reset:
+ /* Assert phy reset */
+ reset_control_assert(uniphy->reset);
+
+err_disable_regulator:
+ regulator_disable(uniphy->vreg);
+
+ return ret;
+}
+
+static int uniphy_usb_shutdown(struct phy *phy)
+{
+ struct uniphy_usb *uniphy = phy_get_drvdata(phy);
+
+ clk_bulk_disable_unprepare(uniphy->num_clks, uniphy->clks);
+
+ /* Assert phy reset */
+ reset_control_assert(uniphy->reset);
+
+ regulator_disable(uniphy->vreg);
+
+ return 0;
+}
+
+static const struct phy_ops uniphy_usb_ops = {
+ .power_on = uniphy_usb_init,
+ .power_off = uniphy_usb_shutdown,
+ .owner = THIS_MODULE,
+};
+
+/*
+ * Register a fixed rate pipe clock.
+ *
+ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
+ * controls it. The <s>_pipe_clk coming out of the GCC is requested
+ * by the PHY driver for its operations.
+ * We register the <s>_pipe_clksrc here. The gcc driver takes care
+ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
+ * Below picture shows this relationship.
+ *
+ * +---------------+
+ * | PHY block |<<---------------------------------------+
+ * | | |
+ * | +-------+ | +-----+ |
+ * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
+ * clk | +-------+ | +-----+
+ * +---------------+
+ */
+static int phy_pipe_clk_register(struct uniphy_usb *uniphy, int id)
+{
+ struct device *dev = uniphy->dev;
+ struct clk_hw *hw;
+ char name[64];
+
+ snprintf(name, sizeof(name), "usbphy%d_pipe_clk_src", id);
+ hw = devm_clk_hw_register_fixed_rate(dev, name, NULL, 0,
+ uniphy->cfg->pipe_clk_rate);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
+}
+
+static int qcom_uniphy_usb_mux_select(struct uniphy_usb *uniphy, bool enable)
+{
+ return regmap_update_bits(uniphy->tcsr, uniphy->mux_offset,
+ TCSR_USB_MUX_SEL,
+ enable ? TCSR_USB_MUX_SEL : 0);
+}
+
+static int qcom_uniphy_usb_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct uniphy_usb *uniphy;
+ int ret;
+
+ uniphy = devm_kzalloc(dev, sizeof(*uniphy), GFP_KERNEL);
+ if (!uniphy)
+ return -ENOMEM;
+
+ uniphy->dev = dev;
+
+ uniphy->cfg = of_device_get_match_data(dev);
+ if (!uniphy->cfg)
+ return -EINVAL;
+
+ uniphy->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(uniphy->base))
+ return dev_err_probe(dev, PTR_ERR(uniphy->base),
+ "failed to map base\n");
+
+ ret = devm_clk_bulk_get_all(dev, &uniphy->clks);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "failed to get clocks\n");
+
+ uniphy->num_clks = ret;
+
+ uniphy->reset = devm_reset_control_get_exclusive_by_index(dev, 0);
+ if (IS_ERR(uniphy->reset))
+ return dev_err_probe(dev, PTR_ERR(uniphy->reset),
+ "failed to get reset\n");
+
+ uniphy->vreg = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(uniphy->vreg))
+ return dev_err_probe(dev, PTR_ERR(uniphy->vreg),
+ "failed to get vreg\n");
+
+ uniphy->tcsr = syscon_regmap_lookup_by_phandle_args(dev->of_node,
+ "qcom,phy-usb-mux-sel",
+ 1, &uniphy->mux_offset);
+ if (IS_ERR(uniphy->tcsr))
+ return dev_err_probe(dev, PTR_ERR(uniphy->tcsr),
+ "failed to get regmap\n");
+
+ uniphy->phy = devm_phy_create(dev, NULL, &uniphy_usb_ops);
+ if (IS_ERR(uniphy->phy))
+ return dev_err_probe(dev, PTR_ERR(uniphy->phy),
+ "failed to create PHY\n");
+
+ ret = phy_pipe_clk_register(uniphy, uniphy->phy->id);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register pipe clk\n");
+
+ phy_set_drvdata(uniphy->phy, uniphy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider))
+ return dev_err_probe(dev, PTR_ERR(phy_provider),
+ "failed to register PHY provider\n");
+
+ /*
+ * Select the USB position of the phy mux before anything comes out
+ * of reset. Selecting it later leaves the SuperSpeed pads muxed away
+ * while the controller resets, and the SS link doesn't train and is
+ * stuck in Rx.Detect (USB2 is unaffected as it isn't muxed).
+ */
+ ret = qcom_uniphy_usb_mux_select(uniphy, true);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to select USB mux\n");
+
+ platform_set_drvdata(pdev, uniphy);
+
+ return 0;
+}
+
+static void qcom_uniphy_usb_remove(struct platform_device *pdev)
+{
+ struct uniphy_usb *uniphy = platform_get_drvdata(pdev);
+
+ qcom_uniphy_usb_mux_select(uniphy, false);
+}
+
+static const struct of_device_id qcom_uniphy_usb_of_match[] = {
+ { .compatible = "qcom,ipq5018-uniphy-usb-ss-phy", .data = &ipq5018_cfg},
+ { .compatible = "qcom,ipq5332-uniphy-usb-ss-phy", .data = &ipq5332_cfg},
+ { },
+};
+MODULE_DEVICE_TABLE(of, qcom_uniphy_usb_of_match);
+
+static struct platform_driver qcom_uniphy_usb_driver = {
+ .probe = qcom_uniphy_usb_probe,
+ .remove = qcom_uniphy_usb_remove,
+ .driver = {
+ .of_match_table = qcom_uniphy_usb_of_match,
+ .name = "qcom,uniphy-usb-ss-phy",
+ }
+};
+module_platform_driver(qcom_uniphy_usb_driver);
+
+MODULE_DESCRIPTION("Qualcomm UNIPHY Super-Speed USB PHY driver");
+MODULE_LICENSE("GPL");
@@ -0,0 +1,52 @@
From 28afa01b1d5ccb39b11973f87095f50c0a2c6cbe Mon Sep 17 00:00:00 2001
From: George Moussalem <george.moussalem@outlook.com>
Date: Wed, 12 Aug 2026 20:37:28 +0400
Subject: [PATCH v3 04/15] arm64: dts: qcom: ipq5018: Add USB Super-Speed PHY node
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-4-9e9f617e231d@outlook.com>
Add USB Super-Speed UNIPHY 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(-)
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -189,6 +189,23 @@
status = "disabled";
};
+ usbphy1: phy@5d000 {
+ compatible = "qcom,ipq5018-uniphy-usb-ss-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>;
@@ -446,7 +463,7 @@
<&sleep_clk>,
<&pcie0_phy>,
<&pcie1_phy>,
- <0>,
+ <&usbphy1>,
<&gephy_rx_clk>,
<&gephy_tx_clk>,
<0>,
@@ -0,0 +1,104 @@
From 386835aa5d53ef83a968154b72dc89d38f4e74f1 Mon Sep 17 00:00:00 2001
From: George Moussalem <george.moussalem@outlook.com>
Date: Wed, 12 Aug 2026 20:37:30 +0400
Subject: [PATCH v3 06/15] arm64: dts: qcom: ipq5018: Flatten usb controller node
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-6-9e9f617e231d@outlook.com>
Flatten usb controller node and update to using latest bindings and
flattened driver approach.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts | 6 ++--
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 49 +++++++++++---------------
2 files changed, 23 insertions(+), 32 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts
+++ b/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts
@@ -108,11 +108,9 @@
};
&usb {
- status = "okay";
-};
-
-&usb_dwc {
dr_mode = "host";
+
+ status = "okay";
};
&usbphy0 {
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -607,16 +607,9 @@
status = "disabled";
};
- usb: usb@8af8800 {
- compatible = "qcom,ipq5018-dwc3", "qcom,dwc3";
- reg = <0x08af8800 0x400>;
-
- interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "pwr_event",
- "dp_hs_phy_irq",
- "dm_hs_phy_irq";
+ usb: usb@8a00000 {
+ compatible = "qcom,ipq5018-dwc3", "qcom,snps-dwc3";
+ reg = <0x08a00000 0xfc100>;
clocks = <&gcc GCC_USB0_MASTER_CLK>,
<&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
@@ -627,29 +620,29 @@
"sleep",
"mock_utmi";
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dwc_usb3",
+ "pwr_event",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq";
+
resets = <&gcc GCC_USB0_BCR>;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+
qcom,select-utmi-as-pipe-clk;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- status = "disabled";
+ tx-fifo-resize;
+ snps,is-utmi-l1-suspend;
+ snps,hird-threshold = /bits/ 8 <0x0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_u3_susphy_quirk;
- usb_dwc: usb@8a00000 {
- compatible = "snps,dwc3";
- reg = <0x08a00000 0xe000>;
- clocks = <&gcc GCC_USB0_MOCK_UTMI_CLK>;
- clock-names = "ref";
- interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
- phy-names = "usb2-phy";
- phys = <&usbphy0>;
- tx-fifo-resize;
- snps,is-utmi-l1-suspend;
- snps,hird-threshold = /bits/ 8 <0x0>;
- snps,dis_u2_susphy_quirk;
- snps,dis_u3_susphy_quirk;
- };
+ status = "disabled";
};
intc: interrupt-controller@b000000 {
@@ -0,0 +1,54 @@
From a1f783ff93ea161e679fb21045028f4163b7a0af Mon Sep 17 00:00:00 2001
From: George Moussalem <george.moussalem@outlook.com>
Date: Wed, 12 Aug 2026 20:37:32 +0400
Subject: [PATCH v3 08/15] dt-bindings: usb: qcom,snps-dwc3: Add clocks for USB3 on Qualcomm IPQ5018
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-8-9e9f617e231d@outlook.com>
Add aux and lfps clocks in Qualcomm IPQ5018. These clocks are required
only for USB Super-Speed support.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
.../devicetree/bindings/usb/qcom,snps-dwc3.yaml | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
@@ -183,6 +183,26 @@ allOf:
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:
+ contains:
+ enum:
- qcom,ipq8064-dwc3
then:
properties:
@@ -271,7 +291,6 @@ allOf:
compatible:
contains:
enum:
- - qcom,ipq5018-dwc3
- qcom,msm8994-dwc3
- qcom,qcs404-dwc3
then:
@@ -0,0 +1,43 @@
From 84b2a1e47780b0d9d76c31b52ce00da7386b60ee Mon Sep 17 00:00:00 2001
From: George Moussalem <george.moussalem@outlook.com>
Date: Wed, 12 Aug 2026 20:37:34 +0400
Subject: [PATCH v3 10/15] arm64: dts: qcom: ipq5018: Configure clocks required for USB3 support
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-10-9e9f617e231d@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.
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -614,11 +614,17 @@
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>;
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
@@ -0,0 +1,33 @@
From 5705cbc5b65fbbc9726777dc877f6e748b1e7e20 Mon Sep 17 00:00:00 2001
From: George Moussalem <george.moussalem@outlook.com>
Date: Wed, 12 Aug 2026 20:37:36 +0400
Subject: [PATCH v3 12/15] arm64: dts: qcom: ipq5018: Add Super-Speed UNIPHY to USB node
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Message-Id: <20260812-ipq5018-usb3-v3-12-9e9f617e231d@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 | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -637,10 +637,8 @@
resets = <&gcc GCC_USB0_BCR>;
- phys = <&usbphy0>;
- phy-names = "usb2-phy";
-
- qcom,select-utmi-as-pipe-clk;
+ phys = <&usbphy0>, <&usbphy1>;
+ phy-names = "usb2-phy", "usb3-phy";
tx-fifo-resize;
snps,is-utmi-l1-suspend;
@@ -8,7 +8,7 @@
#include <dt-bindings/reset/qcom,gcc-ipq5018.h>
#include <dt-bindings/thermal/thermal.h>
@@ -258,6 +259,29 @@
@@ -275,6 +276,29 @@
status = "disabled";
};
@@ -38,8 +38,8 @@
cmn_pll: clock-controller@9b000 {
compatible = "qcom,ipq5018-cmn-pll";
reg = <0x0009b000 0x800>;
@@ -449,8 +473,8 @@
<0>,
@@ -466,8 +490,8 @@
<&usbphy1>,
<&gephy_rx_clk>,
<&gephy_tx_clk>,
- <0>,