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.ma...@sartura.hr> >> Cc: Luka Perkov <luka.per...@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 <s...@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.ma...@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.