public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
From: Puma Hsu <pumahsu@google.com>
To: mathias.nyman@intel.com, gregkh@linuxfoundation.org,
	 Thinh.Nguyen@synopsys.com
Cc: badhri@google.com, royluo@google.com, howardyen@google.com,
	 albertccwang@google.com, raychi@google.com,
	linux-kernel@vger.kernel.org,  linux-usb@vger.kernel.org,
	Puma Hsu <pumahsu@google.com>
Subject: [PATCH 2/3] usb: xhci: Add support for Google XHCI controller
Date: Mon, 19 Feb 2024 14:10:07 +0800	[thread overview]
Message-ID: <20240219061008.1761102-3-pumahsu@google.com> (raw)
In-Reply-To: <20240219061008.1761102-1-pumahsu@google.com>

In our SoC platform, we support allocating dedicated memory spaces
other than system memory for XHCI, which also requires IOMMU mapping.
The rest of driver probing and executing will use the generic
xhci-plat driver.

We support USB dual roles and switch roles by generic dwc3 driver,
the dwc3 driver always probes xhci-plat driver now, so we introduce
a device tree property to probe a XHCI glue driver.

Sample:
  xhci_dma: xhci_dma@99C0000 {
    compatible = "shared-dma-pool";
    reg = <0x00000000 0x99C0000 0x00000000 0x40000>;
    no-map;
  };

  dwc3: dwc3@c400000 {
    compatible = "snps,dwc3";
    reg = <0 0x0c400000  0 0x10000>;
    xhci-glue = "xhci-hcd-goog";
    memory-region = <&xhci_dma>;
    iommus = <&cpuacc_mmu 0x8100>;
  };

Signed-off-by: Puma Hsu <pumahsu@google.com>
---
 drivers/usb/dwc3/host.c      |   8 +-
 drivers/usb/host/Kconfig     |   6 ++
 drivers/usb/host/Makefile    |   1 +
 drivers/usb/host/xhci-goog.c | 154 +++++++++++++++++++++++++++++++++++
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/host/xhci-goog.c

diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index ae189b7a4f8b..45114c0fc38d 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -109,6 +109,7 @@ int dwc3_host_init(struct dwc3 *dwc)
 	struct platform_device	*xhci;
 	int			ret, irq;
 	int			prop_idx = 0;
+	const char		*xhci_glue;
 
 	/*
 	 * Some platforms need to power off all Root hub ports immediately after DWC3 set to host
@@ -121,7 +122,12 @@ int dwc3_host_init(struct dwc3 *dwc)
 	if (irq < 0)
 		return irq;
 
-	xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
+	device_property_read_string(dwc->dev, "xhci-glue", &xhci_glue);
+	if (xhci_glue)
+		xhci = platform_device_alloc(xhci_glue, PLATFORM_DEVID_AUTO);
+	else
+		xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
+
 	if (!xhci) {
 		dev_err(dwc->dev, "couldn't allocate xHCI device\n");
 		return -ENOMEM;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 4448d0ab06f0..1c1613c548d9 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -61,6 +61,12 @@ config USB_XHCI_PLATFORM
 
 	  If unsure, say N.
 
+config USB_XHCI_GOOG
+	tristate "xHCI support for Google Tensor SoCs"
+	help
+	  Say 'Y' to enable the support for the xHCI host controller
+	  found in Google Tensor SoCs.
+	  If unsure, say N.
+
 config USB_XHCI_HISTB
 	tristate "xHCI support for HiSilicon STB SoCs"
 	depends on USB_XHCI_PLATFORM && (ARCH_HISI || COMPILE_TEST)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index be4e5245c52f..76f315a1aa76 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -85,3 +85,4 @@ obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
 obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o
 obj-$(CONFIG_USB_XEN_HCD)	+= xen-hcd.o
+obj-$(CONFIG_USB_XHCI_GOOG)	+= xhci-goog.o
diff --git a/drivers/usb/host/xhci-goog.c b/drivers/usb/host/xhci-goog.c
new file mode 100644
index 000000000000..db027a5866db
--- /dev/null
+++ b/drivers/usb/host/xhci-goog.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * xhci-goog.c - xHCI host controller driver platform Bus Glue.
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/iommu.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/of.h>
+
+#include "xhci.h"
+#include "xhci-plat.h"
+
+
+static int xhci_goog_probe(struct platform_device *pdev)
+{
+	const struct xhci_plat_priv *priv_match;
+	struct device *sysdev;
+	int ret;
+	struct device_node	*np;
+	struct iommu_domain	*domain;
+	struct reserved_mem	*rmem;
+	unsigned long           iova;
+	phys_addr_t             paddr;
+
+	for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) {
+		if (is_of_node(sysdev->fwnode))
+			break;
+	}
+
+	np = of_parse_phandle(sysdev->of_node, "memory-region", 0);
+	if (np) {
+		ret = of_reserved_mem_device_init(sysdev);
+		if (ret) {
+			dev_err(sysdev, "Could not get reserved memory\n");
+			return ret;
+		}
+
+		domain = iommu_get_domain_for_dev(sysdev);
+		if (domain) {
+			rmem = of_reserved_mem_lookup(np);
+			if (!rmem) {
+				dev_err(sysdev, "reserved memory lookup failed\n");
+				ret = -ENOMEM;
+				goto release_reserved_mem;
+			}
+
+			/* We do a direct mapping */
+			paddr = rmem->base;
+			iova = paddr;
+
+			dev_dbg(sysdev, "map: iova: 0x%lx, pa: %pa, size: 0x%llx\n", iova, &paddr,
+				rmem->size);
+
+			ret = iommu_map(domain, iova, paddr, rmem->size,
+					IOMMU_READ | IOMMU_WRITE, GFP_KERNEL);
+			if (ret < 0) {
+				dev_err(sysdev, "iommu map error: %d\n", ret);
+				goto release_reserved_mem;
+			}
+		}
+	}
+
+	if (WARN_ON(!sysdev->dma_mask)) {
+		/* Platform did not initialize dma_mask */
+		ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
+		if (ret)
+			goto unmap_iommu;
+	}
+
+	if (pdev->dev.of_node)
+		priv_match = of_device_get_match_data(&pdev->dev);
+	else
+		priv_match = dev_get_platdata(&pdev->dev);
+
+	ret = xhci_plat_probe(pdev, sysdev, priv_match);
+	if (ret) {
+		dev_err(&pdev->dev, "xhci plat probe failed: %d\n", ret);
+		goto unmap_iommu;
+	}
+
+	return 0;
+
+unmap_iommu:
+	iommu_unmap(domain, rmem->base, rmem->size);
+
+release_reserved_mem:
+	of_reserved_mem_device_release(sysdev);
+
+	return ret;
+}
+
+static int xhci_goog_remove(struct platform_device *dev)
+{
+	struct usb_hcd	*hcd = platform_get_drvdata(dev);
+	struct device *sysdev = hcd->self.sysdev;
+	struct iommu_domain *domain;
+	struct device_node *np;
+	struct reserved_mem *rmem;
+
+	xhci_plat_remove(dev);
+
+	domain = iommu_get_domain_for_dev(sysdev);
+	if (domain) {
+		np = of_parse_phandle(sysdev->of_node, "memory-region", 0);
+		rmem = of_reserved_mem_lookup(np);
+		if (rmem)
+			iommu_unmap(domain, rmem->base, rmem->size);
+	}
+
+	of_reserved_mem_device_release(sysdev);
+
+	return 0;
+}
+
+static void xhci_goog_shutdown(struct platform_device *dev)
+{
+	usb_hcd_platform_shutdown(dev);
+}
+
+static struct platform_driver usb_goog_xhci_driver = {
+	.probe	= xhci_goog_probe,
+	.remove	= xhci_goog_remove,
+	.shutdown = xhci_goog_shutdown,
+	.driver	= {
+		.name = "xhci-hcd-goog",
+		.pm = &xhci_plat_pm_ops,
+	},
+};
+MODULE_ALIAS("platform:xhci-hcd-goog");
+
+static int __init xhci_goog_init(void)
+{
+	return platform_driver_register(&usb_goog_xhci_driver);
+}
+module_init(xhci_goog_init);
+
+static void __exit xhci_goog_exit(void)
+{
+	platform_driver_unregister(&usb_goog_xhci_driver);
+}
+module_exit(xhci_goog_exit);
+
+MODULE_DESCRIPTION("Google xHCI Platform Host Controller Driver");
+MODULE_LICENSE("GPL");
-- 
2.44.0.rc0.258.g7320e95886-goog


  parent reply	other threads:[~2024-02-19  6:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-19  6:10 [PATCH 0/3] usb: xhci: Add support for Google XHCI controller Puma Hsu
2024-02-19  6:10 ` [PATCH 1/3] dt-bindings: usb: Add xhci glue driver support Puma Hsu
2024-02-19 12:18   ` Krzysztof Kozlowski
2024-02-19  6:10 ` Puma Hsu [this message]
2024-02-19  6:30   ` [PATCH 2/3] usb: xhci: Add support for Google XHCI controller Greg KH
2024-02-21  9:22     ` Puma Hsu
2024-02-19 12:21   ` Krzysztof Kozlowski
2024-02-21  9:31     ` Puma Hsu
2024-02-21  9:52       ` Krzysztof Kozlowski
2024-02-22  9:45         ` Puma Hsu
2024-02-19  6:10 ` [PATCH 3/3] MAINTAINERS: Add maintainer for Google USB XHCI driver Puma Hsu
2024-02-19  6:31   ` Greg KH
2024-02-19  8:35     ` Puma Hsu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240219061008.1761102-3-pumahsu@google.com \
    --to=pumahsu@google.com \
    --cc=Thinh.Nguyen@synopsys.com \
    --cc=albertccwang@google.com \
    --cc=badhri@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=howardyen@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=raychi@google.com \
    --cc=royluo@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox