Skip to content
Snippets Groups Projects
Commit c3980ad3 authored by Simon Glass's avatar Simon Glass
Browse files

dm: usb: tegra: Add driver model support to tegra EHCI


Update this driver with driver model support for USB.

Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
Reviewed-by: default avatarMarek Vasut <marex@denx.de>
parent ddb9a502
No related branches found
No related tags found
No related merge requests found
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
*/ */
#include <common.h> #include <common.h>
#include <dm.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm-generic/gpio.h> #include <asm-generic/gpio.h>
...@@ -20,6 +21,8 @@ ...@@ -20,6 +21,8 @@
#include "ehci.h" #include "ehci.h"
DECLARE_GLOBAL_DATA_PTR;
#define USB1_ADDR_MASK 0xFFFF0000 #define USB1_ADDR_MASK 0xFFFF0000
#define HOSTPC1_DEVLC 0x84 #define HOSTPC1_DEVLC 0x84
...@@ -32,9 +35,11 @@ ...@@ -32,9 +35,11 @@
#endif #endif
#endif #endif
#ifndef CONFIG_DM_USB
enum { enum {
USB_PORTS_MAX = 3, /* Maximum ports we allow */ USB_PORTS_MAX = 3, /* Maximum ports we allow */
}; };
#endif
/* Parameters we need for USB */ /* Parameters we need for USB */
enum { enum {
...@@ -71,12 +76,15 @@ enum usb_ctlr_type { ...@@ -71,12 +76,15 @@ enum usb_ctlr_type {
/* Information about a USB port */ /* Information about a USB port */
struct fdt_usb { struct fdt_usb {
struct ehci_ctrl ehci;
struct usb_ctlr *reg; /* address of registers in physical memory */ struct usb_ctlr *reg; /* address of registers in physical memory */
unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */ unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */
unsigned ulpi:1; /* 1 if port has external ULPI transceiver */ unsigned ulpi:1; /* 1 if port has external ULPI transceiver */
unsigned enabled:1; /* 1 to enable, 0 to disable */ unsigned enabled:1; /* 1 to enable, 0 to disable */
unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */ unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
#ifndef CONFIG_DM_USB
unsigned initialized:1; /* has this port already been initialized? */ unsigned initialized:1; /* has this port already been initialized? */
#endif
enum usb_ctlr_type type; enum usb_ctlr_type type;
enum usb_init_type init_type; enum usb_init_type init_type;
enum dr_mode dr_mode; /* dual role mode */ enum dr_mode dr_mode; /* dual role mode */
...@@ -85,8 +93,10 @@ struct fdt_usb { ...@@ -85,8 +93,10 @@ struct fdt_usb {
struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */ struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
}; };
#ifndef CONFIG_DM_USB
static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */ static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */
static unsigned port_count; /* Number of available ports */ static unsigned port_count; /* Number of available ports */
#endif
/* /*
* This table has USB timing parameters for each Oscillator frequency we * This table has USB timing parameters for each Oscillator frequency we
...@@ -163,6 +173,7 @@ static const u8 utmip_elastic_limit = 16; ...@@ -163,6 +173,7 @@ static const u8 utmip_elastic_limit = 16;
static const u8 utmip_hs_sync_start_delay = 9; static const u8 utmip_hs_sync_start_delay = 9;
struct fdt_usb_controller { struct fdt_usb_controller {
/* TODO(sjg@chromium.org): Remove when we only use driver model */
int compat; int compat;
/* flag to determine whether controller supports hostpc register */ /* flag to determine whether controller supports hostpc register */
u32 has_hostpc:1; u32 has_hostpc:1;
...@@ -785,6 +796,7 @@ static const struct ehci_ops tegra_ehci_ops = { ...@@ -785,6 +796,7 @@ static const struct ehci_ops tegra_ehci_ops = {
.powerup_fixup = tegra_ehci_powerup_fixup, .powerup_fixup = tegra_ehci_powerup_fixup,
}; };
#ifndef CONFIG_DM_USB
/* /*
* process_usb_nodes() - Process a list of USB nodes, adding them to our list * process_usb_nodes() - Process a list of USB nodes, adding them to our list
* of USB ports. * of USB ports.
...@@ -905,3 +917,74 @@ int ehci_hcd_stop(int index) ...@@ -905,3 +917,74 @@ int ehci_hcd_stop(int index)
return 0; return 0;
} }
#endif /* !CONFIG_DM_USB */
#ifdef CONFIG_DM_USB
static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
{
struct fdt_usb *priv = dev_get_priv(dev);
int ret;
ret = fdt_decode_usb(gd->fdt_blob, dev->of_offset, priv);
if (ret)
return ret;
priv->type = dev_get_driver_data(dev);
return 0;
}
static int ehci_usb_probe(struct udevice *dev)
{
struct usb_platdata *plat = dev_get_platdata(dev);
struct fdt_usb *priv = dev_get_priv(dev);
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
static bool clk_done;
int ret;
ret = usb_common_init(priv, plat->init_type);
if (ret)
return ret;
hccr = (struct ehci_hccr *)&priv->reg->cap_length;
hcor = (struct ehci_hcor *)&priv->reg->usb_cmd;
if (!clk_done) {
config_clock(get_pll_timing(&fdt_usb_controllers[priv->type]));
clk_done = true;
}
return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0,
plat->init_type);
}
static int ehci_usb_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 = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
{ }
};
U_BOOT_DRIVER(usb_ehci) = {
.name = "ehci_tegra",
.id = UCLASS_USB,
.of_match = ehci_usb_ids,
.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
.probe = ehci_usb_probe,
.remove = ehci_usb_remove,
.ops = &ehci_usb_ops,
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
.priv_auto_alloc_size = sizeof(struct fdt_usb),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment