diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/blk-uclass.c | 2 | ||||
-rw-r--r-- | drivers/core/device.c | 22 | ||||
-rw-r--r-- | drivers/core/root.c | 7 | ||||
-rw-r--r-- | drivers/misc/cros_ec.c | 16 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 6 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/pcf2127.c | 107 | ||||
-rw-r--r-- | drivers/tpm/tpm_tis_lpc.c | 37 | ||||
-rw-r--r-- | drivers/usb/gadget/ether.c | 168 | ||||
-rw-r--r-- | drivers/usb/musb-new/Kconfig | 9 | ||||
-rw-r--r-- | drivers/usb/musb-new/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/musb-new/am35x.c | 14 | ||||
-rw-r--r-- | drivers/usb/musb-new/musb_dsps.c | 8 | ||||
-rw-r--r-- | drivers/usb/musb-new/ti-musb.c | 255 |
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 = ð_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(ð_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(ð_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 */ |