mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-13 00:17:02 +04:00
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:
1 parent
6b98618527
commit
409bf967e4
11 files changed
+840
-3
No files matched your search
@@ -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
|
||||
|
||||
+55
@@ -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:
|
||||
+132
@@ -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 = <®ulator_fixed_5p0>;
|
||||
+ };
|
||||
+362
@@ -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");
|
||||
+52
@@ -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>,
|
||||
+104
@@ -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 {
|
||||
+54
@@ -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:
|
||||
+43
@@ -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>,
|
||||
+33
@@ -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;
|
||||
+3
-3
@@ -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>,
|
||||
|
||||
Reference in new issue
Block a user