diff mbox series

[v2,16/28] drivers: usb: Add generic XHCI

Message ID 20240906072231.2531491-17-patrick.rudolph@9elements.com
State Changes Requested
Delegated to: Tom Rini
Headers show
Series Implement ACPI on aarch64 | expand

Commit Message

Patrick Rudolph Sept. 6, 2024, 7:22 a.m. UTC
Add support for the generic XHCI driver that contains no SoC
specific code. It can be used on platforms that simply work out
of the box, like on emulated platforms.

TEST: Booted on QEMU sbsa machine using the generic xhci driver.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Cc: Tom Rini <trini@konsulko.com>
---
 drivers/usb/host/Kconfig        |  8 +++
 drivers/usb/host/Makefile       |  1 +
 drivers/usb/host/xhci-generic.c | 88 +++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 drivers/usb/host/xhci-generic.c

Comments

Tom Rini Sept. 6, 2024, 4:13 p.m. UTC | #1
On Fri, Sep 06, 2024 at 09:22:18AM +0200, Patrick Rudolph wrote:

> Add support for the generic XHCI driver that contains no SoC
> specific code. It can be used on platforms that simply work out
> of the box, like on emulated platforms.
> 
> TEST: Booted on QEMU sbsa machine using the generic xhci driver.
> 
> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
> Cc: Tom Rini <trini@konsulko.com>

Adding Marek..

> ---
>  drivers/usb/host/Kconfig        |  8 +++
>  drivers/usb/host/Makefile       |  1 +
>  drivers/usb/host/xhci-generic.c | 88 +++++++++++++++++++++++++++++++++
>  3 files changed, 97 insertions(+)
>  create mode 100644 drivers/usb/host/xhci-generic.c
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 6e10b629a3..bb5893d56d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -68,6 +68,14 @@ config USB_XHCI_MVEBU
>  	  SoCs, which includes Armada8K, Armada3700 and other Armada
>  	  family SoCs.
>  
> +config USB_XHCI_GENERIC
> +	bool "Generic SoC USB 3.0 support"
> +	depends on OF_CONTROL
> +	default n
> +	help
> +	  Choose this option to add support for USB 3.0 driver for SoCs
> +	  that do not need platform specific code, like on emulated targets.
> +
>  config USB_XHCI_OCTEON
>  	bool "Support for Marvell Octeon family on-chip xHCI USB controller"
>  	depends on ARCH_OCTEON
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 8dad36f936..9e880195ec 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
>  obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
>  obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
>  obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o
> +obj-$(CONFIG_USB_XHCI_GENERIC) += xhci-generic.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
> diff --git a/drivers/usb/host/xhci-generic.c b/drivers/usb/host/xhci-generic.c
> new file mode 100644
> index 0000000000..8c0341d0c4
> --- /dev/null
> +++ b/drivers/usb/host/xhci-generic.c
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2024 9elements GmbH
> + *
> + * GENERIC USB HOST xHCI Controller
> + */
> +
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <fdtdec.h>
> +#include <log.h>
> +#include <usb.h>
> +
> +#include <usb/xhci.h>
> +
> +struct generic_xhci_plat {
> +	fdt_addr_t hcd_base;
> +};
> +
> +/**
> + * Contains pointers to register base addresses
> + * for the usb controller.
> + */
> +struct generic_xhci {
> +	struct xhci_ctrl ctrl;	/* Needs to come first in this struct! */
> +	struct usb_plat usb_plat;
> +	struct xhci_hccr *hcd;
> +};
> +
> +/*
> + * Dummy implementation that can be overwritten by a board
> + * specific function
> + */
> +__weak int board_xhci_enable(fdt_addr_t base)
> +{
> +	return 0;
> +}
> +
> +static int xhci_usb_probe(struct udevice *dev)
> +{
> +	struct generic_xhci_plat *plat = dev_get_plat(dev);
> +	struct generic_xhci *ctx = dev_get_priv(dev);
> +	struct xhci_hcor *hcor;
> +	int len;
> +
> +	ctx->hcd = (struct xhci_hccr *)phys_to_virt(plat->hcd_base);
> +	len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase));
> +	hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len);
> +
> +	/* Enable USB xHCI in board specific code */
> +	board_xhci_enable(devfdt_get_addr_index(dev, 1));
> +
> +	return xhci_register(dev, ctx->hcd, hcor);
> +}
> +
> +static int xhci_usb_of_to_plat(struct udevice *dev)
> +{
> +	struct generic_xhci_plat *plat = dev_get_plat(dev);
> +
> +	/*
> +	 * Get the base address for XHCI controller from the device node
> +	 */
> +	plat->hcd_base = dev_read_addr(dev);
> +	if (plat->hcd_base == FDT_ADDR_T_NONE) {
> +		debug("Can't get the XHCI register base address\n");
> +		return -ENXIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id xhci_usb_ids[] = {
> +	{ .compatible = "generic-xhci" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(usb_xhci) = {
> +	.name	= "xhci_generic",
> +	.id	= UCLASS_USB,
> +	.of_match = xhci_usb_ids,
> +	.of_to_plat = xhci_usb_of_to_plat,
> +	.probe = xhci_usb_probe,
> +	.remove = xhci_deregister,
> +	.ops	= &xhci_usb_ops,
> +	.plat_auto	= sizeof(struct generic_xhci_plat),
> +	.priv_auto	= sizeof(struct generic_xhci),
> +	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
> +};
> -- 
> 2.45.2
>
Marek Vasut Sept. 9, 2024, 1:59 p.m. UTC | #2
On 9/6/24 6:13 PM, Tom Rini wrote:

>> +/*
>> + * Dummy implementation that can be overwritten by a board
>> + * specific function
>> + */
>> +__weak int board_xhci_enable(fdt_addr_t base)
>> +{
>> +	return 0;
>> +}

Are there any users of this ? If not , please do not add new 
board-specific functions. The HW should configure itself from DT.

Looks good otherwise, thanks .
diff mbox series

Patch

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6e10b629a3..bb5893d56d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -68,6 +68,14 @@  config USB_XHCI_MVEBU
 	  SoCs, which includes Armada8K, Armada3700 and other Armada
 	  family SoCs.
 
+config USB_XHCI_GENERIC
+	bool "Generic SoC USB 3.0 support"
+	depends on OF_CONTROL
+	default n
+	help
+	  Choose this option to add support for USB 3.0 driver for SoCs
+	  that do not need platform specific code, like on emulated targets.
+
 config USB_XHCI_OCTEON
 	bool "Support for Marvell Octeon family on-chip xHCI USB controller"
 	depends on ARCH_OCTEON
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 8dad36f936..9e880195ec 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@  obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
 obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
 obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o
+obj-$(CONFIG_USB_XHCI_GENERIC) += xhci-generic.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
diff --git a/drivers/usb/host/xhci-generic.c b/drivers/usb/host/xhci-generic.c
new file mode 100644
index 0000000000..8c0341d0c4
--- /dev/null
+++ b/drivers/usb/host/xhci-generic.c
@@ -0,0 +1,88 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 9elements GmbH
+ *
+ * GENERIC USB HOST xHCI Controller
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <usb.h>
+
+#include <usb/xhci.h>
+
+struct generic_xhci_plat {
+	fdt_addr_t hcd_base;
+};
+
+/**
+ * Contains pointers to register base addresses
+ * for the usb controller.
+ */
+struct generic_xhci {
+	struct xhci_ctrl ctrl;	/* Needs to come first in this struct! */
+	struct usb_plat usb_plat;
+	struct xhci_hccr *hcd;
+};
+
+/*
+ * Dummy implementation that can be overwritten by a board
+ * specific function
+ */
+__weak int board_xhci_enable(fdt_addr_t base)
+{
+	return 0;
+}
+
+static int xhci_usb_probe(struct udevice *dev)
+{
+	struct generic_xhci_plat *plat = dev_get_plat(dev);
+	struct generic_xhci *ctx = dev_get_priv(dev);
+	struct xhci_hcor *hcor;
+	int len;
+
+	ctx->hcd = (struct xhci_hccr *)phys_to_virt(plat->hcd_base);
+	len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase));
+	hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len);
+
+	/* Enable USB xHCI in board specific code */
+	board_xhci_enable(devfdt_get_addr_index(dev, 1));
+
+	return xhci_register(dev, ctx->hcd, hcor);
+}
+
+static int xhci_usb_of_to_plat(struct udevice *dev)
+{
+	struct generic_xhci_plat *plat = dev_get_plat(dev);
+
+	/*
+	 * Get the base address for XHCI controller from the device node
+	 */
+	plat->hcd_base = dev_read_addr(dev);
+	if (plat->hcd_base == FDT_ADDR_T_NONE) {
+		debug("Can't get the XHCI register base address\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id xhci_usb_ids[] = {
+	{ .compatible = "generic-xhci" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_xhci) = {
+	.name	= "xhci_generic",
+	.id	= UCLASS_USB,
+	.of_match = xhci_usb_ids,
+	.of_to_plat = xhci_usb_of_to_plat,
+	.probe = xhci_usb_probe,
+	.remove = xhci_deregister,
+	.ops	= &xhci_usb_ops,
+	.plat_auto	= sizeof(struct generic_xhci_plat),
+	.priv_auto	= sizeof(struct generic_xhci),
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};