
On Thu, Sep 10, 2020 at 3:37 PM Marek Vasut marex@denx.de wrote:
On 9/10/20 3:30 PM, Tom Rini wrote:
On Tue, Sep 01, 2020 at 07:23:01PM +0200, Robert Marko wrote:
Add driver for Qualcomm DWC3 based dual role xHCI USB controller. Currently tested on IPQ40xx, but should support other Qualcomm SoC families as well.
Only host mode is supported.
Signed-off-by: Robert Marko robert.marko@sartura.hr Cc: Luka Perkov luka.perkov@sartura.hr
MAINTAINERS | 2 + .../usb/qcom-dwc3-ipq.txt | 34 +++++ drivers/usb/host/Kconfig | 6 + drivers/usb/host/Makefile | 1 + drivers/usb/host/xhci-ipq.c | 117 ++++++++++++++++++ 5 files changed, 160 insertions(+) create mode 100644 doc/device-tree-bindings/usb/qcom-dwc3-ipq.txt create mode 100644 drivers/usb/host/xhci-ipq.c
diff --git a/MAINTAINERS b/MAINTAINERS index d8d2c6278b..99828f656a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -241,6 +241,8 @@ F: include/dt-bindings/clock/qcom,ipq4019-gcc.h F: include/dt-bindings/reset/qcom,ipq4019-reset.h F: drivers/reset/reset-ipq4019.c F: drivers/phy/phy-qcom-ipq4019-usb.c +F: doc/device-tree-bindings/usb/qcom-dwc3-ipq.txt +F: drivers/usb/host/xhci-ipq.c
ARM MARVELL KIRKWOOD ARMADA-XP ARMADA-38X ARMADA-37XX ARMADA-7K/8K M: Stefan Roese sr@denx.de diff --git a/doc/device-tree-bindings/usb/qcom-dwc3-ipq.txt b/doc/device-tree-bindings/usb/qcom-dwc3-ipq.txt new file mode 100644 index 0000000000..a910a06fa2 --- /dev/null +++ b/doc/device-tree-bindings/usb/qcom-dwc3-ipq.txt @@ -0,0 +1,34 @@ +Qualcomm SuperSpeed DWC3 USB SoC controller
+This controller is integrated in IPQ40xx SoC-s. +It is a dual role USB3.0/USB2.0 controller.
+Required properties :
- compatible: must be "qcom,dwc3-ipq"
- reg: should contain address and length of the standard XHCI
- register set for the device.
- #address-cells: must be 1
- #size-cells: must be 1
- phys: list of PHY specifiers
- phy-names: shall be "usb2-phy" and "usb3-phy"(In case of USB3.0 only)
+Example:
- usb3: xhci@8a00000 {
compatible = "qcom,dwc3-ipq";
reg = <0x8a00000 0xcd00>;
#address-cells = <1>;
#size-cells = <1>;
phys = <&usb3_hs_phy>, <&usb3_ss_phy>;
phy-names = "usb2-phy", "usb3-phy";
status = "disabled";
- };
- usb2: xhci@6000000 {
compatible = "qcom,dwc3-ipq";
reg = <0x6000000 0xcd00>;
#address-cells = <1>;
#size-cells = <1>;
phys = <&usb2_hs_phy>;
phy-names = "usb2-phy";
status = "disabled";
- };
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1c374a7bd8..7e0b1ab4ce 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -93,6 +93,12 @@ config USB_XHCI_BRCM USB controller based on the Broadcom USB3 IP Core. Supports USB2/3 functionality.
+config USB_XHCI_IPQ
- bool "Support for Qualcomm IPQ on-chip DWC3 xHCI USB controller"
- depends on DM_USB && PHY && USB_XHCI_DWC3 && ARCH_IPQ40XX
- help
Enables support for the on-chip xHCI DWC3 controller on Qualcomm IPQ SoCs.
endif # USB_XHCI_HCD
config USB_EHCI_HCD diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 29d4f87e38..0fa9c8f32a 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o obj-$(CONFIG_USB_XHCI_RCAR) += xhci-rcar.o +obj-$(CONFIG_USB_XHCI_IPQ) += xhci-ipq.o obj-$(CONFIG_USB_XHCI_STI) += dwc3-sti-glue.o
# designware diff --git a/drivers/usb/host/xhci-ipq.c b/drivers/usb/host/xhci-ipq.c new file mode 100644 index 0000000000..840f074819 --- /dev/null +++ b/drivers/usb/host/xhci-ipq.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2020 Sartura Ltd.
- Qualcomm DWC3 controller driver
- Author: Robert Marko robert.marko@sartura.hr
- */
+#include <common.h> +#include <dm.h> +#include <generic-phy.h> +#include <linux/compat.h> +#include <linux/errno.h> +#include <linux/usb/dwc3.h> +#include <usb.h> +#include <usb/xhci.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct ipq_xhci_priv {
- phys_addr_t hcd_base;
- struct xhci_ctrl ctrl;
- struct xhci_hccr *hcd;
- struct dwc3 *dwc3_reg;
- struct phy_bulk phys;
+};
+static int ipq_xhci_core_init(struct ipq_xhci_priv *ipq) +{
- int ret;
- ret = dwc3_core_init(ipq->dwc3_reg);
- if (ret) {
return ret;
- }
- /* We are hard-coding DWC3 core to Host Mode */
- dwc3_set_mode(ipq->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
- return ret;
+}
+static int ipq_xhci_core_exit(struct udevice *dev) +{
- struct ipq_xhci_priv *priv = dev_get_priv(dev);
- int ret;
- ret = generic_phy_power_off_bulk(&priv->phys);
- ret |= generic_phy_exit_bulk(&priv->phys);
- return ret;
+}
+static int ipq_xhci_usb_remove(struct udevice *dev) +{
- int ret;
- ret = xhci_deregister(dev);
- if (ret != 0) {
dev_err(dev, "XHCI deregistration failed\n");
return ret;
- }
- ipq_xhci_core_exit(dev);
- return ret;
+}
+static int ipq_xhci_usb_probe(struct udevice *dev) +{
- struct ipq_xhci_priv *priv = dev_get_priv(dev);
- struct xhci_hcor *hcor;
- int ret;
- priv->hcd_base = dev_read_addr(dev);
- if (priv->hcd_base == FDT_ADDR_T_NONE)
return -EINVAL;
- ret = generic_phy_get_bulk(dev, &priv->phys);
- if (ret)
return ret;
- priv->hcd = (struct xhci_hccr *)priv->hcd_base;
- priv->dwc3_reg = (struct dwc3 *)((char *)(priv->hcd) + DWC3_REG_OFFSET);
- hcor = (struct xhci_hcor *)((uint32_t)priv->hcd +
HC_LENGTH(xhci_readl(&priv->hcd->cr_capbase)));
- ret = generic_phy_power_on_bulk(&priv->phys);
- if (ret)
generic_phy_exit_bulk(&priv->phys);
- ret = ipq_xhci_core_init(priv);
- if (ret) {
dev_err(dev, "Error initializing the XHCI controller\n");
return ret;
- }
- return xhci_register(dev, priv->hcd, hcor);
+}
+static const struct udevice_id ipq_xhci_match_ids[] = {
- { .compatible = "qcom,dwc3-ipq" },
- {}
+};
+U_BOOT_DRIVER(usb_xhci) = {
- .name = "ipq_hci",
- .id = UCLASS_USB,
- .of_match = ipq_xhci_match_ids,
- .probe = ipq_xhci_usb_probe,
- .remove = ipq_xhci_usb_remove,
- .ops = &xhci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct ipq_xhci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
Adding USB maintainer.
And adding Bin, since it's XHCI.
No need to bother reviewing this, I dropped it in the next patch series that will be sent in a couple of minutes Regards Robert