summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2016-12-03 19:43:51 -0500
committerTom Rini <trini@konsulko.com>2016-12-03 19:43:51 -0500
commit73eed452b9c9827474c0789c30729dca6fcf061d (patch)
treeb33a39a41b7b2891b0171f79ea9b5599658884c3 /drivers
parentbfb380b30ad2d678c09037560abb6f09a5e9c9b6 (diff)
parenta2558e8729831e0bcef634ea2440e60425ef0ff6 (diff)
downloadu-boot-imx-73eed452b9c9827474c0789c30729dca6fcf061d.zip
u-boot-imx-73eed452b9c9827474c0789c30729dca6fcf061d.tar.gz
u-boot-imx-73eed452b9c9827474c0789c30729dca6fcf061d.tar.bz2
Merge branch 'master' of git://www.denx.de/git/u-boot-dm
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/blk-uclass.c2
-rw-r--r--drivers/core/device.c22
-rw-r--r--drivers/core/root.c7
-rw-r--r--drivers/misc/cros_ec.c16
-rw-r--r--drivers/rtc/Kconfig6
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/pcf2127.c107
-rw-r--r--drivers/tpm/tpm_tis_lpc.c37
-rw-r--r--drivers/usb/gadget/ether.c168
-rw-r--r--drivers/usb/musb-new/Kconfig9
-rw-r--r--drivers/usb/musb-new/Makefile1
-rw-r--r--drivers/usb/musb-new/am35x.c14
-rw-r--r--drivers/usb/musb-new/musb_dsps.c8
-rw-r--r--drivers/usb/musb-new/ti-musb.c255
14 files changed, 564 insertions, 89 deletions
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 6ba1026..2e041c2 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -156,6 +156,8 @@ static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
if (ret)
return ret;
+ *descp = desc;
+ return 0;
} else if (desc->devnum > devnum) {
found_more = true;
}
diff --git a/drivers/core/device.c b/drivers/core/device.c
index dcf5d9d..ed553d7 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -693,6 +693,28 @@ fdt_addr_t dev_get_addr_index(struct udevice *dev, int index)
#endif
}
+fdt_addr_t dev_get_addr_size_index(struct udevice *dev, int index,
+ fdt_size_t *size)
+{
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ /*
+ * Only get the size in this first call. We'll get the addr in the
+ * next call to the exisiting dev_get_xxx function which handles
+ * all config options.
+ */
+ fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
+ "reg", index, size, false);
+
+ /*
+ * Get the base address via the existing function which handles
+ * all Kconfig cases
+ */
+ return dev_get_addr_index(dev, index);
+#else
+ return FDT_ADDR_T_NONE;
+#endif
+}
+
fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 33dc9c0..9edfc1e 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -41,6 +41,13 @@ struct udevice *dm_root(void)
return gd->dm_root;
}
+void dm_fixup_for_gd_move(struct global_data *new_gd)
+{
+ /* The sentinel node has moved, so update things that point to it */
+ new_gd->uclass_root.next->prev = &new_gd->uclass_root;
+ new_gd->uclass_root.prev->next = &new_gd->uclass_root;
+}
+
fdt_addr_t dm_get_translation_offset(void)
{
struct udevice *root = dm_root();
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 8073730..759bb46 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -1024,22 +1024,6 @@ int cros_ec_register(struct udevice *dev)
return 0;
}
-int cros_ec_decode_region(int argc, char * const argv[])
-{
- if (argc > 0) {
- if (0 == strcmp(*argv, "rw"))
- return EC_FLASH_REGION_RW;
- else if (0 == strcmp(*argv, "ro"))
- return EC_FLASH_REGION_RO;
-
- debug("%s: Invalid region '%s'\n", __func__, *argv);
- } else {
- debug("%s: Missing region parameter\n", __func__);
- }
-
- return -1;
-}
-
int cros_ec_decode_ec_flash(const void *blob, int node,
struct fdt_cros_ec *config)
{
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index b5d9048..57af1b5 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -13,4 +13,10 @@ config DM_RTC
drivers to perform the actual functions. See rtc.h for a
description of the API.
+config RTC_PCF2127
+ bool "Enable PCF2127 driver"
+ depends on DM_RTC
+ help
+ Enable pcf2127 driver which provides rtc get and set function
+
endmenu
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index fc38a3f..c919427 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_MV) += mvrtc.o
obj-$(CONFIG_RTC_MX27) += mx27rtc.o
obj-$(CONFIG_RTC_MXS) += mxsrtc.o
obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
+obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
obj-$(CONFIG_RTC_PL031) += pl031.o
obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
diff --git a/drivers/rtc/pcf2127.c b/drivers/rtc/pcf2127.c
new file mode 100644
index 0000000..bc59c6c
--- /dev/null
+++ b/drivers/rtc/pcf2127.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 by NXP Semiconductors Inc.
+ * Date & Time support for PCF2127 RTC
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <i2c.h>
+#include <rtc.h>
+
+#define PCF2127_REG_CTRL1 (0x00)
+#define PCF2127_REG_CTRL2 (0x01)
+#define PCF2127_REG_CTRL3 (0x02)
+#define PCF2127_REG_SC (0x03) /* datetime */
+#define PCF2127_REG_MN (0x04)
+#define PCF2127_REG_HR (0x05)
+#define PCF2127_REG_DM (0x06)
+#define PCF2127_REG_DW (0x07)
+#define PCF2127_REG_MO (0x08)
+#define PCF2127_REG_YR (0x09)
+
+static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+ uchar buf[8];
+ int i = 0;
+
+ /* start register address */
+ buf[i++] = PCF2127_REG_SC;
+
+ /* hours, minutes and seconds */
+ buf[i++] = bin2bcd(tm->tm_sec);
+ buf[i++] = bin2bcd(tm->tm_min);
+ buf[i++] = bin2bcd(tm->tm_hour);
+ buf[i++] = bin2bcd(tm->tm_mday);
+ buf[i++] = tm->tm_wday & 0x07;
+
+ /* month, 1 - 12 */
+ buf[i++] = bin2bcd(tm->tm_mon + 1);
+
+ /* year */
+ buf[i++] = bin2bcd(tm->tm_year % 100);
+
+ /* write register's data */
+ if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+ int rel = 0;
+ uchar buf[10] = { PCF2127_REG_CTRL1 };
+
+ if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1) < 0)
+ return -1;
+ if (dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0)
+ return -1;
+
+ if (buf[PCF2127_REG_CTRL3] & 0x04)
+ puts("### Warning: RTC Low Voltage - date/time not reliable\n");
+
+ tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
+ tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
+ tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F);
+ tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
+ tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1;
+ tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]) + 1900;
+ if (tm->tm_year < 1970)
+ tm->tm_year += 100; /* assume we are in 1970...2069 */
+ tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
+ tm->tm_yday = 0;
+ tm->tm_isdst = 0;
+
+ debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ return rel;
+}
+
+static int pcf2127_rtc_reset(struct udevice *dev)
+{
+ /*Doing nothing here*/
+ return 0;
+}
+
+static const struct rtc_ops pcf2127_rtc_ops = {
+ .get = pcf2127_rtc_get,
+ .set = pcf2127_rtc_set,
+ .reset = pcf2127_rtc_reset,
+};
+
+static const struct udevice_id pcf2127_rtc_ids[] = {
+ { .compatible = "pcf2127-rtc" },
+ { }
+};
+
+U_BOOT_DRIVER(rtc_pcf2127) = {
+ .name = "rtc-pcf2127",
+ .id = UCLASS_RTC,
+ .of_match = pcf2127_rtc_ids,
+ .ops = &pcf2127_rtc_ops,
+};
diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c
index b4efbb5..d2b3783 100644
--- a/drivers/tpm/tpm_tis_lpc.c
+++ b/drivers/tpm/tpm_tis_lpc.c
@@ -21,6 +21,21 @@
#define PREFIX "lpc_tpm: "
+enum i2c_chip_type {
+ SLB9635,
+ AT97SC3204,
+};
+
+static const char * const chip_name[] = {
+ [SLB9635] = "Infineon SLB9635 TT 1.2",
+ [AT97SC3204] = "Atmel AT97SC3204",
+};
+
+static const u32 chip_didvid[] = {
+ [SLB9635] = 0xb15d1,
+ [AT97SC3204] = 0x32041114,
+};
+
struct tpm_locality {
u32 access;
u8 padding0[4];
@@ -146,9 +161,9 @@ static int tis_wait_reg(struct tpm_tis_lpc_priv *priv, u32 *reg, u8 mask,
static int tpm_tis_lpc_probe(struct udevice *dev)
{
struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
- u32 vid, did;
fdt_addr_t addr;
u32 didvid;
+ ulong chip_type = dev_get_driver_data(dev);
addr = dev_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
@@ -156,14 +171,15 @@ static int tpm_tis_lpc_probe(struct udevice *dev)
priv->regs = map_sysmem(addr, 0);
didvid = tpm_read_word(priv, &priv->regs[0].did_vid);
- vid = didvid & 0xffff;
- did = (didvid >> 16) & 0xffff;
- if (vid != 0x15d1 || did != 0xb) {
+ if (didvid != chip_didvid[chip_type]) {
+ u32 vid, did;
+ vid = didvid & 0xffff;
+ did = (didvid >> 16) & 0xffff;
debug("Invalid vendor/device ID %04x/%04x\n", vid, did);
- return -ENOSYS;
+ return -ENODEV;
}
- debug("Found TPM %s by %s\n", "SLB9635 TT 1.2", "Infineon");
+ debug("Found TPM: %s\n", chip_name[chip_type]);
return 0;
}
@@ -421,11 +437,13 @@ static int tpm_tis_lpc_close(struct udevice *dev)
static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
{
+ ulong chip_type = dev_get_driver_data(dev);
+
if (size < 50)
return -ENOSPC;
- return snprintf(buf, size, "1.2 TPM (vendor %s, chip %s)",
- "Infineon", "SLB9635 TT 1.2");
+ return snprintf(buf, size, "1.2 TPM (%s)",
+ chip_name[chip_type]);
}
@@ -438,7 +456,8 @@ static const struct tpm_ops tpm_tis_lpc_ops = {
};
static const struct udevice_id tpm_tis_lpc_ids[] = {
- { .compatible = "infineon,slb9635lpc" },
+ { .compatible = "infineon,slb9635lpc", .data = SLB9635 },
+ { .compatible = "atmel,at97sc3204", .data = AT97SC3204 },
{ }
};
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 497b981..046ad8c 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -24,6 +24,10 @@
#include "gadget_chips.h"
#include "rndis.h"
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <dm/device-internal.h>
+
#define USB_NET_NAME "usb_ether"
#define atomic_read
@@ -101,6 +105,9 @@ struct eth_dev {
struct usb_gadget *gadget;
struct usb_request *req; /* for control responses */
struct usb_request *stat_req; /* for cdc & rndis status */
+#ifdef CONFIG_DM_USB
+ struct udevice *usb_udev;
+#endif
u8 config;
struct usb_ep *in_ep, *out_ep, *status_ep;
@@ -134,9 +141,14 @@ struct eth_dev {
*/
/*-------------------------------------------------------------------------*/
-static struct eth_dev l_ethdev;
-static struct eth_device l_netdev;
-static struct usb_gadget_driver eth_driver;
+struct ether_priv {
+ struct eth_dev ethdev;
+ struct eth_device netdev;
+ struct usb_gadget_driver eth_driver;
+};
+
+struct ether_priv eth_priv;
+struct ether_priv *l_priv = &eth_priv;
/*-------------------------------------------------------------------------*/
@@ -1135,7 +1147,7 @@ static void eth_status_complete(struct usb_ep *ep, struct usb_request *req)
event->bNotificationType, value);
if (event->bNotificationType ==
USB_CDC_NOTIFY_SPEED_CHANGE) {
- l_ethdev.network_started = 1;
+ dev->network_started = 1;
printf("USB network up!\n");
}
}
@@ -1323,7 +1335,7 @@ eth_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
* that network is working. So we signalize it
* here.
*/
- l_ethdev.network_started = 1;
+ dev->network_started = 1;
debug("USB network up!\n");
goto done_set_intf;
}
@@ -1823,10 +1835,10 @@ static void rndis_control_ack_complete(struct usb_ep *ep,
debug("rndis control ack complete --> %d, %d/%d\n",
req->status, req->actual, req->length);
- if (!l_ethdev.network_started) {
+ if (!dev->network_started) {
if (rndis_get_state(dev->rndis_config)
== RNDIS_DATA_INITIALIZED) {
- l_ethdev.network_started = 1;
+ dev->network_started = 1;
printf("USB RNDIS network up!\n");
}
}
@@ -1841,7 +1853,8 @@ static char rndis_resp_buf[8] __attribute__((aligned(sizeof(__le32))));
static int rndis_control_ack(struct eth_device *net)
{
- struct eth_dev *dev = &l_ethdev;
+ struct ether_priv *priv = (struct ether_priv *)net->priv;
+ struct eth_dev *dev = &priv->ethdev;
int length;
struct usb_request *resp = dev->stat_req;
@@ -1982,7 +1995,7 @@ static int get_ether_addr(const char *str, u8 *dev_addr)
static int eth_bind(struct usb_gadget *gadget)
{
- struct eth_dev *dev = &l_ethdev;
+ struct eth_dev *dev = &l_priv->ethdev;
u8 cdc = 1, zlp = 1, rndis = 1;
struct usb_ep *in_ep, *out_ep, *status_ep = NULL;
int status = -ENOMEM;
@@ -2175,7 +2188,7 @@ autoconf_fail:
/* network device setup */
- dev->net = &l_netdev;
+ dev->net = &l_priv->netdev;
dev->cdc = cdc;
dev->zlp = zlp;
@@ -2303,19 +2316,39 @@ fail:
/*-------------------------------------------------------------------------*/
-static int usb_eth_init(struct eth_device *netdev, bd_t *bd)
+#ifdef CONFIG_DM_USB
+int dm_usb_init(struct eth_dev *e_dev)
{
- struct eth_dev *dev = &l_ethdev;
+ struct udevice *dev = NULL;
+ int ret;
+
+ ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev);
+ if (!dev || ret) {
+ error("No USB device found\n");
+ return -ENODEV;
+ }
+
+ e_dev->usb_udev = dev;
+
+ return ret;
+}
+#endif
+
+static int _usb_eth_init(struct ether_priv *priv)
+{
+ struct eth_dev *dev = &priv->ethdev;
struct usb_gadget *gadget;
unsigned long ts;
unsigned long timeout = USB_CONNECT_TIMEOUT;
- if (!netdev) {
- error("received NULL ptr");
- goto fail;
+#ifdef CONFIG_DM_USB
+ if (dm_usb_init(dev)) {
+ error("USB ether not found\n");
+ return -ENODEV;
}
-
+#else
board_usb_init(0, USB_INIT_DEVICE);
+#endif
/* Configure default mac-addresses for the USB ethernet device */
#ifdef CONFIG_USBNET_DEV_ADDR
@@ -2342,7 +2375,15 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd)
goto fail;
}
- if (usb_gadget_register_driver(&eth_driver) < 0)
+ priv->eth_driver.speed = DEVSPEED;
+ priv->eth_driver.bind = eth_bind;
+ priv->eth_driver.unbind = eth_unbind;
+ priv->eth_driver.setup = eth_setup;
+ priv->eth_driver.reset = eth_disconnect;
+ priv->eth_driver.disconnect = eth_disconnect;
+ priv->eth_driver.suspend = eth_suspend;
+ priv->eth_driver.resume = eth_resume;
+ if (usb_gadget_register_driver(&priv->eth_driver) < 0)
goto fail;
dev->network_started = 0;
@@ -2357,7 +2398,7 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd)
timeout = simple_strtoul(getenv("cdc_connect_timeout"),
NULL, 10) * CONFIG_SYS_HZ;
ts = get_timer(0);
- while (!l_ethdev.network_started) {
+ while (!dev->network_started) {
/* Handle control-c and timeouts */
if (ctrlc() || (get_timer(ts) > timeout)) {
error("The remote end did not respond in time.");
@@ -2373,11 +2414,11 @@ fail:
return -1;
}
-static int usb_eth_send(struct eth_device *netdev, void *packet, int length)
+static int _usb_eth_send(struct ether_priv *priv, void *packet, int length)
{
int retval;
void *rndis_pkt = NULL;
- struct eth_dev *dev = &l_ethdev;
+ struct eth_dev *dev = &priv->ethdev;
struct usb_request *req = dev->tx_req;
unsigned long ts;
unsigned long timeout = USB_CONNECT_TIMEOUT;
@@ -2442,34 +2483,16 @@ drop:
return -ENOMEM;
}
-static int usb_eth_recv(struct eth_device *netdev)
+static int _usb_eth_recv(struct ether_priv *priv)
{
- struct eth_dev *dev = &l_ethdev;
-
usb_gadget_handle_interrupts(0);
- if (packet_received) {
- debug("%s: packet received\n", __func__);
- if (dev->rx_req) {
- net_process_received_packet(net_rx_packets[0],
- dev->rx_req->length);
- packet_received = 0;
-
- rx_submit(dev, dev->rx_req, 0);
- } else
- error("dev->rx_req invalid");
- }
return 0;
}
-void usb_eth_halt(struct eth_device *netdev)
+void _usb_eth_halt(struct ether_priv *priv)
{
- struct eth_dev *dev = &l_ethdev;
-
- if (!netdev) {
- error("received NULL ptr");
- return;
- }
+ struct eth_dev *dev = &priv->ethdev;
/* If the gadget not registered, simple return */
if (!dev->gadget)
@@ -2496,27 +2519,65 @@ void usb_eth_halt(struct eth_device *netdev)
dev->network_started = 0;
}
- usb_gadget_unregister_driver(&eth_driver);
+ usb_gadget_unregister_driver(&priv->eth_driver);
+#ifdef CONFIG_DM_USB
+ device_remove(dev->usb_udev);
+#else
board_usb_cleanup(0, USB_INIT_DEVICE);
+#endif
+}
+
+static int usb_eth_init(struct eth_device *netdev, bd_t *bd)
+{
+ struct ether_priv *priv = (struct ether_priv *)netdev->priv;
+
+ return _usb_eth_init(priv);
}
-static struct usb_gadget_driver eth_driver = {
- .speed = DEVSPEED,
+static int usb_eth_send(struct eth_device *netdev, void *packet, int length)
+{
+ struct ether_priv *priv = (struct ether_priv *)netdev->priv;
- .bind = eth_bind,
- .unbind = eth_unbind,
+ return _usb_eth_send(priv, packet, length);
+}
- .setup = eth_setup,
- .reset = eth_disconnect,
- .disconnect = eth_disconnect,
+static int usb_eth_recv(struct eth_device *netdev)
+{
+ struct ether_priv *priv = (struct ether_priv *)netdev->priv;
+ struct eth_dev *dev = &priv->ethdev;
+ int ret;
+
+ ret = _usb_eth_recv(priv);
+ if (ret) {
+ error("error packet receive\n");
+ return ret;
+ }
- .suspend = eth_suspend,
- .resume = eth_resume,
-};
+ if (!packet_received)
+ return 0;
+
+ if (dev->rx_req) {
+ net_process_received_packet(net_rx_packets[0],
+ dev->rx_req->length);
+ } else {
+ error("dev->rx_req invalid");
+ }
+ packet_received = 0;
+ rx_submit(dev, dev->rx_req, 0);
+
+ return 0;
+}
+
+void usb_eth_halt(struct eth_device *netdev)
+{
+ struct ether_priv *priv = (struct ether_priv *)netdev->priv;
+
+ _usb_eth_halt(priv);
+}
int usb_eth_initialize(bd_t *bi)
{
- struct eth_device *netdev = &l_netdev;
+ struct eth_device *netdev = &l_priv->netdev;
strlcpy(netdev->name, USB_NET_NAME, sizeof(netdev->name));
@@ -2524,6 +2585,7 @@ int usb_eth_initialize(bd_t *bi)
netdev->send = usb_eth_send;
netdev->recv = usb_eth_recv;
netdev->halt = usb_eth_halt;
+ netdev->priv = l_priv;
#ifdef CONFIG_MCAST_TFTP
#error not supported
diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig
index c264859..caba42c 100644
--- a/drivers/usb/musb-new/Kconfig
+++ b/drivers/usb/musb-new/Kconfig
@@ -14,6 +14,15 @@ config USB_MUSB_GADGET
help
Enables the MUSB USB dual-role controller in gadget mode.
+config USB_MUSB_TI
+ bool "Enable TI OTG USB controller"
+ depends on DM_USB
+ default n
+ help
+ Say y here to enable support for the dual role high
+ speed USB controller based on the Mentor Graphics
+ silicon IP.
+
if USB_MUSB_HOST || USB_MUSB_GADGET
config USB_MUSB_PIC32
diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile
index df1c3c8..296f230 100644
--- a/drivers/usb/musb-new/Makefile
+++ b/drivers/usb/musb-new/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o
obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o
obj-$(CONFIG_USB_MUSB_PIC32) += pic32.o
obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o
+obj-$(CONFIG_USB_MUSB_TI) += ti-musb.o
ccflags-y := $(call cc-option,-Wno-unused-variable) \
$(call cc-option,-Wno-unused-but-set-variable) \
diff --git a/drivers/usb/musb-new/am35x.c b/drivers/usb/musb-new/am35x.c
index b8791dd..0167ea7 100644
--- a/drivers/usb/musb-new/am35x.c
+++ b/drivers/usb/musb-new/am35x.c
@@ -336,7 +336,7 @@ eoi:
if (ret == IRQ_HANDLED || epintr || usbintr) {
/* clear level interrupt */
if (data->clear_irq)
- data->clear_irq();
+ data->clear_irq(data->dev);
/* write EOI */
musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
}
@@ -401,14 +401,14 @@ static int am35x_musb_init(struct musb *musb)
/* Reset the musb */
if (data->reset)
- data->reset();
+ data->reset(data->dev);
/* Reset the controller */
musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK);
/* Start the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(1);
+ data->set_phy_power(data->dev, 1);
msleep(5);
@@ -416,7 +416,7 @@ static int am35x_musb_init(struct musb *musb)
/* clear level interrupt */
if (data->clear_irq)
- data->clear_irq();
+ data->clear_irq(data->dev);
return 0;
}
@@ -439,7 +439,7 @@ static int am35x_musb_exit(struct musb *musb)
/* Shutdown the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(0);
+ data->set_phy_power(data->dev, 0);
#ifndef __UBOOT__
usb_put_phy(musb->xceiv);
@@ -630,7 +630,7 @@ static int am35x_suspend(struct device *dev)
/* Shutdown the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(0);
+ data->set_phy_power(data->dev, 0);
clk_disable(glue->phy_clk);
clk_disable(glue->clk);
@@ -647,7 +647,7 @@ static int am35x_resume(struct device *dev)
/* Start the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(1);
+ data->set_phy_power(data->dev, 1);
ret = clk_enable(glue->phy_clk);
if (ret) {
diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c
index a71db76..399b85b 100644
--- a/drivers/usb/musb-new/musb_dsps.c
+++ b/drivers/usb/musb-new/musb_dsps.c
@@ -452,7 +452,7 @@ static int dsps_musb_init(struct musb *musb)
/* Start the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(1);
+ data->set_phy_power(data->dev, 1);
musb->isr = dsps_interrupt;
@@ -493,7 +493,7 @@ static int dsps_musb_exit(struct musb *musb)
/* Shutdown the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(0);
+ data->set_phy_power(data->dev, 0);
#ifndef __UBOOT__
/* NOP driver needs change if supporting dual instance */
@@ -693,7 +693,7 @@ static int dsps_suspend(struct device *dev)
/* Shutdown the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(0);
+ data->set_phy_power(data->dev, 0);
return 0;
}
@@ -705,7 +705,7 @@ static int dsps_resume(struct device *dev)
/* Start the on-chip PHY and its PLL. */
if (data->set_phy_power)
- data->set_phy_power(1);
+ data->set_phy_power(data->dev, 1);
return 0;
}
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
new file mode 100644
index 0000000..1c15aa2
--- /dev/null
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -0,0 +1,255 @@
+/*
+ * MISC driver for TI MUSB Glue.
+ *
+ * (C) Copyright 2016
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <dm.h>
+#include <linux/usb/otg.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+
+#include <asm/io.h>
+#include <asm/omap_musb.h>
+#include "musb_uboot.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_DM_USB
+
+/* USB 2.0 PHY Control */
+#define CM_PHY_PWRDN (1 << 0)
+#define CM_PHY_OTG_PWRDN (1 << 1)
+#define OTGVDET_EN (1 << 19)
+#define OTGSESSENDEN (1 << 20)
+
+#define AM335X_USB1_CTRL 0x8
+
+struct ti_musb_platdata {
+ void *base;
+ void *ctrl_mod_base;
+ struct musb_hdrc_platform_data plat;
+ struct musb_hdrc_config musb_config;
+ struct omap_musb_board_data otg_board_data;
+};
+
+static int ti_musb_get_usb_index(int node)
+{
+ const void *fdt = gd->fdt_blob;
+ int i = 0;
+ char path[64];
+ const char *alias_path;
+ char alias[16];
+
+ fdt_get_path(fdt, node, path, sizeof(path));
+
+ do {
+ snprintf(alias, sizeof(alias), "usb%d", i);
+ alias_path = fdt_get_alias(fdt, alias);
+ if (alias_path == NULL) {
+ debug("USB index not found\n");
+ return -ENOENT;
+ }
+
+ if (!strcmp(path, alias_path))
+ return i;
+
+ i++;
+ } while (alias_path);
+
+ return -ENOENT;
+}
+
+static void ti_musb_set_phy_power(struct udevice *dev, u8 on)
+{
+ struct ti_musb_platdata *platdata = dev_get_platdata(dev);
+
+ if (on) {
+ clrsetbits_le32(platdata->ctrl_mod_base,
+ CM_PHY_PWRDN | CM_PHY_OTG_PWRDN,
+ OTGVDET_EN | OTGSESSENDEN);
+ } else {
+ clrsetbits_le32(platdata->ctrl_mod_base, 0,
+ CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+ }
+}
+
+static int ti_musb_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ti_musb_platdata *platdata = dev_get_platdata(dev);
+ const void *fdt = gd->fdt_blob;
+ int node = dev->of_offset;
+ int phys;
+ int ctrl_mod;
+ int usb_index;
+
+ platdata->base = (void *)dev_get_addr_index(dev, 1);
+
+ phys = fdtdec_lookup_phandle(fdt, node, "phys");
+ ctrl_mod = fdtdec_lookup_phandle(fdt, phys, "ti,ctrl_mod");
+ platdata->ctrl_mod_base = (void *)fdtdec_get_addr(fdt, ctrl_mod, "reg");
+ usb_index = ti_musb_get_usb_index(node);
+ switch (usb_index) {
+ case 1:
+ platdata->ctrl_mod_base += AM335X_USB1_CTRL;
+ case 0:
+ default:
+ break;
+ }
+
+ platdata->musb_config.multipoint = fdtdec_get_int(fdt, node,
+ "mentor,multipoint",
+ -1);
+ if (platdata->musb_config.multipoint < 0) {
+ error("MUSB multipoint DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->musb_config.dyn_fifo = 1;
+
+ platdata->musb_config.num_eps = fdtdec_get_int(fdt, node,
+ "mentor,num-eps", -1);
+ if (platdata->musb_config.num_eps < 0) {
+ error("MUSB num-eps DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->musb_config.ram_bits = fdtdec_get_int(fdt, node,
+ "mentor,ram-bits", -1);
+ if (platdata->musb_config.ram_bits < 0) {
+ error("MUSB ram-bits DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->otg_board_data.set_phy_power = ti_musb_set_phy_power;
+ platdata->otg_board_data.dev = dev;
+ platdata->plat.config = &platdata->musb_config;
+
+ platdata->plat.power = fdtdec_get_int(fdt, node, "mentor,power", -1);
+ if (platdata->plat.power < 0) {
+ error("MUSB mentor,power DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->plat.platform_ops = &musb_dsps_ops;
+ platdata->plat.board_data = &platdata->otg_board_data;
+
+ return 0;
+}
+
+static int ti_musb_host_probe(struct udevice *dev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ struct ti_musb_platdata *platdata = dev_get_platdata(dev);
+ struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
+ struct omap_musb_board_data *otg_board_data;
+ int ret;
+
+ priv->desc_before_addr = true;
+
+ otg_board_data = &platdata->otg_board_data;
+
+ host->host = musb_init_controller(&platdata->plat,
+ (struct device *)otg_board_data,
+ platdata->base);
+ if (!host->host)
+ return -EIO;
+
+ ret = musb_lowlevel_init(host);
+
+ return ret;
+}
+
+static int ti_musb_host_remove(struct udevice *dev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+
+ musb_stop(host->host);
+
+ return 0;
+}
+
+static int ti_musb_host_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ti_musb_platdata *platdata = dev_get_platdata(dev);
+ const void *fdt = gd->fdt_blob;
+ int node = dev->of_offset;
+ int ret;
+
+ ret = ti_musb_ofdata_to_platdata(dev);
+ if (ret) {
+ error("platdata dt parse error\n");
+ return ret;
+ }
+
+ platdata->plat.mode = MUSB_HOST;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(ti_musb_host) = {
+ .name = "ti-musb-host",
+ .id = UCLASS_USB,
+ .ofdata_to_platdata = ti_musb_host_ofdata_to_platdata,
+ .probe = ti_musb_host_probe,
+ .remove = ti_musb_host_remove,
+ .ops = &musb_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct ti_musb_platdata),
+ .priv_auto_alloc_size = sizeof(struct musb_host_data),
+};
+
+static int ti_musb_wrapper_bind(struct udevice *parent)
+{
+ const void *fdt = gd->fdt_blob;
+ int node;
+ int ret;
+
+ for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0;
+ node = fdt_next_subnode(fdt, node)) {
+ struct udevice *dev;
+ const char *name = fdt_get_name(fdt, node, NULL);
+ enum usb_dr_mode dr_mode;
+ struct driver *drv;
+
+ if (strncmp(name, "usb@", 4))
+ continue;
+
+ dr_mode = usb_get_dr_mode(node);
+ switch (dr_mode) {
+ case USB_DR_MODE_PERIPHERAL:
+ /* Bind MUSB device */
+ break;
+ case USB_DR_MODE_HOST:
+ /* Bind MUSB host */
+ ret = device_bind_driver_to_node(parent, "ti-musb-host",
+ name, node, &dev);
+ if (ret) {
+ error("musb - not able to bind usb host node\n");
+ return ret;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ return 0;
+}
+
+static const struct udevice_id ti_musb_ids[] = {
+ { .compatible = "ti,am33xx-usb" },
+ { }
+};
+
+U_BOOT_DRIVER(ti_musb_wrapper) = {
+ .name = "ti-musb-wrapper",
+ .id = UCLASS_MISC,
+ .of_match = ti_musb_ids,
+ .bind = ti_musb_wrapper_bind,
+};
+
+#endif /* CONFIG_DM_USB */