summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2015-09-01 11:39:44 +0200
committerLuka Perkov <luka.perkov@sartura.hr>2015-10-21 02:25:01 +0200
commitcd48225b089427eb0aa7b8cf6909d5d5e2d311f1 (patch)
treeff035131f9fce0cefba5ecc94b4abadee99ad8d9 /drivers
parent9cffb2335c16ab51c3bef7735ff4e0ec4c8f6035 (diff)
downloadtalos-obmc-uboot-cd48225b089427eb0aa7b8cf6909d5d5e2d311f1.tar.gz
talos-obmc-uboot-cd48225b089427eb0aa7b8cf6909d5d5e2d311f1.zip
usb: ehci-marvell.c: Add DM support
This patch adds driver model (DM) support to the Marvell EHCI driver. This will be used by the MVEBU SoC's, currently Armada XP and 38x. Tested on Marvell Armada XP and 38x eval boards. Signed-off-by: Stefan Roese <sr@denx.de> Acked-by: Marek Vasut <marex@denx.de> Cc: Simon Glass <sjg@chromium.org> Cc: Luka Perkov <luka.perkov@sartura.hr>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/Kconfig7
-rw-r--r--drivers/usb/host/ehci-marvell.c86
2 files changed, 77 insertions, 16 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b30b43da3b..2a2bffe06f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -52,6 +52,13 @@ config USB_EHCI
if USB_EHCI_HCD
+config USB_EHCI_MARVELL
+ bool "Support for MVEBU (AXP / A38x) on-chip EHCI USB controller"
+ depends on ARCH_MVEBU
+ default y
+ ---help---
+ Enables support for the on-chip EHCI controller on MVEBU SoCs.
+
config USB_EHCI_MX6
bool "Support for i.MX6 on-chip EHCI USB controller"
depends on ARCH_MX6
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 50fa01c079..5b0f46aaef 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -12,6 +12,7 @@
#include "ehci.h"
#include <linux/mbus.h>
#include <asm/arch/cpu.h>
+#include <dm.h>
#if defined(CONFIG_KIRKWOOD)
#include <asm/arch/soc.h>
@@ -28,24 +29,19 @@ DECLARE_GLOBAL_DATA_PTR;
/*
* USB 2.0 Bridge Address Decoding registers setup
*/
-#ifdef CONFIG_ARMADA_XP
+#ifdef CONFIG_DM_USB
-/*
- * Armada XP and Armada 38x have different base addresses for
- * the USB 2.0 EHCI host controller. So we need to provide
- * a mechnism to support both here.
- */
-#define MVUSB0_BASE \
- (mvebu_soc_family() == MVEBU_SOC_A38X ? \
- MVEBU_USB20_BASE : MVEBU_AXP_USB_BASE)
-#define MVUSB_BASE(port) MVUSB0_BASE + ((port) << 12)
+struct ehci_mvebu_priv {
+ struct ehci_ctrl ehci;
+ fdt_addr_t hcd_base;
+};
/*
* Once all the older Marvell SoC's (Orion, Kirkwood) are converted
* to the common mvebu archticture including the mbus setup, this
* will be the only function needed to configure the access windows
*/
-static void usb_brg_adrdec_setup(int index)
+static void usb_brg_adrdec_setup(u32 base)
{
const struct mbus_dram_target_info *dram;
int i;
@@ -53,8 +49,8 @@ static void usb_brg_adrdec_setup(int index)
dram = mvebu_mbus_dram_info();
for (i = 0; i < 4; i++) {
- writel(0, MVUSB_BASE(index) + USB_WINDOW_CTRL(i));
- writel(0, MVUSB_BASE(index) + USB_WINDOW_BASE(i));
+ writel(0, base + USB_WINDOW_CTRL(i));
+ writel(0, base + USB_WINDOW_BASE(i));
}
for (i = 0; i < dram->num_cs; i++) {
@@ -63,12 +59,69 @@ static void usb_brg_adrdec_setup(int index)
/* 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,
- MVUSB_BASE(index) + USB_WINDOW_CTRL(i));
+ base + USB_WINDOW_CTRL(i));
/* Write base address to base register */
- writel(cs->base, MVUSB_BASE(index) + USB_WINDOW_BASE(i));
+ writel(cs->base, base + USB_WINDOW_BASE(i));
}
}
+
+static int ehci_mvebu_probe(struct udevice *dev)
+{
+ struct ehci_mvebu_priv *priv = dev_get_priv(dev);
+ struct ehci_hccr *hccr;
+ struct ehci_hcor *hcor;
+
+ /*
+ * Get the base address for EHCI controller from the device node
+ */
+ priv->hcd_base = dev_get_addr(dev);
+ if (priv->hcd_base == FDT_ADDR_T_NONE) {
+ debug("Can't get the EHCI register base address\n");
+ return -ENXIO;
+ }
+
+ usb_brg_adrdec_setup(priv->hcd_base);
+
+ hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100);
+ hcor = (struct ehci_hcor *)
+ ((u32)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ debug("ehci-marvell: init hccr %x and hcor %x hc_length %d\n",
+ (u32)hccr, (u32)hcor,
+ (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_mvebu_remove(struct udevice *dev)
+{
+ int ret;
+
+ ret = ehci_deregister(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct udevice_id ehci_usb_ids[] = {
+ { .compatible = "marvell,orion-ehci", },
+ { }
+};
+
+U_BOOT_DRIVER(ehci_mvebu) = {
+ .name = "ehci_mvebu",
+ .id = UCLASS_USB,
+ .of_match = ehci_usb_ids,
+ .probe = ehci_mvebu_probe,
+ .remove = ehci_mvebu_remove,
+ .ops = &ehci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct ehci_mvebu_priv),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
#else
#define MVUSB_BASE(port) MVUSB0_BASE
@@ -112,7 +165,6 @@ static void usb_brg_adrdec_setup(int index)
writel(base, MVUSB0_BASE + USB_WINDOW_BASE(i));
}
}
-#endif
/*
* Create the appropriate control structures to manage
@@ -142,3 +194,5 @@ int ehci_hcd_stop(int index)
{
return 0;
}
+
+#endif /* CONFIG_DM_USB */
OpenPOWER on IntegriCloud