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>
This commit is contained in:
Stefan Roese 2015-09-01 11:39:44 +02:00 committed by Luka Perkov
parent 9cffb2335c
commit cd48225b08
2 changed files with 77 additions and 16 deletions

View File

@ -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

View File

@ -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 */