[PATCH v2 8/9] usb: xhci: Add Qualcomm DWC3 xHCI driver

Marek Vasut marex at denx.de
Thu Sep 10 15:37:54 CEST 2020


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 at sartura.hr>
>> Cc: Luka Perkov <luka.perkov at 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 at 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 at 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 at 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 at 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.


More information about the U-Boot mailing list