From: Luca Lauro via B4 Relay <devnull+famlauro93l.gmail.com@kernel.org>
To: Sascha Hauer <s.hauer@pengutronix.de>,
"open list:BAREBOX" <barebox@lists.infradead.org>
Cc: Luca Lauro <famlauro93l@gmail.com>
Subject: [PATCH 16/19] usb: ehci: add Marvell EHCI host controller driver
Date: Thu, 23 Jul 2026 15:57:54 +0200 [thread overview]
Message-ID: <20260723-rn102-rn104-series-v1-16-7698d25df866@gmail.com> (raw)
In-Reply-To: <20260723-rn102-rn104-series-v1-0-7698d25df866@gmail.com>
From: Luca Lauro <famlauro93l@gmail.com>
---
drivers/usb/host/Kconfig | 7 ++
drivers/usb/host/Makefile | 13 +--
drivers/usb/host/ehci-marvell.c | 229 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 243 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 58f276cdb4..21bf876d69 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -22,6 +22,13 @@ config USB_EHCI_ZYNQ
help
Enable support for Zynq on-chip EHCI USB controller
+config USB_EHCI_MARVELL
+ bool "Marvell USB EHCI driver"
+ depends on ARCH_MVEBU
+ depends on USB_EHCI
+ help
+ Enable support for Marvell USB EHCI controller
+
config USB_OHCI
bool "OHCI driver"
depends on !MMU && HAS_DMA
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cbddfbe923..932581d691 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -1,8 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
-obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o
+obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
+obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o
obj-$(CONFIG_USB_EHCI_ATMEL) += ehci-atmel.o
-obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
-obj-$(CONFIG_USB_OHCI) += ohci-hcd.o
-obj-$(CONFIG_USB_OHCI_AT91) += ohci-at91.o
-obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
+obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
+obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o
+obj-$(CONFIG_USB_OHCI) += ohci-hcd.o
+obj-$(CONFIG_USB_OHCI_AT91) += ohci-at91.o
+obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
new file mode 100644
index 0000000000..8accfd697d
--- /dev/null
+++ b/drivers/usb/host/ehci-marvell.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Marvell Orion / Kirkwood / Armada EHCI host for barebox
+ *
+ * Porting basato su ehci-marvell.c di U-Boot moderno,
+ * adattato al modello ehci_register() di barebox.
+ */
+/*#define DEBUG*/
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <linux/usb/usb.h>
+#include <linux/usb/ehci.h>
+#include <linux/mbus.h>
+
+#include "ehci.h"
+
+#define USB_WINDOW_CTRL(i) (0x320 + ((i) << 4))
+#define USB_WINDOW_BASE(i) (0x324 + ((i) << 4))
+#define USB_TARGET_DRAM 0x0
+
+#define USB2_SBUSCFG_OFF 0x90
+
+#define USB_SBUSCFG_BAWR_OFF 0x6
+#define USB_SBUSCFG_BARD_OFF 0x3
+#define USB_SBUSCFG_AHBBRST_OFF 0x0
+
+#define USB_SBUSCFG_BAWR_ALIGN_64B 0x4
+#define USB_SBUSCFG_BARD_ALIGN_64B 0x4
+#define USB_SBUSCFG_AHBBRST_INCR16 0x7
+
+/* AC5 special window mapping (copiato da U-Boot) */
+#define USB_TO_DRAM_TARGET_ID 0x2
+#define USB_TO_DRAM_ATTR_ID 0x0
+#define USB_DRAM_BASE 0x00000000
+#define USB_DRAM_SIZE 0xfff /* non oltrepassare lo spazio sorgente */
+
+/*
+ * Stato privato per questa istanza EHCI Marvell.
+ * Non serve conoscere struct ehci_host: basta il puntatore.
+ */
+struct marvell_ehci {
+ struct ehci_host *ehci;
+ void __iomem *base;
+ struct device *dev;
+ u32 dram_bus_base;
+};
+
+static void marvell_ehci_sbuscfg_fixup(void __iomem *base)
+{
+ /*
+ * SBUSCFG: Control for the AMBA system bus interface:
+ * BAWR = BARD = 4 : Align rd/wr bursts packets larger than 64 bytes
+ * AHBBRST = 7 : Align AHB burst for packets larger than 64 bytes
+ */
+ writel((USB_SBUSCFG_BAWR_ALIGN_64B << USB_SBUSCFG_BAWR_OFF) |
+ (USB_SBUSCFG_BARD_ALIGN_64B << USB_SBUSCFG_BARD_OFF) |
+ (USB_SBUSCFG_AHBBRST_INCR16 << USB_SBUSCFG_AHBBRST_OFF),
+ base + USB2_SBUSCFG_OFF);
+}
+
+/*
+ * Programma le decoding windows USB -> DRAM usando le info MBUS.
+ * Per AC5 replica lo speciale mapping 0x0..USB_DRAM_SIZE.
+ */
+static void marvell_usb_brg_adrdec_setup(struct marvell_ehci *priv)
+{
+ const struct mbus_dram_target_info *dram;
+ void __iomem *base = priv->base;
+ int i;
+
+ dev_info(priv->dev, "USB adrdec setup: ENTER\n");
+
+ dram = mvebu_mbus_dram_info();
+ if (!dram) {
+ dev_err(priv->dev, "no MBUS DRAM info\n");
+ return;
+ }
+
+ for (i = 0; i < 4; i++) {
+ writel(0, base + USB_WINDOW_CTRL(i));
+ writel(0, base + USB_WINDOW_BASE(i));
+ }
+
+ if (priv->dev->of_node &&
+ of_device_is_compatible(priv->dev->of_node, "marvell,ac5-ehci")) {
+ /* mappa DRAM vista da USB a 0x0 (come in U-Boot) */
+ writel((USB_DRAM_SIZE << 16) |
+ (USB_TO_DRAM_ATTR_ID << 8) |
+ (USB_TO_DRAM_TARGET_ID << 4) | 1,
+ base + USB_WINDOW_CTRL(0));
+ writel(USB_DRAM_BASE, base + USB_WINDOW_BASE(0));
+
+ dev_dbg(priv->dev,
+ "AC5 decoding windows: ctrl=0x%08x base=0x%08x\n",
+ readl(base + USB_WINDOW_CTRL(0)),
+ readl(base + USB_WINDOW_BASE(0)));
+ } else {
+ /* caso generico mvebu: una window per ciascun CS DRAM */
+
+ for (i = 0; i < dram->num_cs; i++) {
+ const struct mbus_dram_window *cs = dram->cs + i;
+
+ /* Write size, attributes and target id to control register */
+ writel(((cs->size - 1) & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ base + USB_WINDOW_CTRL(i));
+
+ /* Write base address to base register */
+ writel(cs->base, base + USB_WINDOW_BASE(i));
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ u32 ctrl = readl(base + USB_WINDOW_CTRL(i));
+ u32 winb = readl(base + USB_WINDOW_BASE(i));
+ dev_info(priv->dev, "WIN%d: CTRL=0x%08x BASE=0x%08x\n", i, ctrl, winb);
+ }
+}
+
+/*
+ * Hook di init chiamato da ehci-hcd.c prima di avviare l'host.
+ * Qui facciamo solo la parte “bridge address decoding”.
+ */
+static int marvell_ehci_init(void *drvdata)
+{
+ struct marvell_ehci *priv = drvdata;
+
+ marvell_usb_brg_adrdec_setup(priv);
+
+ writel((USB_SBUSCFG_BAWR_ALIGN_64B << USB_SBUSCFG_BAWR_OFF) |
+ (USB_SBUSCFG_BARD_ALIGN_64B << USB_SBUSCFG_BARD_OFF) |
+ (USB_SBUSCFG_AHBBRST_INCR16 << USB_SBUSCFG_AHBBRST_OFF),
+ priv->base + 0x100 + 0x90);
+ mdelay(50);
+
+ /*
+ * La programmazione di SBUSCFG (BAWR/BARD/AHBBRST) in U-Boot
+ * serve solo per SoC senza hlock (Armada3700, ecc.).
+ * Per ora la lasciamo fuori: se in futuro servirà, possiamo
+ * aggiungere un post_init o un hook dedicato nel core EHCI.
+ */
+
+ dev_dbg(priv->dev, "marvell_ehci_init done\n");
+
+ return 0;
+}
+
+static int marvell_ehci_probe(struct device *dev)
+{
+ struct marvell_ehci *priv;
+ struct resource *iores;
+ struct ehci_data data;
+ void __iomem *base;
+ struct ehci_host *ehci;
+
+ priv = xzalloc(sizeof(*priv));
+ priv->dev = dev;
+ dev->priv = priv;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ base = IOMEM(iores->start);
+ priv->base = base;
+
+ memset(&data, 0, sizeof(data));
+
+ /*
+ * Sui controller Marvell il blocco EHCI inizia a offset 0x100
+ * rispetto alla base USB.
+ */
+ data.hccr = base + 0x100;
+
+ u32 capbase = readl(data.hccr); /* HC_CAPBASE */
+ u8 caplength = capbase & 0xff; /* CAPLENGTH */
+
+ data.hcor = (void __iomem *)((u8 *)data.hccr + caplength);
+
+ dev_info(dev, "EHCI probe: base=%p hccr=%p hcor=%p\n",
+ base, data.hccr, data.hcor);
+
+ dev_info(dev, "EHCI CAPBASE=0x%08x CAPLENGTH=0x%02x\n",
+ capbase, caplength);
+
+ data.init = marvell_ehci_init;
+ data.drvdata = priv;
+
+ if (of_device_is_compatible(dev->of_node, "marvell,armada-3700-ehci"))
+ marvell_ehci_sbuscfg_fixup(base);
+
+ dev_dbg(dev, "marvell_ehci_probe: done\n");
+
+ ehci = ehci_register(dev, &data);
+ if (IS_ERR(ehci))
+ return PTR_ERR(ehci);
+
+ priv->ehci = ehci;
+
+ return 0;
+}
+
+static void marvell_ehci_remove(struct device *dev)
+{
+ struct marvell_ehci *priv = dev->priv;
+
+ if (priv && priv->ehci)
+ ehci_unregister(priv->ehci);
+}
+
+static const struct of_device_id marvell_ehci_dt_ids[] = {
+ { .compatible = "marvell,orion-ehci" },
+ { .compatible = "marvell,armada-3700-ehci" },
+ { .compatible = "marvell,ac5-ehci" },
+ { /* sentinel */ }
+};
+
+static struct driver marvell_ehci_driver = {
+ .name = "marvell-ehci",
+ .probe = marvell_ehci_probe,
+ .remove = marvell_ehci_remove,
+ .of_compatible = DRV_OF_COMPAT(marvell_ehci_dt_ids),
+};
+device_platform_driver(marvell_ehci_driver);
--
2.47.3
next prev parent reply other threads:[~2026-07-23 14:02 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 13:57 [PATCH 00/19] ARM: mvebu: add Netgear RN102/RN104 support and related drivers Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 01/19] ARM: mvebu: add board support for Netgear RN102 Luca Lauro via B4 Relay
2026-07-27 13:27 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 02/19] ARM: mvebu: add lowlevel " Luca Lauro via B4 Relay
2026-07-27 13:30 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 03/19] ARM: dts: add barebox device tree " Luca Lauro via B4 Relay
2026-07-27 13:32 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 04/19] ARM: dts: update RN102 Linux DTS Luca Lauro via B4 Relay
2026-07-27 13:40 ` Sascha Hauer
2026-07-27 13:41 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 05/19] ARM: mvebu: add Kconfig entry for Netgear RN102 Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 06/19] ARM: mvebu: add RN102 image support Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 07/19] ARM: mvebu: enable RN102 in mvebu_defconfig Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 08/19] ARM: mvebu: rn104: placeholder bay management Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 09/19] ARM: mvebu: add lowlevel support for Netgear RN104 Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 10/19] ARM: dts: update RN104 Linux DTS Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 11/19] ARM: mvebu: adapt RN104 image support Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 12/19] ARM: mvebu: rename PUTC_LL to MVEBU_PUTC_LL Luca Lauro via B4 Relay
2026-07-27 13:46 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 13/19] drivers: fan: add fan framework and API Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 14/19] commands: add fan control command Luca Lauro via B4 Relay
2026-07-23 13:57 ` [PATCH 15/19] commands: integrate fan command into Kconfig and Makefile Luca Lauro via B4 Relay
2026-07-23 13:57 ` Luca Lauro via B4 Relay [this message]
2026-07-27 14:09 ` [PATCH 16/19] usb: ehci: add Marvell EHCI host controller driver Sascha Hauer
2026-07-23 13:57 ` [PATCH 17/19] usb: ehci: minor fixes for Marvell compatibility Luca Lauro via B4 Relay
2026-07-27 14:12 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 18/19] ata: ahci: fixes and updates for Marvell SATA controller Luca Lauro via B4 Relay
2026-07-27 14:15 ` Sascha Hauer
2026-07-23 13:57 ` [PATCH 19/19] drivers: integrate USB/AHCI changes Luca Lauro via B4 Relay
2026-07-27 14:16 ` Sascha Hauer
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=20260723-rn102-rn104-series-v1-16-7698d25df866@gmail.com \
--to=devnull+famlauro93l.gmail.com@kernel.org \
--cc=barebox@lists.infradead.org \
--cc=famlauro93l@gmail.com \
--cc=s.hauer@pengutronix.de \
/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