diff --git a/target/linux/qualcommax/config-6.18 b/target/linux/qualcommax/config-6.18 index b49ea9f8eb8..abb51181c64 100644 --- a/target/linux/qualcommax/config-6.18 +++ b/target/linux/qualcommax/config-6.18 @@ -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 diff --git a/target/linux/qualcommax/ipq50xx/config-default b/target/linux/qualcommax/ipq50xx/config-default index 262f1278d88..cadb1d07467 100644 --- a/target/linux/qualcommax/ipq50xx/config-default +++ b/target/linux/qualcommax/ipq50xx/config-default @@ -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 diff --git a/target/linux/qualcommax/patches-6.18/0091-v6.19-dt-bindings-usb-qcom-snps-dwc3-Correct-IPQ5018-interrupts.patch b/target/linux/qualcommax/patches-6.18/0091-v6.19-dt-bindings-usb-qcom-snps-dwc3-Correct-IPQ5018-interrupts.patch new file mode 100644 index 00000000000..e7522ac05a1 --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0091-v6.19-dt-bindings-usb-qcom-snps-dwc3-Correct-IPQ5018-interrupts.patch @@ -0,0 +1,55 @@ +From db0635a30462f6dbdc7284a712f65ec5345a0caa Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +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 +Link: https://patch.msgid.link/20260106185012.19551-3-krzysztof.kozlowski@oss.qualcomm.com +Signed-off-by: Greg Kroah-Hartman +--- + 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: diff --git a/target/linux/qualcommax/patches-6.18/0821-dt-bindings-phy-document-the-qualcomm-ipq5332-uniphy-usb-super-speed-phy.patch b/target/linux/qualcommax/patches-6.18/0821-dt-bindings-phy-document-the-qualcomm-ipq5332-uniphy-usb-super-speed-phy.patch new file mode 100644 index 00000000000..41f6abff6d6 --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0821-dt-bindings-phy-document-the-qualcomm-ipq5332-uniphy-usb-super-speed-phy.patch @@ -0,0 +1,132 @@ +From 4275b7e1114aaf6aadc020c8fd6c4626dd22c411 Mon Sep 17 00:00:00 2001 +From: Praveenkumar I +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 +Signed-off-by: George Moussalem +--- + .../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 ++ - Varadarajan Narayanan ++ ++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 ++ ++ 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 = <®ulator_fixed_5p0>; ++ }; diff --git a/target/linux/qualcommax/patches-6.18/0822-phy-qcom-introduce-qualcomm-ipq5332-super-speed-usb-uniphy-driver.patch b/target/linux/qualcommax/patches-6.18/0822-phy-qcom-introduce-qualcomm-ipq5332-super-speed-usb-uniphy-driver.patch new file mode 100644 index 00000000000..366795c4259 --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0822-phy-qcom-introduce-qualcomm-ipq5332-super-speed-usb-uniphy-driver.patch @@ -0,0 +1,362 @@ +From 748ee8ce426246e43bd96b5df5f1d58f1dd0bb68 Mon Sep 17 00:00:00 2001 +From: Praveenkumar I +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 +Signed-off-by: George Moussalem +--- + 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 _pipe_clksrc generated by PHY goes to the GCC that gate ++ * controls it. The _pipe_clk coming out of the GCC is requested ++ * by the PHY driver for its operations. ++ * We register the _pipe_clksrc here. The gcc driver takes care ++ * of assigning this _pipe_clksrc as parent to _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"); diff --git a/target/linux/qualcommax/patches-6.18/0823-arm64-dts-qcom-ipq5018-add-usb-super-speed-phy-node.patch b/target/linux/qualcommax/patches-6.18/0823-arm64-dts-qcom-ipq5018-add-usb-super-speed-phy-node.patch new file mode 100644 index 00000000000..2ae64dd6c3a --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0823-arm64-dts-qcom-ipq5018-add-usb-super-speed-phy-node.patch @@ -0,0 +1,52 @@ +From 28afa01b1d5ccb39b11973f87095f50c0a2c6cbe Mon Sep 17 00:00:00 2001 +From: George Moussalem +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 +--- + 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>, diff --git a/target/linux/qualcommax/patches-6.18/0824-arm64-dts-qcom-ipq5018-flatten-usb-controller-node.patch b/target/linux/qualcommax/patches-6.18/0824-arm64-dts-qcom-ipq5018-flatten-usb-controller-node.patch new file mode 100644 index 00000000000..b18f5f9b40a --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0824-arm64-dts-qcom-ipq5018-flatten-usb-controller-node.patch @@ -0,0 +1,104 @@ +From 386835aa5d53ef83a968154b72dc89d38f4e74f1 Mon Sep 17 00:00:00 2001 +From: George Moussalem +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 +--- + 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 = , +- , +- ; +- 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 = , ++ , ++ , ++ ; ++ 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 = ; +- 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 { diff --git a/target/linux/qualcommax/patches-6.18/0825-dt-bindings-usb-qcom-snps-dwc3-add-clocks-for-usb3-on-qualcomm-ipq5018.patch b/target/linux/qualcommax/patches-6.18/0825-dt-bindings-usb-qcom-snps-dwc3-add-clocks-for-usb3-on-qualcomm-ipq5018.patch new file mode 100644 index 00000000000..ce734195548 --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0825-dt-bindings-usb-qcom-snps-dwc3-add-clocks-for-usb3-on-qualcomm-ipq5018.patch @@ -0,0 +1,54 @@ +From a1f783ff93ea161e679fb21045028f4163b7a0af Mon Sep 17 00:00:00 2001 +From: George Moussalem +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 +--- + .../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: diff --git a/target/linux/qualcommax/patches-6.18/0826-arm64-dts-qcom-ipq5018-add-clocks-required-for-usb3-support.patch b/target/linux/qualcommax/patches-6.18/0826-arm64-dts-qcom-ipq5018-add-clocks-required-for-usb3-support.patch new file mode 100644 index 00000000000..ede7f16aa03 --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0826-arm64-dts-qcom-ipq5018-add-clocks-required-for-usb3-support.patch @@ -0,0 +1,43 @@ +From 84b2a1e47780b0d9d76c31b52ce00da7386b60ee Mon Sep 17 00:00:00 2001 +From: George Moussalem +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 +--- + 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 = , + , diff --git a/target/linux/qualcommax/patches-6.18/0827-arm64-dts-qcom-ipq5018-add-super-speed-uniphy-to-usb-node.patch b/target/linux/qualcommax/patches-6.18/0827-arm64-dts-qcom-ipq5018-add-super-speed-uniphy-to-usb-node.patch new file mode 100644 index 00000000000..6f1490a5276 --- /dev/null +++ b/target/linux/qualcommax/patches-6.18/0827-arm64-dts-qcom-ipq5018-add-super-speed-uniphy-to-usb-node.patch @@ -0,0 +1,33 @@ +From 5705cbc5b65fbbc9726777dc877f6e748b1e7e20 Mon Sep 17 00:00:00 2001 +From: George Moussalem +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 +--- + 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; diff --git a/target/linux/qualcommax/patches-6.18/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch b/target/linux/qualcommax/patches-6.18/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch index a4432179777..470a02215e0 100644 --- a/target/linux/qualcommax/patches-6.18/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch +++ b/target/linux/qualcommax/patches-6.18/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch @@ -8,7 +8,7 @@ #include #include -@@ -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>,