]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
Merge git://git.denx.de/u-boot-usb
authorTom Rini <trini@konsulko.com>
Sat, 29 Jul 2017 15:43:51 +0000 (11:43 -0400)
committerTom Rini <trini@konsulko.com>
Sat, 29 Jul 2017 15:43:51 +0000 (11:43 -0400)
96 files changed:
Documentation/devicetree/bindings/phy/no-op.txt [new file with mode: 0644]
arch/arm/include/asm/ehci-omap.h
arch/x86/dts/minnowmax.dts
cmd/usb.c
common/usb_hub.c
configs/minnowmax_defconfig
drivers/clk/clk-uclass.c
drivers/core/of_access.c
drivers/core/ofnode.c
drivers/dfu/dfu.c
drivers/dfu/dfu_mmc.c
drivers/dfu/dfu_nand.c
drivers/dfu/dfu_ram.c
drivers/dfu/dfu_sf.c
drivers/phy/Kconfig
drivers/phy/Makefile
drivers/phy/nop-phy.c [new file with mode: 0644]
drivers/phy/phy-uclass.c
drivers/reset/reset-uclass.c
drivers/usb/emul/sandbox_hub.c
drivers/usb/gadget/f_thor.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-generic.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci.h
drivers/usb/host/ohci-generic.c
drivers/usb/host/usb-uclass.c
drivers/usb/host/xhci-dwc3.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
include/clk.h
include/configs/MPC8572DS.h
include/configs/am43xx_evm.h
include/configs/am57xx_evm.h
include/configs/cl-som-am57x.h
include/configs/cm_t43.h
include/configs/cm_t54.h
include/configs/corvus.h
include/configs/dra7xx_evm.h
include/configs/ds414.h
include/configs/duovero.h
include/configs/exynos5-common.h
include/configs/ls1012afrdm.h
include/configs/ls1012aqds.h
include/configs/ls1012ardb.h
include/configs/ls1021aiot.h
include/configs/ls1021aqds.h
include/configs/ls1021atwr.h
include/configs/ls1043aqds.h
include/configs/ls1043ardb.h
include/configs/ls1046aqds.h
include/configs/ls1046ardb.h
include/configs/ls2080aqds.h
include/configs/ls2080ardb.h
include/configs/ma5d4evk.h
include/configs/mcx.h
include/configs/minnowmax.h
include/configs/mvebu_armada-37xx.h
include/configs/mvebu_armada-8k.h
include/configs/mx35pdk.h
include/configs/odroid.h
include/configs/omap3_beagle.h
include/configs/omap3_overo.h
include/configs/omap4_panda.h
include/configs/omap5_uevm.h
include/configs/picosam9g45.h
include/configs/poplar.h
include/configs/rk3328_common.h
include/configs/rk3399_common.h
include/configs/sama5d2_ptc.h
include/configs/snapper9g45.h
include/configs/sunxi-common.h
include/configs/tam3517-common.h
include/configs/tao3530.h
include/configs/tegra114-common.h
include/configs/tegra124-common.h
include/configs/tegra20-common.h
include/configs/tegra210-common.h
include/configs/tegra30-common.h
include/configs/ti_armv7_keystone2.h
include/configs/uniphier.h
include/configs/vinco.h
include/configs/x86-common.h
include/configs/xilinx_zynqmp.h
include/dfu.h
include/dm/of_access.h
include/dm/ofnode.h
include/dm/read.h
include/generic-phy.h
include/reset.h
include/usb.h
include/usb_defs.h
scripts/config_whitelist.txt

diff --git a/Documentation/devicetree/bindings/phy/no-op.txt b/Documentation/devicetree/bindings/phy/no-op.txt
new file mode 100644 (file)
index 0000000..a338112
--- /dev/null
@@ -0,0 +1,16 @@
+NOP PHY driver
+
+This driver is used to stub PHY operations in a driver (USB, SATA).
+This is useful when the 'client' driver (USB, SATA, ...) uses the PHY framework
+and there is no actual PHY harwdare to drive.
+
+Required properties:
+- compatible     : must contain "nop-phy"
+- #phy-cells     : must contain <0>
+
+Example:
+
+nop_phy {
+       compatible = "nop-phy";
+       #phy-cells = <0>;
+};
index 5a53e403a602d96744c33f5449b3f9ac16e51a06..9dbb2c4c66a036ed1459431a227e411018e1d5ec 100644 (file)
@@ -19,11 +19,7 @@ enum usbhs_omap_port_mode {
        OMAP_EHCI_PORT_MODE_HSIC,
 };
 
-#ifdef CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS
-#define OMAP_HS_USB_PORTS      CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS
-#else
 #define OMAP_HS_USB_PORTS      3
-#endif
 
 #define is_ehci_phy_mode(x)    ((x) == OMAP_EHCI_PORT_MODE_PHY)
 #define is_ehci_tll_mode(x)    ((x) == OMAP_EHCI_PORT_MODE_TLL)
index 4c0a8fe26f2df8ee2b20788cdd4e5f81d423fa94..a0ad03ce23973384060033d6f495f7dfbb43dabf 100644 (file)
                fsp,enable-spi;
                fsp,enable-sata;
                fsp,sata-mode = <SATA_MODE_AHCI>;
+#ifdef CONFIG_USB_XHCI_HCD
+               fsp,enable-xhci;
+#endif
                fsp,lpe-mode = <LPE_MODE_PCI>;
                fsp,lpss-sio-mode = <LPSS_SIO_MODE_PCI>;
                fsp,enable-dma0;
index 4fa456e318347452785edf5a2239fda63a1a6458..992d41408191c8fa20445a378ba80148850f8fde 100644 (file)
--- a/cmd/usb.c
+++ b/cmd/usb.c
@@ -150,6 +150,8 @@ static void usb_display_string(struct usb_device *dev, int index)
 
 static void usb_display_desc(struct usb_device *dev)
 {
+       uint packet_size = dev->descriptor.bMaxPacketSize0;
+
        if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) {
                printf("%d: %s,  USB Revision %x.%x\n", dev->devnum,
                usb_get_class_desc(dev->config.if_desc[0].desc.bInterfaceClass),
@@ -171,9 +173,10 @@ static void usb_display_desc(struct usb_device *dev)
                               usb_get_class_desc(
                                dev->config.if_desc[0].desc.bInterfaceClass));
                }
+               if (dev->descriptor.bcdUSB >= cpu_to_le16(0x0300))
+                       packet_size = 1 << packet_size;
                printf(" - PacketSize: %d  Configurations: %d\n",
-                       dev->descriptor.bMaxPacketSize0,
-                       dev->descriptor.bNumConfigurations);
+                       packet_size, dev->descriptor.bNumConfigurations);
                printf(" - Vendor: 0x%04x  Product 0x%04x Version %d.%d\n",
                        dev->descriptor.idVendor, dev->descriptor.idProduct,
                        (dev->descriptor.bcdDevice>>8) & 0xff,
index d135526e4fe87b4fc776a14e81a9cdfe7cd10eeb..70bc6e2931164d31fd0f86ad71a314b713870c9b 100644 (file)
@@ -55,9 +55,6 @@ struct usb_device_scan {
        struct list_head list;
 };
 
-/* TODO(sjg@chromium.org): Remove this when CONFIG_DM_USB is defined */
-static struct usb_hub_device hub_dev[USB_MAX_HUB];
-static int usb_hub_index;
 static LIST_HEAD(usb_scan_list);
 
 __weak void usb_hub_reset_devices(int port)
@@ -65,11 +62,41 @@ __weak void usb_hub_reset_devices(int port)
        return;
 }
 
+static inline bool usb_hub_is_superspeed(struct usb_device *hdev)
+{
+       return hdev->descriptor.bDeviceProtocol == 3;
+}
+
+#ifdef CONFIG_DM_USB
+bool usb_hub_is_root_hub(struct udevice *hub)
+{
+       if (device_get_uclass_id(hub->parent) != UCLASS_USB_HUB)
+               return true;
+
+       return false;
+}
+
+static int usb_set_hub_depth(struct usb_device *dev, int depth)
+{
+       if (depth < 0 || depth > 4)
+               return -EINVAL;
+
+       return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+               USB_REQ_SET_HUB_DEPTH, USB_DIR_OUT | USB_RT_HUB,
+               depth, 0, NULL, 0, USB_CNTL_TIMEOUT);
+}
+#endif
+
 static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
 {
+       unsigned short dtype = USB_DT_HUB;
+
+       if (usb_hub_is_superspeed(dev))
+               dtype = USB_DT_SS_HUB;
+
        return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
                USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-               USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
+               dtype << 8, 0, data, size, USB_CNTL_TIMEOUT);
 }
 
 static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
@@ -95,9 +122,40 @@ static int usb_get_hub_status(struct usb_device *dev, void *data)
 
 int usb_get_port_status(struct usb_device *dev, int port, void *data)
 {
-       return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+       int ret;
+
+       ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
                        USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
-                       data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+                       data, sizeof(struct usb_port_status), USB_CNTL_TIMEOUT);
+
+#ifdef CONFIG_DM_USB
+       if (ret < 0)
+               return ret;
+
+       /*
+        * Translate the USB 3.0 hub port status field into the old version
+        * that U-Boot understands. Do this only when the hub is not root hub.
+        * For root hub, the port status field has already been translated
+        * in the host controller driver (see xhci_submit_root() in xhci.c).
+        *
+        * Note: this only supports driver model.
+        */
+
+       if (!usb_hub_is_root_hub(dev->dev) && usb_hub_is_superspeed(dev)) {
+               struct usb_port_status *status = (struct usb_port_status *)data;
+               u16 tmp = (status->wPortStatus) & USB_SS_PORT_STAT_MASK;
+
+               if (status->wPortStatus & USB_SS_PORT_STAT_POWER)
+                       tmp |= USB_PORT_STAT_POWER;
+               if ((status->wPortStatus & USB_SS_PORT_STAT_SPEED) ==
+                   USB_SS_PORT_STAT_SPEED_5GBPS)
+                       tmp |= USB_PORT_STAT_SUPER_SPEED;
+
+               status->wPortStatus = tmp;
+       }
+#endif
+
+       return ret;
 }
 
 
@@ -154,6 +212,10 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
              max(100, (int)pgood_delay) + 1000);
 }
 
+#ifndef CONFIG_DM_USB
+static struct usb_hub_device hub_dev[USB_MAX_HUB];
+static int usb_hub_index;
+
 void usb_hub_reset(void)
 {
        usb_hub_index = 0;
@@ -170,6 +232,7 @@ static struct usb_hub_device *usb_hub_allocate(void)
        printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB);
        return NULL;
 }
+#endif
 
 #define MAX_TRIES 5
 
@@ -195,8 +258,18 @@ static inline char *portspeed(int portstatus)
        return speed_str;
 }
 
-int legacy_hub_port_reset(struct usb_device *dev, int port,
-                       unsigned short *portstat)
+/**
+ * usb_hub_port_reset() - reset a port given its usb_device pointer
+ *
+ * Reset a hub port and see if a device is present on that port, providing
+ * sufficient time for it to show itself. The port status is returned.
+ *
+ * @dev:       USB device to reset
+ * @port:      Port number to reset (note ports are numbered from 0 here)
+ * @portstat:  Returns port status
+ */
+static int usb_hub_port_reset(struct usb_device *dev, int port,
+                             unsigned short *portstat)
 {
        int err, tries;
        ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
@@ -269,15 +342,6 @@ int legacy_hub_port_reset(struct usb_device *dev, int port,
        return 0;
 }
 
-#ifdef CONFIG_DM_USB
-int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat)
-{
-       struct usb_device *udev = dev_get_parent_priv(dev);
-
-       return legacy_hub_port_reset(udev, port, portstat);
-}
-#endif
-
 int usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
        ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
@@ -311,7 +375,7 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)
        }
 
        /* Reset the port */
-       ret = legacy_hub_port_reset(dev, port, &portstatus);
+       ret = usb_hub_port_reset(dev, port, &portstatus);
        if (ret < 0) {
                if (ret != -ENXIO)
                        printf("cannot reset port %i!?\n", port + 1);
@@ -405,8 +469,15 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)
        portchange = le16_to_cpu(portsts->wPortChange);
        debug("Port %d Status %X Change %X\n", i + 1, portstatus, portchange);
 
-       /* No connection change happened, wait a bit more. */
-       if (!(portchange & USB_PORT_STAT_C_CONNECTION)) {
+       /*
+        * No connection change happened, wait a bit more.
+        *
+        * For some situation, the hub reports no connection change but a
+        * device is connected to the port (eg: CCS bit is set but CSC is not
+        * in the PORTSC register of a root hub), ignore such case.
+        */
+       if (!(portchange & USB_PORT_STAT_C_CONNECTION) &&
+           !(portstatus & USB_PORT_STAT_CONNECTION)) {
                if (get_timer(0) >= hub->connect_timeout) {
                        debug("devnum=%d port=%d: timeout\n",
                              dev->devnum, i + 1);
@@ -418,10 +489,6 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)
                return 0;
        }
 
-       /* Test if the connection came up, and if not exit */
-       if (!(portstatus & USB_PORT_STAT_CONNECTION))
-               return 0;
-
        /* A new USB device is ready at this point */
        debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1);
 
@@ -530,6 +597,20 @@ out:
        return ret;
 }
 
+static struct usb_hub_device *usb_get_hub_device(struct usb_device *dev)
+{
+       struct usb_hub_device *hub;
+
+#ifndef CONFIG_DM_USB
+       /* "allocate" Hub device */
+       hub = usb_hub_allocate();
+#else
+       hub = dev_get_uclass_priv(dev->dev);
+#endif
+
+       return hub;
+}
+
 static int usb_hub_configure(struct usb_device *dev)
 {
        int i, length;
@@ -541,11 +622,11 @@ static int usb_hub_configure(struct usb_device *dev)
        __maybe_unused struct usb_hub_status *hubsts;
        int ret;
 
-       /* "allocate" Hub device */
-       hub = usb_hub_allocate();
+       hub = usb_get_hub_device(dev);
        if (hub == NULL)
                return -ENOMEM;
        hub->pusb_dev = dev;
+
        /* Get the the hub descriptor */
        ret = usb_get_hub_descriptor(dev, buffer, 4);
        if (ret < 0) {
@@ -570,17 +651,19 @@ static int usb_hub_configure(struct usb_device *dev)
                        &descriptor->wHubCharacteristics)),
                        &hub->desc.wHubCharacteristics);
        /* set the bitmap */
-       bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
+       bitmap = (unsigned char *)&hub->desc.u.hs.DeviceRemovable[0];
        /* devices not removable by default */
        memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
-       bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
+       bitmap = (unsigned char *)&hub->desc.u.hs.PortPowerCtrlMask[0];
        memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
 
        for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
-               hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
+               hub->desc.u.hs.DeviceRemovable[i] =
+                       descriptor->u.hs.DeviceRemovable[i];
 
        for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
-               hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
+               hub->desc.u.hs.PortPowerCtrlMask[i] =
+                       descriptor->u.hs.PortPowerCtrlMask[i];
 
        dev->maxchild = descriptor->bNbrPorts;
        debug("%d ports detected\n", dev->maxchild);
@@ -617,6 +700,56 @@ static int usb_hub_configure(struct usb_device *dev)
                break;
        }
 
+       switch (dev->descriptor.bDeviceProtocol) {
+       case USB_HUB_PR_FS:
+               break;
+       case USB_HUB_PR_HS_SINGLE_TT:
+               debug("Single TT\n");
+               break;
+       case USB_HUB_PR_HS_MULTI_TT:
+               ret = usb_set_interface(dev, 0, 1);
+               if (ret == 0) {
+                       debug("TT per port\n");
+                       hub->tt.multi = true;
+               } else {
+                       debug("Using single TT (err %d)\n", ret);
+               }
+               break;
+       case USB_HUB_PR_SS:
+               /* USB 3.0 hubs don't have a TT */
+               break;
+       default:
+               debug("Unrecognized hub protocol %d\n",
+                     dev->descriptor.bDeviceProtocol);
+               break;
+       }
+
+       /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
+       switch (hubCharacteristics & HUB_CHAR_TTTT) {
+       case HUB_TTTT_8_BITS:
+               if (dev->descriptor.bDeviceProtocol != 0) {
+                       hub->tt.think_time = 666;
+                       debug("TT requires at most %d FS bit times (%d ns)\n",
+                             8, hub->tt.think_time);
+               }
+               break;
+       case HUB_TTTT_16_BITS:
+               hub->tt.think_time = 666 * 2;
+               debug("TT requires at most %d FS bit times (%d ns)\n",
+                     16, hub->tt.think_time);
+               break;
+       case HUB_TTTT_24_BITS:
+               hub->tt.think_time = 666 * 3;
+               debug("TT requires at most %d FS bit times (%d ns)\n",
+                     24, hub->tt.think_time);
+               break;
+       case HUB_TTTT_32_BITS:
+               hub->tt.think_time = 666 * 4;
+               debug("TT requires at most %d FS bit times (%d ns)\n",
+                     32, hub->tt.think_time);
+               break;
+       }
+
        debug("power on to power good time: %dms\n",
              descriptor->bPwrOn2PwrGood * 2);
        debug("hub controller current requirement: %dmA\n",
@@ -624,7 +757,7 @@ static int usb_hub_configure(struct usb_device *dev)
 
        for (i = 0; i < dev->maxchild; i++)
                debug("port %d is%s removable\n", i + 1,
-                     hub->desc.DeviceRemovable[(i + 1) / 8] & \
+                     hub->desc.u.hs.DeviceRemovable[(i + 1) / 8] & \
                      (1 << ((i + 1) % 8)) ? " not" : "");
 
        if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
@@ -653,6 +786,59 @@ static int usb_hub_configure(struct usb_device *dev)
        debug("%sover-current condition exists\n",
              (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
              "" : "no ");
+
+#ifdef CONFIG_DM_USB
+       /*
+        * Update USB host controller's internal representation of this hub
+        * after the hub descriptor is fetched.
+        */
+       ret = usb_update_hub_device(dev);
+       if (ret < 0 && ret != -ENOSYS) {
+               debug("%s: failed to update hub device for HCD (%x)\n",
+                     __func__, ret);
+               return ret;
+       }
+
+       /*
+        * A maximum of seven tiers are allowed in a USB topology, and the
+        * root hub occupies the first tier. The last tier ends with a normal
+        * USB device. USB 3.0 hubs use a 20-bit field called 'route string'
+        * to route packets to the designated downstream port. The hub uses a
+        * hub depth value multiplied by four as an offset into the 'route
+        * string' to locate the bits it uses to determine the downstream
+        * port number.
+        */
+       if (usb_hub_is_root_hub(dev->dev)) {
+               hub->hub_depth = -1;
+       } else {
+               struct udevice *hdev;
+               int depth = 0;
+
+               hdev = dev->dev->parent;
+               while (!usb_hub_is_root_hub(hdev)) {
+                       depth++;
+                       hdev = hdev->parent;
+               }
+
+               hub->hub_depth = depth;
+
+               if (usb_hub_is_superspeed(dev)) {
+                       debug("set hub (%p) depth to %d\n", dev, depth);
+                       /*
+                        * This request sets the value that the hub uses to
+                        * determine the index into the 'route string index'
+                        * for this hub.
+                        */
+                       ret = usb_set_hub_depth(dev, depth);
+                       if (ret < 0) {
+                               debug("%s: failed to set hub depth (%lX)\n",
+                                     __func__, dev->status);
+                               return ret;
+                       }
+               }
+       }
+#endif
+
        usb_hub_power_on(hub);
 
        /*
@@ -777,6 +963,7 @@ UCLASS_DRIVER(usb_hub) = {
        .child_pre_probe        = usb_child_pre_probe,
        .per_child_auto_alloc_size = sizeof(struct usb_device),
        .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+       .per_device_auto_alloc_size = sizeof(struct usb_hub_device),
 };
 
 static const struct usb_device_id hub_id_table[] = {
index 81e8253719530a333a1b4109dee880ddce665ac8..d05875310a1c6bb92fa1cf2475a0316b1aa9275e 100644 (file)
@@ -69,6 +69,7 @@ CONFIG_ICH_SPI=y
 CONFIG_TIMER=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
index 83b63288fb9bae96337ddd74ca31888199134e83..e68d9279b96322737e14125d25d65ae029688e30 100644 (file)
@@ -65,6 +65,8 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
        debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
 
        assert(clk);
+       clk->dev = NULL;
+
        ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
                                          index, &args);
        if (ret) {
@@ -102,6 +104,7 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
        int index;
 
        debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);
+       clk->dev = NULL;
 
        index = dev_read_stringlist_search(dev, "clock-names", name);
        if (index < 0) {
@@ -111,6 +114,30 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
 
        return clk_get_by_index(dev, index, clk);
 }
+
+int clk_release_all(struct clk *clk, int count)
+{
+       int i, ret;
+
+       for (i = 0; i < count; i++) {
+               debug("%s(clk[%d]=%p)\n", __func__, i, &clk[i]);
+
+               /* check if clock has been previously requested */
+               if (!clk[i].dev)
+                       continue;
+
+               ret = clk_disable(&clk[i]);
+               if (ret && ret != -ENOSYS)
+                       return ret;
+
+               ret = clk_free(&clk[i]);
+               if (ret && ret != -ENOSYS)
+                       return ret;
+       }
+
+       return 0;
+}
+
 #endif /* OF_CONTROL */
 
 int clk_request(struct udevice *dev, struct clk *clk)
index 2bb23eef8850743d2e68a8af57b88fcca5a3af71..c31cba7fd6b501fd6ffcb5ee0c5ba0a239f52dfa 100644 (file)
@@ -665,6 +665,13 @@ int of_parse_phandle_with_args(const struct device_node *np,
                                            index, out_args);
 }
 
+int of_count_phandle_with_args(const struct device_node *np,
+                              const char *list_name, const char *cells_name)
+{
+       return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
+                                           -1, NULL);
+}
+
 static void of_alias_add(struct alias_prop *ap, struct device_node *np,
                         int id, const char *stem, int stem_len)
 {
index c3fb0ae7b9124188d2f1d0e9b5a28300fa282027..c1a2e9f0daefdffef2b7087e91d5b23f86bb1c6e 100644 (file)
@@ -315,6 +315,18 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
        return 0;
 }
 
+int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
+                                  const char *cells_name)
+{
+       if (ofnode_is_np(node))
+               return of_count_phandle_with_args(ofnode_to_np(node),
+                               list_name, cells_name);
+       else
+               return fdtdec_parse_phandle_with_args(gd->fdt_blob,
+                               ofnode_to_offset(node), list_name, cells_name,
+                               0, -1, NULL);
+}
+
 ofnode ofnode_path(const char *path)
 {
        if (of_live_active())
index ceb33e35eed212e837a2f5571cea86f70c135806..f6281f4baad42aba448d55f05268fbd4a0524749 100644 (file)
@@ -165,18 +165,48 @@ static int dfu_write_buffer_drain(struct dfu_entity *dfu)
        return ret;
 }
 
-void dfu_write_transaction_cleanup(struct dfu_entity *dfu)
+void dfu_transaction_cleanup(struct dfu_entity *dfu)
 {
        /* clear everything */
        dfu->crc = 0;
        dfu->offset = 0;
        dfu->i_blk_seq_num = 0;
-       dfu->i_buf_start = dfu_buf;
-       dfu->i_buf_end = dfu_buf;
+       dfu->i_buf_start = dfu_get_buf(dfu);
+       dfu->i_buf_end = dfu->i_buf_start;
        dfu->i_buf = dfu->i_buf_start;
+       dfu->r_left = 0;
+       dfu->b_left = 0;
+       dfu->bad_skip = 0;
+
        dfu->inited = 0;
 }
 
+int dfu_transaction_initiate(struct dfu_entity *dfu, bool read)
+{
+       int ret = 0;
+
+       if (dfu->inited)
+               return 0;
+
+       dfu_transaction_cleanup(dfu);
+
+       if (dfu->i_buf_start == NULL)
+               return -ENOMEM;
+
+       dfu->i_buf_end = dfu->i_buf_start + dfu_get_buf_size();
+
+       if (read) {
+               ret = dfu->get_medium_size(dfu, &dfu->r_left);
+               if (ret < 0)
+                       return ret;
+               debug("%s: %s %lld [B]\n", __func__, dfu->name, dfu->r_left);
+       }
+
+       dfu->inited = 1;
+
+       return 0;
+}
+
 int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 {
        int ret = 0;
@@ -192,7 +222,7 @@ int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name,
                       dfu->crc);
 
-       dfu_write_transaction_cleanup(dfu);
+       dfu_transaction_cleanup(dfu);
 
        return ret;
 }
@@ -205,25 +235,14 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
              __func__, dfu->name, buf, size, blk_seq_num, dfu->offset,
              (unsigned long)(dfu->i_buf - dfu->i_buf_start));
 
-       if (!dfu->inited) {
-               /* initial state */
-               dfu->crc = 0;
-               dfu->offset = 0;
-               dfu->bad_skip = 0;
-               dfu->i_blk_seq_num = 0;
-               dfu->i_buf_start = dfu_get_buf(dfu);
-               if (dfu->i_buf_start == NULL)
-                       return -ENOMEM;
-               dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size;
-               dfu->i_buf = dfu->i_buf_start;
-
-               dfu->inited = 1;
-       }
+       ret = dfu_transaction_initiate(dfu, false);
+       if (ret < 0)
+               return ret;
 
        if (dfu->i_blk_seq_num != blk_seq_num) {
                printf("%s: Wrong sequence number! [%d] [%d]\n",
                       __func__, dfu->i_blk_seq_num, blk_seq_num);
-               dfu_write_transaction_cleanup(dfu);
+               dfu_transaction_cleanup(dfu);
                return -1;
        }
 
@@ -247,7 +266,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
        if ((dfu->i_buf + size) > dfu->i_buf_end) {
                ret = dfu_write_buffer_drain(dfu);
                if (ret) {
-                       dfu_write_transaction_cleanup(dfu);
+                       dfu_transaction_cleanup(dfu);
                        return ret;
                }
        }
@@ -256,7 +275,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
        if ((dfu->i_buf + size) > dfu->i_buf_end) {
                error("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf,
                      size, dfu->i_buf_end);
-               dfu_write_transaction_cleanup(dfu);
+               dfu_transaction_cleanup(dfu);
                return -1;
        }
 
@@ -267,7 +286,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
        if (size == 0 || (dfu->i_buf + size) > dfu->i_buf_end) {
                ret = dfu_write_buffer_drain(dfu);
                if (ret) {
-                       dfu_write_transaction_cleanup(dfu);
+                       dfu_transaction_cleanup(dfu);
                        return ret;
                }
        }
@@ -334,28 +353,9 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
        debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n",
               __func__, dfu->name, buf, size, blk_seq_num, dfu->i_buf);
 
-       if (!dfu->inited) {
-               dfu->i_buf_start = dfu_get_buf(dfu);
-               if (dfu->i_buf_start == NULL)
-                       return -ENOMEM;
-
-               dfu->r_left = dfu->get_medium_size(dfu);
-               if (dfu->r_left < 0)
-                       return dfu->r_left;
-
-               debug("%s: %s %ld [B]\n", __func__, dfu->name, dfu->r_left);
-
-               dfu->i_blk_seq_num = 0;
-               dfu->crc = 0;
-               dfu->offset = 0;
-               dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size;
-               dfu->i_buf = dfu->i_buf_start;
-               dfu->b_left = 0;
-
-               dfu->bad_skip = 0;
-
-               dfu->inited = 1;
-       }
+       ret = dfu_transaction_initiate(dfu, true);
+       if (ret < 0)
+               return ret;
 
        if (dfu->i_blk_seq_num != blk_seq_num) {
                printf("%s: Wrong sequence number! [%d] [%d]\n",
@@ -377,17 +377,7 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                              dfu_hash_algo->name, dfu->crc);
                puts("\nUPLOAD ... done\nCtrl+C to exit ...\n");
 
-               dfu->i_blk_seq_num = 0;
-               dfu->crc = 0;
-               dfu->offset = 0;
-               dfu->i_buf_start = dfu_buf;
-               dfu->i_buf_end = dfu_buf;
-               dfu->i_buf = dfu->i_buf_start;
-               dfu->b_left = 0;
-
-               dfu->bad_skip = 0;
-
-               dfu->inited = 0;
+               dfu_transaction_cleanup(dfu);
        }
 
        return ret;
index 926ccbd2ef5e9eac95d2083f6047c9abcee2ef0a..bb23e7fdcb08e8f683e575d2264c994cef45cc50 100644 (file)
@@ -17,7 +17,7 @@
 #include <mmc.h>
 
 static unsigned char *dfu_file_buf;
-static long dfu_file_buf_len;
+static u64 dfu_file_buf_len;
 static long dfu_file_buf_filled;
 
 static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
@@ -107,7 +107,7 @@ static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len)
 }
 
 static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
-                       void *buf, long *len)
+                       void *buf, u64 *len)
 {
        const char *fsname, *opname;
        char cmd_buf[DFU_CMD_BUF_SIZE];
@@ -150,7 +150,7 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
        sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name);
 
        if (op == DFU_OP_WRITE)
-               sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len);
+               sprintf(cmd_buf + strlen(cmd_buf), " %llx", *len);
 
        debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf);
 
@@ -209,23 +209,23 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu)
        return ret;
 }
 
-long dfu_get_medium_size_mmc(struct dfu_entity *dfu)
+int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 *size)
 {
        int ret;
-       long len;
 
        switch (dfu->layout) {
        case DFU_RAW_ADDR:
-               return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size;
+               *size = dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size;
+               return 0;
        case DFU_FS_FAT:
        case DFU_FS_EXT4:
                dfu_file_buf_filled = -1;
-               ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len);
+               ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, size);
                if (ret < 0)
                        return ret;
-               if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE)
+               if (*size > CONFIG_SYS_DFU_MAX_FILE_SIZE)
                        return -1;
-               return len;
+               return 0;
        default:
                printf("%s: Layout (%s) not (yet) supported!\n", __func__,
                       dfu_get_layout(dfu->layout));
@@ -237,7 +237,7 @@ static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf,
                             long *len)
 {
        int ret;
-       long file_len;
+       u64 file_len;
 
        if (dfu_file_buf_filled == -1) {
                ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len);
index 97cd608e30868d3eaf6b61f73d705db164d6feba..6dc9ff7aeaf77b756d244dc69fe1ab4ef657a717 100644 (file)
@@ -114,9 +114,11 @@ static int dfu_write_medium_nand(struct dfu_entity *dfu,
        return ret;
 }
 
-long dfu_get_medium_size_nand(struct dfu_entity *dfu)
+int dfu_get_medium_size_nand(struct dfu_entity *dfu, u64 *size)
 {
-       return dfu->data.nand.size;
+       *size = dfu->data.nand.size;
+
+       return 0;
 }
 
 static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,
index c1b00217c911bb265df23445a50177cf7dc88eb8..6e3f5316f5ada793bcbcf02be408167a3cca2c37 100644 (file)
@@ -41,9 +41,11 @@ static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset,
        return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len);
 }
 
-long dfu_get_medium_size_ram(struct dfu_entity *dfu)
+int dfu_get_medium_size_ram(struct dfu_entity *dfu, u64 *size)
 {
-       return dfu->data.ram.size;
+       *size = dfu->data.ram.size;
+
+       return 0;
 }
 
 static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset,
index b6d5fe24dc82e56620460185c875243bb0c8ef63..2d2586db52ad0a9c9ca56d33b115c5b6ff37f9f6 100644 (file)
 #include <spi.h>
 #include <spi_flash.h>
 
-static long dfu_get_medium_size_sf(struct dfu_entity *dfu)
+static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
 {
-       return dfu->data.sf.size;
+       *size = dfu->data.sf.size;
+
+       return 0;
 }
 
 static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
index 7841554d091937c85d9aa5c0d118f8350785578f..98f2a1b04713f3dcc192aecc2299cb510e4523bf 100644 (file)
@@ -41,6 +41,24 @@ config PHY_SANDBOX
          This select a dummy sandbox PHY driver. It used only to implement
          the unit tests for the phy framework
 
+config NOP_PHY
+       bool "NOP PHY driver"
+       depends on PHY
+       help
+         Support for a no-op PHY driver (stubbed PHY driver).
+
+         This is useful when a driver uses the PHY framework but no real PHY
+         hardware exists.
+
+config SPL_NOP_PHY
+       bool "NOP PHY driver in SPL"
+       depends on SPL_PHY
+       help
+         Support for a no-op PHY driver (stubbed PHY driver) in the SPL.
+
+         This is useful when a driver uses the PHY framework but no real PHY
+         hardware exists.
+
 config PIPE3_PHY
        bool "Support omap's PIPE3 PHY"
        depends on PHY && ARCH_OMAP2PLUS
index 6ce96d2cccb0c9cfd1ec11428d0b4f2545baa5f6..ab56c46bb45f8f012c94f8d331a2dabedaa97582 100644 (file)
@@ -6,5 +6,6 @@
 #
 
 obj-$(CONFIG_$(SPL_)PHY) += phy-uclass.o
+obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o
 obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
 obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c
new file mode 100644 (file)
index 0000000..2201cc3
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device.h>
+#include <generic-phy.h>
+
+static const struct udevice_id nop_phy_ids[] = {
+       { .compatible = "nop-phy" },
+       { }
+};
+
+static struct phy_ops nop_phy_ops = {
+};
+
+U_BOOT_DRIVER(nop_phy) = {
+       .name   = "nop_phy",
+       .id     = UCLASS_PHY,
+       .of_match = nop_phy_ids,
+       .ops = &nop_phy_ops,
+};
index d8b8d58e44f30d8f1cbc4423f7542f343a5c6ff2..68e518fc79008be1bbeff09cf71a6750447ee619 100644 (file)
@@ -45,6 +45,7 @@ int generic_phy_get_by_index(struct udevice *dev, int index,
        debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
 
        assert(phy);
+       phy->dev = NULL;
        ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
                                         &args);
        if (ret) {
index de3695ffaafc8a581a79c156e6284efd8b694d8f..307a29705f154640273521ca39fc7d70f8cc65c4 100644 (file)
@@ -42,6 +42,7 @@ int reset_get_by_index(struct udevice *dev, int index,
 
        debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
              reset_ctl);
+       reset_ctl->dev = NULL;
 
        ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0,
                                          index, &args);
@@ -87,6 +88,7 @@ int reset_get_by_name(struct udevice *dev, const char *name,
 
        debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
              reset_ctl);
+       reset_ctl->dev = NULL;
 
        index = dev_read_stringlist_search(dev, "reset-names", name);
        if (index < 0) {
@@ -97,6 +99,15 @@ int reset_get_by_name(struct udevice *dev, const char *name,
        return reset_get_by_index(dev, index, reset_ctl);
 }
 
+int reset_request(struct reset_ctl *reset_ctl)
+{
+       struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
+
+       debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
+
+       return ops->request(reset_ctl);
+}
+
 int reset_free(struct reset_ctl *reset_ctl)
 {
        struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
@@ -124,6 +135,29 @@ int reset_deassert(struct reset_ctl *reset_ctl)
        return ops->rst_deassert(reset_ctl);
 }
 
+int reset_release_all(struct reset_ctl *reset_ctl, int count)
+{
+       int i, ret;
+
+       for (i = 0; i < count; i++) {
+               debug("%s(reset_ctl[%d]=%p)\n", __func__, i, &reset_ctl[i]);
+
+               /* check if reset has been previously requested */
+               if (!reset_ctl[i].dev)
+                       continue;
+
+               ret = reset_assert(&reset_ctl[i]);
+               if (ret)
+                       return ret;
+
+               ret = reset_free(&reset_ctl[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 UCLASS_DRIVER(reset) = {
        .id             = UCLASS_RESET,
        .name           = "reset",
index 9ffda9cc7479061cfd121a47d5a5838da5c1447d..1432858fd594cd3b70ba7b4a4b0ddb9334fd3f35 100644 (file)
@@ -96,7 +96,12 @@ static struct usb_hub_descriptor hub_desc = {
                                                                1 << 7),
        .bPwrOn2PwrGood         = 2,
        .bHubContrCurrent       = 5,
-       .DeviceRemovable        = {0, 0xff}, /* all ports removeable */
+       {
+               {
+                       /* all ports removeable */
+                       .DeviceRemovable        = {0, 0xff}
+               }
+       }
 #if SANDBOX_NUM_PORTS > 8
 #error "This code sets up an incorrect mask"
 #endif
index a60e9487e7746d62a98d8aa04db11a335aeb9f9c..cd4d9e659a39bb7b205a1898531194c71901c439 100644 (file)
@@ -891,6 +891,7 @@ static void thor_func_disable(struct usb_function *f)
        }
 
        if (dev->out_ep->driver_data) {
+               free(dev->out_req->buf);
                dev->out_req->buf = NULL;
                usb_ep_free_request(dev->out_ep, dev->out_req);
                usb_ep_disable(dev->out_ep);
index bc2c1f17e588e762e3dadf4774108bdbe5b0af02..67ad72b4a2c2e6c2f9d4f39aac9ccdc11fec9758 100644 (file)
@@ -31,6 +31,13 @@ config USB_XHCI_MVEBU
          SoCs, which includes Armada8K, Armada3700 and other Armada
          family SoCs.
 
+config USB_XHCI_PCI
+       bool "Support for PCI-based xHCI USB controller"
+       depends on DM_USB
+       default y if X86
+       help
+         Enables support for the PCI-based xHCI controller.
+
 config USB_XHCI_ROCKCHIP
        bool "Support for Rockchip on-chip xHCI USB controller"
        depends on ARCH_ROCKCHIP
index fb7846289372b0f8a0c67c0f7539ee8563afd424..03f8d321af13e3ddb04c46ae9a66d16b82defe73 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <common.h>
 #include <clk.h>
+#include <dm/ofnode.h>
+#include <generic-phy.h>
 #include <reset.h>
 #include <asm/io.h>
 #include <dm.h>
  */
 struct generic_ehci {
        struct ehci_ctrl ctrl;
+       struct clk *clocks;
+       struct reset_ctl *resets;
+       struct phy phy;
+       int clock_count;
+       int reset_count;
 };
 
 static int ehci_usb_probe(struct udevice *dev)
 {
+       struct generic_ehci *priv = dev_get_priv(dev);
        struct ehci_hccr *hccr;
        struct ehci_hcor *hcor;
-       int i;
-
-       for (i = 0; ; i++) {
-               struct clk clk;
-               int ret;
-
-               ret = clk_get_by_index(dev, i, &clk);
-               if (ret < 0)
-                       break;
-               if (clk_enable(&clk))
-                       printf("failed to enable clock %d\n", i);
-               clk_free(&clk);
+       int i, err, ret, clock_nb, reset_nb;
+
+       err = 0;
+       priv->clock_count = 0;
+       clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
+                                                 "#clock-cells");
+       if (clock_nb > 0) {
+               priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
+                                           GFP_KERNEL);
+               if (!priv->clocks)
+                       return -ENOMEM;
+
+               for (i = 0; i < clock_nb; i++) {
+                       err = clk_get_by_index(dev, i, &priv->clocks[i]);
+
+                       if (err < 0)
+                               break;
+                       err = clk_enable(&priv->clocks[i]);
+                       if (err) {
+                               error("failed to enable clock %d\n", i);
+                               clk_free(&priv->clocks[i]);
+                               goto clk_err;
+                       }
+                       priv->clock_count++;
+               }
+       } else {
+               if (clock_nb != -ENOENT) {
+                       error("failed to get clock phandle(%d)\n", clock_nb);
+                       return clock_nb;
+               }
+       }
+
+       priv->reset_count = 0;
+       reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
+                                                 "#reset-cells");
+       if (reset_nb > 0) {
+               priv->resets = devm_kcalloc(dev, reset_nb,
+                                           sizeof(struct reset_ctl),
+                                           GFP_KERNEL);
+               if (!priv->resets)
+                       return -ENOMEM;
+
+               for (i = 0; i < reset_nb; i++) {
+                       err = reset_get_by_index(dev, i, &priv->resets[i]);
+                       if (err < 0)
+                               break;
+
+                       if (reset_deassert(&priv->resets[i])) {
+                               error("failed to deassert reset %d\n", i);
+                               reset_free(&priv->resets[i]);
+                               goto reset_err;
+                       }
+                       priv->reset_count++;
+               }
+       } else {
+               if (reset_nb != -ENOENT) {
+                       error("failed to get reset phandle(%d)\n", reset_nb);
+                       goto clk_err;
+               }
        }
 
-       for (i = 0; ; i++) {
-               struct reset_ctl reset;
-               int ret;
+       err = generic_phy_get_by_index(dev, 0, &priv->phy);
+       if (err) {
+               if (err != -ENOENT) {
+                       error("failed to get usb phy\n");
+                       goto reset_err;
+               }
+       } else {
 
-               ret = reset_get_by_index(dev, i, &reset);
-               if (ret < 0)
-                       break;
-               if (reset_deassert(&reset))
-                       printf("failed to deassert reset %d\n", i);
-               reset_free(&reset);
+               err = generic_phy_init(&priv->phy);
+               if (err) {
+                       error("failed to init usb phy\n");
+                       goto reset_err;
+               }
        }
 
        hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
        hcor = (struct ehci_hcor *)((uintptr_t)hccr +
                                    HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 
-       return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+       err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+       if (err)
+               goto phy_err;
+
+       return 0;
+
+phy_err:
+       if (generic_phy_valid(&priv->phy)) {
+               ret = generic_phy_exit(&priv->phy);
+               if (ret)
+                       error("failed to release phy\n");
+       }
+
+reset_err:
+       ret = reset_release_all(priv->resets, priv->reset_count);
+       if (ret)
+               error("failed to assert all resets\n");
+clk_err:
+       ret = clk_release_all(priv->clocks, priv->clock_count);
+       if (ret)
+               error("failed to disable all clocks\n");
+
+       return err;
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+       struct generic_ehci *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = ehci_deregister(dev);
+       if (ret)
+               return ret;
+
+       if (generic_phy_valid(&priv->phy)) {
+               ret = generic_phy_exit(&priv->phy);
+               if (ret)
+                       return ret;
+       }
+
+       ret =  reset_release_all(priv->resets, priv->reset_count);
+       if (ret)
+               return ret;
+
+       return clk_release_all(priv->clocks, priv->clock_count);
 }
 
 static const struct udevice_id ehci_usb_ids[] = {
@@ -67,7 +169,7 @@ U_BOOT_DRIVER(ehci_generic) = {
        .id     = UCLASS_USB,
        .of_match = ehci_usb_ids,
        .probe = ehci_usb_probe,
-       .remove = ehci_deregister,
+       .remove = ehci_usb_remove,
        .ops    = &ehci_usb_ops,
        .priv_auto_alloc_size = sizeof(struct generic_ehci),
        .flags  = DM_FLAG_ALLOC_PRIV_DMA,
index 13aa70d606614a61eb0db6fd04a4651786958671..3243c1d1cf250a9de353b8c05d46acd12b1efa6d 100644 (file)
@@ -52,8 +52,8 @@ static struct descriptor {
                0,              /* wHubCharacteristics */
                10,             /* bPwrOn2PwrGood */
                0,              /* bHubCntrCurrent */
-               {},             /* Device removable */
-               {}              /* at most 7 ports! XXX */
+               {               /* Device removable */
+                             /* at most 7 ports! XXX */
        },
        {
                0x12,           /* bLength */
@@ -148,9 +148,12 @@ static void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 
 static uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
 {
-       if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+       int max_ports = HCS_N_PORTS(ehci_readl(&ctrl->hccr->cr_hcsparams));
+
+       if (port < 0 || port >= max_ports) {
                /* Printing the message would cause a scan failure! */
-               debug("The request port(%u) is not configured\n", port);
+               debug("The request port(%u) exceeds maximum port number\n",
+                     port);
                return NULL;
        }
 
@@ -205,6 +208,7 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl)
 {
        int i, ret = 0;
        uint32_t cmd, reg;
+       int max_ports = HCS_N_PORTS(ehci_readl(&ctrl->hccr->cr_hcsparams));
 
        if (!ctrl || !ctrl->hcor)
                return -EINVAL;
@@ -219,7 +223,7 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl)
                100 * 1000);
 
        if (!ret) {
-               for (i = 0; i < CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS; i++) {
+               for (i = 0; i < max_ports; i++) {
                        reg = ehci_readl(&ctrl->hcor->or_portsc[i]);
                        reg |= EHCI_PS_SUSP;
                        ehci_writel(&ctrl->hcor->or_portsc[i], reg);
@@ -937,7 +941,7 @@ unknown:
        return -1;
 }
 
-const struct ehci_ops default_ehci_ops = {
+static const struct ehci_ops default_ehci_ops = {
        .set_usb_mode           = ehci_set_usbmode,
        .get_port_speed         = ehci_get_port_speed,
        .powerup_fixup          = ehci_powerup_fixup,
index 2ab830df5155a51c33828fe2a28e83eebba04ebc..7c39becd247e03caab60ba0a787f6024a4f28434 100644 (file)
@@ -11,9 +11,8 @@
 
 #include <usb.h>
 
-#if !defined(CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     2
-#endif
+/* Section 2.2.3 - N_PORTS */
+#define MAX_HC_PORTS           15
 
 /*
  * Register Space.
@@ -62,7 +61,7 @@ struct ehci_hcor {
        uint32_t _reserved_1_[6];
        uint32_t or_configflag;
 #define FLAG_CF                (1 << 0)        /* true:  we'll support "high speed" */
-       uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS];
+       uint32_t or_portsc[MAX_HC_PORTS];
 #define PORTSC_PSPD(x)         (((x) >> 26) & 0x3)
 #define PORTSC_PSPD_FS                 0x0
 #define PORTSC_PSPD_LS                 0x1
index f85738fb05f0525ba29840ce84af5066dcfa8573..e22ee9793914d27b7b146303881a18054eacd695 100644 (file)
@@ -5,7 +5,11 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
+#include <dm/ofnode.h>
+#include <generic-phy.h>
+#include <reset.h>
 #include "ohci.h"
 
 #if !defined(CONFIG_USB_OHCI_NEW)
 
 struct generic_ohci {
        ohci_t ohci;
+       struct clk *clocks;     /* clock list */
+       struct reset_ctl *resets; /* reset list */
+       struct phy phy;
+       int clock_count;        /* number of clock in clock list */
+       int reset_count;        /* number of reset in reset list */
 };
 
 static int ohci_usb_probe(struct udevice *dev)
 {
        struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
+       struct generic_ohci *priv = dev_get_priv(dev);
+       int i, err, ret, clock_nb, reset_nb;
 
-       return ohci_register(dev, regs);
+       err = 0;
+       priv->clock_count = 0;
+       clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
+       if (clock_nb > 0) {
+               priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
+                                           GFP_KERNEL);
+               if (!priv->clocks)
+                       return -ENOMEM;
+
+               for (i = 0; i < clock_nb; i++) {
+                       err = clk_get_by_index(dev, i, &priv->clocks[i]);
+                       if (err < 0)
+                               break;
+
+                       err = clk_enable(&priv->clocks[i]);
+                       if (err) {
+                               error("failed to enable clock %d\n", i);
+                               clk_free(&priv->clocks[i]);
+                               goto clk_err;
+                       }
+                       priv->clock_count++;
+               }
+       } else if (clock_nb != -ENOENT) {
+               error("failed to get clock phandle(%d)\n", clock_nb);
+               return clock_nb;
+       }
+
+       priv->reset_count = 0;
+       reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells");
+       if (reset_nb > 0) {
+               priv->resets = devm_kcalloc(dev, reset_nb,
+                                           sizeof(struct reset_ctl),
+                                           GFP_KERNEL);
+               if (!priv->resets)
+                       return -ENOMEM;
+
+               for (i = 0; i < reset_nb; i++) {
+                       err = reset_get_by_index(dev, i, &priv->resets[i]);
+                       if (err < 0)
+                               break;
+
+                       err = reset_deassert(&priv->resets[i]);
+                       if (err) {
+                               error("failed to deassert reset %d\n", i);
+                               reset_free(&priv->resets[i]);
+                               goto reset_err;
+                       }
+                       priv->reset_count++;
+               }
+       } else if (reset_nb != -ENOENT) {
+               error("failed to get reset phandle(%d)\n", reset_nb);
+               goto clk_err;
+       }
+
+       err = generic_phy_get_by_index(dev, 0, &priv->phy);
+       if (err) {
+               if (err != -ENOENT) {
+                       error("failed to get usb phy\n");
+                       goto reset_err;
+               }
+       } else {
+
+               err = generic_phy_init(&priv->phy);
+               if (err) {
+                       error("failed to init usb phy\n");
+                       goto reset_err;
+               }
+       }
+
+       err = ohci_register(dev, regs);
+       if (err)
+               goto phy_err;
+
+       return 0;
+
+phy_err:
+       if (generic_phy_valid(&priv->phy)) {
+               ret = generic_phy_exit(&priv->phy);
+               if (ret)
+                       error("failed to release phy\n");
+       }
+
+reset_err:
+       ret = reset_release_all(priv->resets, priv->reset_count);
+       if (ret)
+               error("failed to assert all resets\n");
+clk_err:
+       ret = clk_release_all(priv->clocks, priv->clock_count);
+       if (ret)
+               error("failed to disable all clocks\n");
+
+       return err;
 }
 
 static int ohci_usb_remove(struct udevice *dev)
 {
-       return ohci_deregister(dev);
+       struct generic_ohci *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = ohci_deregister(dev);
+       if (ret)
+               return ret;
+
+       if (generic_phy_valid(&priv->phy)) {
+               ret = generic_phy_exit(&priv->phy);
+               if (ret)
+                       return ret;
+       }
+
+       ret = reset_release_all(priv->resets, priv->reset_count);
+       if (ret)
+               return ret;
+
+       return clk_release_all(priv->clocks, priv->clock_count);
 }
 
 static const struct udevice_id ohci_usb_ids[] = {
index 110ddc92fa3ada91f181cedcc454077b8da527b2..0b8a501ce8851be7a0d0751c1f74fa7145ddf1d2 100644 (file)
@@ -139,6 +139,17 @@ int usb_reset_root_port(struct usb_device *udev)
        return ops->reset_root_port(bus, udev);
 }
 
+int usb_update_hub_device(struct usb_device *udev)
+{
+       struct udevice *bus = udev->controller_dev;
+       struct dm_usb_ops *ops = usb_get_ops(bus);
+
+       if (!ops->update_hub_device)
+               return -ENOSYS;
+
+       return ops->update_hub_device(bus, udev);
+}
+
 int usb_stop(void)
 {
        struct udevice *bus;
@@ -177,7 +188,6 @@ int usb_stop(void)
 #ifdef CONFIG_USB_STORAGE
        usb_stor_reset();
 #endif
-       usb_hub_reset();
        uc_priv->companion_device_count = 0;
        usb_started = 0;
 
@@ -230,7 +240,6 @@ int usb_init(void)
        int ret;
 
        asynch_allowed = 1;
-       usb_hub_reset();
 
        ret = uclass_get(UCLASS_USB, &uc);
        if (ret)
@@ -373,8 +382,8 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
 }
 
 /* returns 0 if no match, 1 if match */
-int usb_match_device(const struct usb_device_descriptor *desc,
-                    const struct usb_device_id *id)
+static int usb_match_device(const struct usb_device_descriptor *desc,
+                           const struct usb_device_id *id)
 {
        if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
            id->idVendor != le16_to_cpu(desc->idVendor))
@@ -410,9 +419,9 @@ int usb_match_device(const struct usb_device_descriptor *desc,
 }
 
 /* returns 0 if no match, 1 if match */
-int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
-                         const struct usb_interface_descriptor *int_desc,
-                         const struct usb_device_id *id)
+static int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
+                       const struct usb_interface_descriptor *int_desc,
+                       const struct usb_device_id *id)
 {
        /* The interface class, subclass, protocol and number should never be
         * checked for a match if the device class is Vendor Specific,
@@ -445,9 +454,9 @@ int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
 }
 
 /* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_device_descriptor *desc,
-                    struct usb_interface_descriptor *int_desc,
-                    const struct usb_device_id *id)
+static int usb_match_one_id(struct usb_device_descriptor *desc,
+                           struct usb_interface_descriptor *int_desc,
+                           const struct usb_device_id *id)
 {
        if (!usb_match_device(desc, id))
                return 0;
@@ -680,7 +689,7 @@ int usb_detect_change(void)
        return change;
 }
 
-int usb_child_post_bind(struct udevice *dev)
+static int usb_child_post_bind(struct udevice *dev)
 {
        struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
        int val;
index 33961cd63455ff7353481ffb9a798e67a29d34fb..4191a894218f64141108b837b45f4d4112b11165 100644 (file)
@@ -9,8 +9,21 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <generic-phy.h>
+#include <usb.h>
+
+#include "xhci.h"
 #include <asm/io.h>
 #include <linux/usb/dwc3.h>
+#include <linux/usb/otg.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct xhci_dwc3_platdata {
+       struct phy usb_phy;
+};
 
 void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
 {
@@ -19,7 +32,7 @@ void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
                        DWC3_GCTL_PRTCAPDIR(mode));
 }
 
-void dwc3_phy_reset(struct dwc3 *dwc3_reg)
+static void dwc3_phy_reset(struct dwc3 *dwc3_reg)
 {
        /* Assert USB3 PHY reset */
        setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
@@ -97,3 +110,79 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
        setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL |
                        GFLADJ_30MHZ(val));
 }
+
+#ifdef CONFIG_DM_USB
+static int xhci_dwc3_probe(struct udevice *dev)
+{
+       struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+       struct xhci_hcor *hcor;
+       struct xhci_hccr *hccr;
+       struct dwc3 *dwc3_reg;
+       enum usb_dr_mode dr_mode;
+       int ret;
+
+       hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
+       hcor = (struct xhci_hcor *)((uintptr_t)hccr +
+                       HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
+
+       ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
+       if (ret) {
+               if (ret != -ENOENT) {
+                       error("Failed to get USB PHY for %s\n", dev->name);
+                       return ret;
+               }
+       } else {
+               ret = generic_phy_init(&plat->usb_phy);
+               if (ret) {
+                       error("Can't init USB PHY for %s\n", dev->name);
+                       return ret;
+               }
+       }
+
+       dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
+
+       dwc3_core_init(dwc3_reg);
+
+       dr_mode = usb_get_dr_mode(dev_of_offset(dev));
+       if (dr_mode == USB_DR_MODE_UNKNOWN)
+               /* by default set dual role mode to HOST */
+               dr_mode = USB_DR_MODE_HOST;
+
+       dwc3_set_mode(dwc3_reg, dr_mode);
+
+       return xhci_register(dev, hccr, hcor);
+}
+
+static int xhci_dwc3_remove(struct udevice *dev)
+{
+       struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+       int ret;
+
+       if (generic_phy_valid(&plat->usb_phy)) {
+               ret = generic_phy_exit(&plat->usb_phy);
+               if (ret) {
+                       error("Can't deinit USB PHY for %s\n", dev->name);
+                       return ret;
+               }
+       }
+
+       return xhci_deregister(dev);
+}
+
+static const struct udevice_id xhci_dwc3_ids[] = {
+       { .compatible = "snps,dwc3" },
+       { }
+};
+
+U_BOOT_DRIVER(xhci_dwc3) = {
+       .name = "xhci-dwc3",
+       .id = UCLASS_USB,
+       .of_match = xhci_dwc3_ids,
+       .probe = xhci_dwc3_probe,
+       .remove = xhci_dwc3_remove,
+       .ops = &xhci_usb_ops,
+       .priv_auto_alloc_size = sizeof(struct xhci_ctrl),
+       .platdata_auto_alloc_size = sizeof(struct xhci_dwc3_platdata),
+       .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
index 62db51d01851c1eb1909a79de4271cf0e0ff7497..d5eab3a61545442ae31066e85b4584946bbdf54d 100644 (file)
@@ -95,6 +95,25 @@ static void xhci_ring_free(struct xhci_ring *ring)
        free(ring);
 }
 
+/**
+ * Free the scratchpad buffer array and scratchpad buffers
+ *
+ * @ctrl       host controller data structure
+ * @return     none
+ */
+static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
+{
+       if (!ctrl->scratchpad)
+               return;
+
+       ctrl->dcbaa->dev_context_ptrs[0] = 0;
+
+       free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]);
+       free(ctrl->scratchpad->sp_array);
+       free(ctrl->scratchpad);
+       ctrl->scratchpad = NULL;
+}
+
 /**
  * frees the "xhci_container_ctx" pointer passed
  *
@@ -155,6 +174,7 @@ void xhci_cleanup(struct xhci_ctrl *ctrl)
 {
        xhci_ring_free(ctrl->event_ring);
        xhci_ring_free(ctrl->cmd_ring);
+       xhci_scratchpad_free(ctrl);
        xhci_free_virt_devices(ctrl);
        free(ctrl->erst.entries);
        free(ctrl->dcbaa);
@@ -319,6 +339,70 @@ struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs)
        return ring;
 }
 
+/**
+ * Set up the scratchpad buffer array and scratchpad buffers
+ *
+ * @ctrl       host controller data structure
+ * @return     -ENOMEM if buffer allocation fails, 0 on success
+ */
+static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
+{
+       struct xhci_hccr *hccr = ctrl->hccr;
+       struct xhci_hcor *hcor = ctrl->hcor;
+       struct xhci_scratchpad *scratchpad;
+       int num_sp;
+       uint32_t page_size;
+       void *buf;
+       int i;
+
+       num_sp = HCS_MAX_SCRATCHPAD(xhci_readl(&hccr->cr_hcsparams2));
+       if (!num_sp)
+               return 0;
+
+       scratchpad = malloc(sizeof(*scratchpad));
+       if (!scratchpad)
+               goto fail_sp;
+       ctrl->scratchpad = scratchpad;
+
+       scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64));
+       if (!scratchpad->sp_array)
+               goto fail_sp2;
+       ctrl->dcbaa->dev_context_ptrs[0] =
+               cpu_to_le64((uintptr_t)scratchpad->sp_array);
+
+       page_size = xhci_readl(&hcor->or_pagesize) & 0xffff;
+       for (i = 0; i < 16; i++) {
+               if ((0x1 & page_size) != 0)
+                       break;
+               page_size = page_size >> 1;
+       }
+       BUG_ON(i == 16);
+
+       page_size = 1 << (i + 12);
+       buf = memalign(page_size, num_sp * page_size);
+       if (!buf)
+               goto fail_sp3;
+       memset(buf, '\0', num_sp * page_size);
+       xhci_flush_cache((uintptr_t)buf, num_sp * page_size);
+
+       for (i = 0; i < num_sp; i++) {
+               uintptr_t ptr = (uintptr_t)buf + i * page_size;
+               scratchpad->sp_array[i] = cpu_to_le64(ptr);
+       }
+
+       return 0;
+
+fail_sp3:
+       free(scratchpad->sp_array);
+
+fail_sp2:
+       free(scratchpad);
+       ctrl->scratchpad = NULL;
+
+fail_sp:
+       return -ENOMEM;
+}
+
 /**
  * Allocates the Container context
  *
@@ -499,6 +583,9 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
 
        xhci_writeq(&ctrl->ir_set->erst_base, val_64);
 
+       /* set up the scratchpad buffer array and scratchpad buffers */
+       xhci_scratchpad_alloc(ctrl);
+
        /* initializing the virtual devices to NULL */
        for (i = 0; i < MAX_HC_SLOTS; ++i)
                ctrl->devs[i] = NULL;
@@ -626,14 +713,21 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx,
  * @param udev pointer to the Device Data Structure
  * @return returns negative value on failure else 0 on success
  */
-void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
-                                    int speed, int hop_portnr)
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
+                                    struct usb_device *udev, int hop_portnr)
 {
        struct xhci_virt_device *virt_dev;
        struct xhci_ep_ctx *ep0_ctx;
        struct xhci_slot_ctx *slot_ctx;
        u32 port_num = 0;
        u64 trb_64 = 0;
+       int slot_id = udev->slot_id;
+       int speed = udev->speed;
+       int route = 0;
+#ifdef CONFIG_DM_USB
+       struct usb_device *dev = udev;
+       struct usb_hub_device *hub;
+#endif
 
        virt_dev = ctrl->devs[slot_id];
 
@@ -644,7 +738,32 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
        slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->in_ctx);
 
        /* Only the control endpoint is valid - one endpoint context */
-       slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0);
+       slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));
+
+#ifdef CONFIG_DM_USB
+       /* Calculate the route string for this device */
+       port_num = dev->portnr;
+       while (!usb_hub_is_root_hub(dev->dev)) {
+               hub = dev_get_uclass_priv(dev->dev);
+               /*
+                * Each hub in the topology is expected to have no more than
+                * 15 ports in order for the route string of a device to be
+                * unique. SuperSpeed hubs are restricted to only having 15
+                * ports, but FS/LS/HS hubs are not. The xHCI specification
+                * says that if the port number the device is greater than 15,
+                * that portion of the route string shall be set to 15.
+                */
+               if (port_num > 15)
+                       port_num = 15;
+               route |= port_num << (hub->hub_depth * 4);
+               dev = dev_get_parent_priv(dev->dev);
+               port_num = dev->portnr;
+               dev = dev_get_parent_priv(dev->dev->parent);
+       }
+
+       debug("route string %x\n", route);
+#endif
+       slot_ctx->dev_info |= route;
 
        switch (speed) {
        case USB_SPEED_SUPER:
@@ -664,6 +783,20 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
                BUG();
        }
 
+#ifdef CONFIG_DM_USB
+       /* Set up TT fields to support FS/LS devices */
+       if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) {
+               dev = dev_get_parent_priv(udev->dev);
+               if (dev->speed == USB_SPEED_HIGH) {
+                       hub = dev_get_uclass_priv(udev->dev);
+                       if (hub->tt.multi)
+                               slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+                       slot_ctx->tt_info |= cpu_to_le32(TT_PORT(udev->portnr));
+                       slot_ctx->tt_info |= cpu_to_le32(TT_SLOT(dev->slot_id));
+               }
+       }
+#endif
+
        port_num = hop_portnr;
        debug("port_num = %d\n", port_num);
 
index 63daaa6759918f316a8679a307bd7268724c9e07..e4a0ef4a1a5963a9281abd836070b909d3b4abec 100644 (file)
@@ -8,66 +8,10 @@
 
 #include <common.h>
 #include <dm.h>
-#include <errno.h>
 #include <pci.h>
 #include <usb.h>
-
 #include "xhci.h"
 
-#ifndef CONFIG_DM_USB
-
-/*
- * Create the appropriate control structures to manage a new XHCI host
- * controller.
- */
-int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr,
-                 struct xhci_hcor **ret_hcor)
-{
-       struct xhci_hccr *hccr;
-       struct xhci_hcor *hcor;
-       pci_dev_t pdev;
-       uint32_t cmd;
-       int len;
-
-       pdev = pci_find_class(PCI_CLASS_SERIAL_USB_XHCI, index);
-       if (pdev < 0) {
-               printf("XHCI host controller not found\n");
-               return -1;
-       }
-
-       hccr = (struct xhci_hccr *)pci_map_bar(pdev,
-                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-       len = HC_LENGTH(xhci_readl(&hccr->cr_capbase));
-       hcor = (struct xhci_hcor *)((uint32_t)hccr + len);
-
-       debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
-             (uint32_t)hccr, (uint32_t)hcor, len);
-
-       *ret_hccr = hccr;
-       *ret_hcor = hcor;
-
-       /* enable busmaster */
-       pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER;
-       pci_write_config_dword(pdev, PCI_COMMAND, cmd);
-
-       return 0;
-}
-
-/*
- * Destroy the appropriate control structures corresponding * to the XHCI host
- * controller
- */
-void xhci_hcd_stop(int index)
-{
-}
-
-#else
-
-struct xhci_pci_priv {
-       struct xhci_ctrl ctrl;  /* Needs to come first in this struct! */
-};
-
 static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
                          struct xhci_hcor **ret_hcor)
 {
@@ -103,17 +47,6 @@ static int xhci_pci_probe(struct udevice *dev)
        return xhci_register(dev, hccr, hcor);
 }
 
-static int xhci_pci_remove(struct udevice *dev)
-{
-       int ret;
-
-       ret = xhci_deregister(dev);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
 static const struct udevice_id xhci_pci_ids[] = {
        { .compatible = "xhci-pci" },
        { }
@@ -123,11 +56,11 @@ U_BOOT_DRIVER(xhci_pci) = {
        .name   = "xhci_pci",
        .id     = UCLASS_USB,
        .probe = xhci_pci_probe,
-       .remove = xhci_pci_remove,
+       .remove = xhci_deregister,
        .of_match = xhci_pci_ids,
        .ops    = &xhci_usb_ops,
        .platdata_auto_alloc_size = sizeof(struct usb_platdata),
-       .priv_auto_alloc_size = sizeof(struct xhci_pci_priv),
+       .priv_auto_alloc_size = sizeof(struct xhci_ctrl),
        .flags  = DM_FLAG_ALLOC_PRIV_DMA,
 };
 
@@ -137,5 +70,3 @@ static struct pci_device_id xhci_pci_supported[] = {
 };
 
 U_BOOT_PCI_DEVICE(xhci_pci, xhci_pci_supported);
-
-#endif /* CONFIG_DM_USB */
index 2675a8f6491538050a62040255fd6cfe267962fe..579e6707eb35a11067458da2f8cf643048b18df8 100644 (file)
@@ -280,8 +280,15 @@ void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id,
        fields[0] = lower_32_bits(val_64);
        fields[1] = upper_32_bits(val_64);
        fields[2] = 0;
-       fields[3] = TRB_TYPE(cmd) | EP_ID_FOR_TRB(ep_index) |
-                   SLOT_ID_FOR_TRB(slot_id) | ctrl->cmd_ring->cycle_state;
+       fields[3] = TRB_TYPE(cmd) | SLOT_ID_FOR_TRB(slot_id) |
+                   ctrl->cmd_ring->cycle_state;
+
+       /*
+        * Only 'reset endpoint', 'stop endpoint' and 'set TR dequeue pointer'
+        * commands need endpoint id encoded.
+        */
+       if (cmd >= TRB_RESET_EP && cmd <= TRB_SET_DEQ)
+               fields[3] |= EP_ID_FOR_TRB(ep_index);
 
        queue_trb(ctrl, ctrl->cmd_ring, false, fields);
 
index 32011774768fb6ed73550c931c297ee63c5da0f3..9b82ee5c602782a10876fbdd3995e5bd71be1495 100644 (file)
@@ -50,8 +50,8 @@ static struct descriptor {
                cpu_to_le16(0x8), /* wHubCharacteristics */
                10,             /* bPwrOn2PwrGood */
                0,              /* bHubCntrCurrent */
-               {},             /* Device removable */
-               {}              /* at most 7 ports! XXX */
+               {               /* Device removable */
+                             /* at most 7 ports! XXX */
        },
        {
                0x12,           /* bLength */
@@ -192,7 +192,7 @@ static int xhci_start(struct xhci_hcor *hcor)
  * @param hcor pointer to host controller operation registers
  * @return -EBUSY if XHCI Controller is not halted else status of handshake
  */
-int xhci_reset(struct xhci_hcor *hcor)
+static int xhci_reset(struct xhci_hcor *hcor)
 {
        u32 cmd;
        u32 state;
@@ -332,8 +332,8 @@ static int xhci_set_configuration(struct usb_device *udev)
        ifdesc = &udev->config.if_desc[0];
 
        ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
-       /* Zero the input context control */
-       ctrl_ctx->add_flags = 0;
+       /* Initialize the input context control */
+       ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
        ctrl_ctx->drop_flags = 0;
 
        /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
@@ -415,8 +415,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr)
         * so setting up the slot context.
         */
        debug("Setting up addressable devices %p\n", ctrl->dcbaa);
-       xhci_setup_addressable_virt_dev(ctrl, udev->slot_id, udev->speed,
-                                       root_portnr);
+       xhci_setup_addressable_virt_dev(ctrl, udev, root_portnr);
 
        ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
        ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
@@ -481,7 +480,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr)
  * @param udev pointer to the Device Data Structure
  * @return Returns 0 on succes else return error code on failure
  */
-int _xhci_alloc_device(struct usb_device *udev)
+static int _xhci_alloc_device(struct usb_device *udev)
 {
        struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
        union xhci_trb *event;
@@ -668,12 +667,14 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
        uint32_t reg;
        volatile uint32_t *status_reg;
        struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
+       struct xhci_hccr *hccr = ctrl->hccr;
        struct xhci_hcor *hcor = ctrl->hcor;
+       int max_ports = HCS_MAX_PORTS(xhci_readl(&hccr->cr_hcsparams1));
 
        if ((req->requesttype & USB_RT_PORT) &&
-           le16_to_cpu(req->index) > CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS) {
-               printf("The request port(%d) is not configured\n",
-                       le16_to_cpu(req->index) - 1);
+           le16_to_cpu(req->index) > max_ports) {
+               printf("The request port(%d) exceeds maximum port number\n",
+                      le16_to_cpu(req->index) - 1);
                return -EINVAL;
        }
 
@@ -727,6 +728,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
        case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
                switch (le16_to_cpu(req->value) >> 8) {
                case USB_DT_HUB:
+               case USB_DT_SS_HUB:
                        debug("USB_DT_HUB config\n");
                        srcptr = &descriptor.hub;
                        srclen = 0x8;
@@ -1113,26 +1115,6 @@ int usb_lowlevel_stop(int index)
 #endif /* CONFIG_DM_USB */
 
 #ifdef CONFIG_DM_USB
-/*
-static struct usb_device *get_usb_device(struct udevice *dev)
-{
-       struct usb_device *udev;
-
-       if (device_get_uclass_id(dev) == UCLASS_USB)
-               udev = dev_get_uclass_priv(dev);
-       else
-               udev = dev_get_parent_priv(dev);
-
-       return udev;
-}
-*/
-static bool is_root_hub(struct udevice *dev)
-{
-       if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB)
-               return true;
-
-       return false;
-}
 
 static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
                                   unsigned long pipe, void *buffer, int length,
@@ -1147,10 +1129,10 @@ static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
        hub = udev->dev;
        if (device_get_uclass_id(hub) == UCLASS_USB_HUB) {
                /* Figure out our port number on the root hub */
-               if (is_root_hub(hub)) {
+               if (usb_hub_is_root_hub(hub)) {
                        root_portnr = udev->portnr;
                } else {
-                       while (!is_root_hub(hub->parent))
+                       while (!usb_hub_is_root_hub(hub->parent))
                                hub = hub->parent;
                        uhop = dev_get_parent_priv(hub);
                        root_portnr = uhop->portnr;
@@ -1188,6 +1170,64 @@ static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev)
        return _xhci_alloc_device(udev);
 }
 
+static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
+{
+       struct xhci_ctrl *ctrl = dev_get_priv(dev);
+       struct usb_hub_device *hub = dev_get_uclass_priv(udev->dev);
+       struct xhci_virt_device *virt_dev;
+       struct xhci_input_control_ctx *ctrl_ctx;
+       struct xhci_container_ctx *out_ctx;
+       struct xhci_container_ctx *in_ctx;
+       struct xhci_slot_ctx *slot_ctx;
+       int slot_id = udev->slot_id;
+       unsigned think_time;
+
+       debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+
+       /* Ignore root hubs */
+       if (usb_hub_is_root_hub(udev->dev))
+               return 0;
+
+       virt_dev = ctrl->devs[slot_id];
+       BUG_ON(!virt_dev);
+
+       out_ctx = virt_dev->out_ctx;
+       in_ctx = virt_dev->in_ctx;
+
+       ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
+       /* Initialize the input context control */
+       ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
+       ctrl_ctx->drop_flags = 0;
+
+       xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
+
+       /* slot context */
+       xhci_slot_copy(ctrl, in_ctx, out_ctx);
+       slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
+
+       /* Update hub related fields */
+       slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
+       if (hub->tt.multi && udev->speed == USB_SPEED_HIGH)
+               slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+       slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild));
+       /*
+        * Set TT think time - convert from ns to FS bit times.
+        * Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns
+        *
+        * 0 =  8 FS bit times, 1 = 16 FS bit times,
+        * 2 = 24 FS bit times, 3 = 32 FS bit times.
+        *
+        * This field shall be 0 if the device is not a high-spped hub.
+        */
+       think_time = hub->tt.think_time;
+       if (think_time != 0)
+               think_time = (think_time / 666) - 1;
+       if (udev->speed == USB_SPEED_HIGH)
+               slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time));
+
+       return xhci_configure_endpoints(udev, false);
+}
+
 int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
                  struct xhci_hcor *hcor)
 {
@@ -1240,6 +1280,7 @@ struct dm_usb_ops xhci_usb_ops = {
        .bulk = xhci_submit_bulk_msg,
        .interrupt = xhci_submit_int_msg,
        .alloc_device = xhci_alloc_device,
+       .update_hub_device = xhci_update_hub_device,
 };
 
 #endif
index 2afa38694be8f12325d9f1537ad6bd9f04bbd122..a497d9d830fa7be54b05ac79c5def17e1c3a9d04 100644 (file)
@@ -30,7 +30,7 @@
 /* Max number of USB devices for any host controller - limit in section 6.1 */
 #define MAX_HC_SLOTS            256
 /* Section 5.3.3 - MaxPorts */
-#define MAX_HC_PORTS            127
+#define MAX_HC_PORTS            255
 
 /* Up to 16 ms to halt an HC */
 #define XHCI_MAX_HALT_USEC     (16*1000)
@@ -102,8 +102,8 @@ struct xhci_hccr {
 #define HCS_MAX_INTRS(p)       (((p) >> 8) & 0x7ff)
 /* bits 24:31, Max Ports - max value is 0x7F = 127 ports */
 #define HCS_MAX_PORTS_SHIFT    24
-#define HCS_MAX_PORTS_MASK     (0x7f << HCS_MAX_PORTS_SHIFT)
-#define HCS_MAX_PORTS(p)       (((p) >> 24) & 0x7f)
+#define HCS_MAX_PORTS_MASK     (0xff << HCS_MAX_PORTS_SHIFT)
+#define HCS_MAX_PORTS(p)       (((p) >> 24) & 0xff)
 
 /* HCSPARAMS2 - hcs_params2 - bitmasks */
 /* bits 0:3, frames or uframes that SW needs to queue transactions
@@ -111,9 +111,10 @@ struct xhci_hccr {
 #define HCS_IST(p)             (((p) >> 0) & 0xf)
 /* bits 4:7, max number of Event Ring segments */
 #define HCS_ERST_MAX(p)                (((p) >> 4) & 0xf)
+/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */
 /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
-/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
-#define HCS_MAX_SCRATCHPAD(p)   (((p) >> 27) & 0x1f)
+/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */
+#define HCS_MAX_SCRATCHPAD(p)  ((((p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f))
 
 /* HCSPARAMS3 - hcs_params3 - bitmasks */
 /* bits 0:7, Max U1 to U0 latency for the roothub ports */
@@ -171,9 +172,7 @@ struct xhci_hcor {
        volatile uint64_t or_dcbaap;
        volatile uint32_t or_config;
        volatile uint32_t reserved_2[241];
-       struct xhci_hcor_port_regs portregs[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS];
-
-       uint32_t reserved_4[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS * 254];
+       struct xhci_hcor_port_regs portregs[MAX_HC_PORTS];
 };
 
 /* USBCMD - USB command - command bitmasks */
@@ -482,10 +481,9 @@ struct xhci_protocol_caps {
  * @type: Type of context.  Used to calculated offsets to contained contexts.
  * @size: Size of the context data
  * @bytes: The raw context data given to HW
- * @dma: dma address of the bytes
  *
  * Represents either a Device or Input context.  Holds a pointer to the raw
- * memory used for the context (bytes) and dma address of it (dma).
+ * memory used for the context (bytes).
  */
 struct xhci_container_ctx {
        unsigned type;
@@ -550,12 +548,12 @@ struct xhci_slot_ctx {
  * The Slot ID of the hub that isolates the high speed signaling from
  * this low or full-speed device.  '0' if attached to root hub port.
  */
-#define TT_SLOT                        (0xff)
+#define TT_SLOT(p)             (((p) & 0xff) << 0)
 /*
  * The number of the downstream facing port of the high-speed hub
  * '0' if the device is not low or full speed.
  */
-#define TT_PORT                        (0xff << 8)
+#define TT_PORT(p)             (((p) & 0xff) << 8)
 #define TT_THINK_TIME(p)       (((p) & 0x3) << 16)
 
 /* dev_state bitmasks */
@@ -1038,6 +1036,10 @@ struct xhci_erst {
        unsigned int            erst_size;
 };
 
+struct xhci_scratchpad {
+       u64 *sp_array;
+};
+
 /*
  * Each segment table entry is 4*32bits long.  1K seems like an ok size:
  * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
@@ -1225,6 +1227,7 @@ struct xhci_ctrl {
        struct xhci_intr_reg *ir_set;
        struct xhci_erst erst;
        struct xhci_erst_entry entry[ERST_NUM_SEGS];
+       struct xhci_scratchpad *scratchpad;
        struct xhci_virt_device *devs[MAX_HC_SLOTS];
        int rootdev;
 };
@@ -1244,8 +1247,8 @@ void xhci_endpoint_copy(struct xhci_ctrl *ctrl,
 void xhci_slot_copy(struct xhci_ctrl *ctrl,
                    struct xhci_container_ctx *in_ctx,
                    struct xhci_container_ctx *out_ctx);
-void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
-                                    int speed, int hop_portnr);
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
+                                    struct usb_device *udev, int hop_portnr);
 void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr,
                        u32 slot_id, u32 ep_index, trb_type cmd);
 void xhci_acknowledge_event(struct xhci_ctrl *ctrl);
index 5a5c2ff1e674875dfd6ba999addf73baae231d3a..c5988f78a8f1a1c7fc3f6b777eb00848db490757 100644 (file)
@@ -98,6 +98,21 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
  * @return 0 if OK, or a negative error code.
  */
 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
+
+/**
+ * clk_release_all() - Disable (turn off)/Free an array of previously
+ * requested clocks.
+ *
+ * For each clock contained in the clock array, this function will check if
+ * clock has been previously requested and then will disable and free it.
+ *
+ * @clk:       A clock struct array that was previously successfully
+ *             requested by clk_request/get_by_*().
+ * @count      Number of clock contained in the array
+ * @return zero on success, or -ve error code.
+ */
+int clk_release_all(struct clk *clk, int count);
+
 #else
 static inline int clk_get_by_index(struct udevice *dev, int index,
                                   struct clk *clk)
@@ -110,6 +125,12 @@ static inline int clk_get_by_name(struct udevice *dev, const char *name,
 {
        return -ENOSYS;
 }
+
+static inline int clk_release_all(struct clk *clk, int count)
+{
+       return -ENOSYS;
+}
+
 #endif
 
 /**
index 0a2bcb2383292e6f87a009ca0bbc3895a4c17543..32c593291a5d487720c68570e526dbb106f6889f 100644 (file)
 #define CONFIG_USB_EHCI_PCI
 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET
 #define CONFIG_PCI_EHCI_DEVICE                 0
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     2
 #endif
 
 #undef CONFIG_WATCHDOG                 /* watchdog disabled */
index a91b7df3477e683a938f728d389f3908455965a2..70e7473ee8df802acbfc1cd79ccca70d48192acf 100644 (file)
@@ -82,7 +82,6 @@
 #if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
 #define CONFIG_SYS_USB_FAT_BOOT_PARTITION              1
 #define CONFIG_USB_XHCI_OMAP
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
 
 #define CONFIG_OMAP_USB_PHY
 #define CONFIG_AM437X_USB2PHY2_HOST
index 9216998486fe571e64ac7ee837f3ba7610259554..9976686bd812f61d949177cbfb60264cfe80fc2f 100644 (file)
@@ -92,7 +92,6 @@
 
 /* USB xHCI HOST */
 #define CONFIG_USB_XHCI_OMAP
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
 
 #define CONFIG_OMAP_USB_PHY
 #define CONFIG_OMAP_USB3PHY1_HOST
index c1cf4132fe37eeb2f82c919d801f3cf0dddaa15f..120ac02e0662776430868eea31f5a3f5594e4662 100644 (file)
@@ -83,7 +83,6 @@
 
 /* USB xHCI HOST */
 #define CONFIG_USB_XHCI_OMAP
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
 
 #define CONFIG_OMAP_USB_PHY
 #define CONFIG_OMAP_USB3PHY1_HOST
index f6e0743b536e0024e005e81344b940e3a14709f5..7a61107294ffe68eccdd2bd72030a920d8c1868a 100644 (file)
@@ -60,7 +60,6 @@
 
 /* USB support */
 #define CONFIG_USB_XHCI_OMAP
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
 #define CONFIG_OMAP_USB_PHY
 #define CONFIG_AM437X_USB2PHY2_HOST
 
index 69706d254e6f71bf3cf34ade5c717455e7a58b3c..8a4c333564abae190be9adb13514721d49da9303 100644 (file)
@@ -56,7 +56,6 @@
 #define CONFIG_SYS_SCSI_MAX_DEVICE     (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
                                                CONFIG_SYS_SCSI_MAX_LUN)
 /* USB UHH support options */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET
 
 #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO       76 /* HSIC2 HUB #RESET */
index ed1a2287abaaa51900f504e566463a2bdbd3d886..015072720edea6e4299d2c4035caf90d0cce51bf 100644 (file)
@@ -94,9 +94,6 @@
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_AT91_WANTS_COMMON_PHY
 
-/* USB */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     2
-
 #define CONFIG_MTD_DEVICE
 #define CONFIG_MTD_PARTITIONS
 
index 8566bdc569d3920141e18eb22e4d25805015e814..b5091513f7f575e8c99fa66090cd7cc52d51bf35 100644 (file)
 
 /* USB xHCI HOST */
 #define CONFIG_USB_XHCI_OMAP
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
 
 #define CONFIG_OMAP_USB_PHY
 #define CONFIG_OMAP_USB2PHY2_HOST
index a209e6f09cc0d1d447ae7f0789b4c7b0a7c26e8f..c1e9346290570f74720d549cff0948b228dd62be 100644 (file)
@@ -68,7 +68,6 @@
 #if 0
 #undef CONFIG_DM_USB
 #define CONFIG_USB_XHCI_PCI
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
 #endif
 
 #if !defined(CONFIG_USB_XHCI_HCD)
index 8efcc94945e66396ca4a107ac47fea7a39b2d27b..c4496a7f48dffa28da9066b1237801cfaaabe24a 100644 (file)
@@ -25,8 +25,6 @@
 #define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
 
 /* USB UHH support options */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
-
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 1
 #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 62
 
index 378219d83a3b8ee21db0a2ede30fdf2a6baddc90..3b73bbc5255429a87239bd5cd3ec3709130ea8f8 100644 (file)
 /* Enable Time Command */
 
 /* USB */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
-
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_ASIX
 #define CONFIG_USB_ETHER_SMSC95XX
index f6f88e84c73043f1e33bfb88af840a141a0a84e7..6b1ba578e9225da18a40077e8b386e30b2de0cc8 100644 (file)
@@ -39,7 +39,6 @@
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         1
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 #endif
 
 #define CONFIG_CMD_MEMINFO
index 9e6c7a797cb9167b6be98fea799d1d58898a8948..bebb0dfce8161d8056bffd57178689b45551cb5f 100644 (file)
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         1
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 #endif
 
 /*  MMC  */
index 0705bc5f684d8399836af63dd7eb20641debc053..32c8cec07231b0300673e357193c681cd9a00dd3 100644 (file)
@@ -27,7 +27,6 @@
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         1
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 #endif
 
 /*
index 1f2eb52c243c22799004033355ee07a4d9f102c1..58f893f4fdd575ca82044e34cd35c8b06a72e5cb 100644 (file)
@@ -26,7 +26,6 @@
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_XHCI_DWC3
 #define CONFIG_USB_MAX_CONTROLLER_COUNT                1
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #endif
 
 #if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_XHCI_USB)
index 251a66e5955f5cfa05ca5e08254c63a7ca0ac53f..83e7e7a50e7f088a2d388c932f03f81c4e2644c5 100644 (file)
@@ -413,7 +413,6 @@ unsigned long get_board_ddr_clk(void);
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT                1
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #endif
 
 /*
index b9e5cdbb1ec180671e0d397bc4821294b5205be9..0aa6fdd09ab499095823b3812382c350b0cd5676 100644 (file)
@@ -50,7 +50,6 @@
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT        1
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #endif
 
 #define CONFIG_SYS_CLK_FREQ            100000000
index 415a7055087d124a77bd4704fd46d80a99d92f59..0897da1998d2192c10a693d03dfddae1ece0bce9 100644 (file)
@@ -377,7 +377,6 @@ unsigned long get_board_ddr_clk(void);
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT                3
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #endif
 
 /*
index 59e7760b100745bb69949ab7755cdd25b4238bb5..617a7123983fea9530eab22f4fd2a793796580cd 100644 (file)
 #ifdef CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT                3
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #endif
 #endif
 
index ea99676b7a2b0fc98239069a9d73ce6a70bf34b5..bb3d9416a8a9199094d7202e8d3d857cf8b88aa7 100644 (file)
@@ -144,7 +144,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_XHCI_DWC3
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         3
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 #define CONFIG_CMD_USB
 #define CONFIG_USB_STORAGE
 #endif
index 20a5e7f65938f33288e7ff4c1873bacc3879a5ce..8c72291f62fe61a3445fbfe745602b849f41719a 100644 (file)
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_XHCI_DWC3
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         3
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 #define CONFIG_CMD_USB
 #define CONFIG_USB_STORAGE
 #endif
index 929ae3286af96afa3b8da6b97204742a56884913..66936c4a9e96f3f71c62c94b1575ac37c5a5e403 100644 (file)
@@ -446,7 +446,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT                2
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 
 #include <asm/fsl_secure_boot.h>
 
index 0be4c4fa0b1392b856d81f9c0227284be8d904c6..744a78997b939a589595b35c4096082995469e6d 100644 (file)
@@ -346,7 +346,6 @@ unsigned long get_board_sys_clk(void);
 #define CONFIG_HAS_FSL_XHCI_USB
 #define CONFIG_USB_XHCI_FSL
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         2
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 
 #undef CONFIG_CMDLINE_EDITING
 #include <config_distro_defaults.h>
index 2744efb922d34620ea90e68688f4b46a25be612c..7c28a94d92d6f77b1cc70d3b8a0af7dab24dd72e 100644 (file)
@@ -96,7 +96,6 @@
  * USB
  */
 #ifdef CONFIG_CMD_USB
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
 
 /* USB device */
 #define CONFIG_USB_ETHER
index 73fdfbd09fb43473cfbc6509c39ecf4e6d1d4f5e..3f5fdab9a979b50b02ccb4cc16a7a25849c5ba46 100644 (file)
@@ -74,7 +74,6 @@
 
 /* EHCI */
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       57
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 #define        CONFIG_USB_HOST_ETHER
 #define        CONFIG_USB_ETHER_ASIX
 #define CONFIG_USB_ETHER_MCS7830
index ae9548599305523b97d296585cd7cd6587f8f260..6ea607df6702fb1733e9c12f9b40f84064914fa5 100644 (file)
@@ -20,7 +20,8 @@
 
 #define CONFIG_STD_DEVICES_SETTINGS    "stdin=usbkbd,serial\0" \
                                        "stdout=vidconsole,serial\0" \
-                                       "stderr=vidconsole,serial\0"
+                                       "stderr=vidconsole,serial\0" \
+                                       "usb_pgood_delay=40\0"
 
 #define CONFIG_SCSI_DEV_LIST           \
        {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \
index 778cc9e3783d18561bb73f56e5281a064ce5b5fe..1307d215ed878e4856ddd412b8887c0974165d73 100644 (file)
 #define CONFIG_NET_RETRY_COUNT 50
 #define CONFIG_PHY_MARVELL
 
-/* USB 2.0 */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
-
-/* USB 3.0 */
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 3
-
-#define CONFIG_USB_MAX_CONTROLLER_COUNT (CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS + \
-                                        CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS)
+#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3)
 
 /* USB ethernet */
 #define CONFIG_USB_HOST_ETHER
index 53db10f9bc1f14508cbe8627984c9cd5788af7db..86ae19c9fbe10ff56f1f3897eb713b139fd047a3 100644 (file)
 #define CONFIG_ARP_TIMEOUT     200
 #define CONFIG_NET_RETRY_COUNT 50
 
-/* USB 2.0 */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
-
-/* USB 3.0 */
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 3
-
-#define CONFIG_USB_MAX_CONTROLLER_COUNT (CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS + \
-                                        CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS)
+#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3)
 
 /* USB ethernet */
 #define CONFIG_USB_HOST_ETHER
index 9ae3d181375d83b847fcc4cc8a1967cd45355dfa..8338d6df79f3bf7fbe869d6137347e6df8bfe75b 100644 (file)
 #define CONFIG_SYS_NAND_LARGEPAGE
 
 /* EHCI driver */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     1
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET
 #define CONFIG_USB_EHCI_MXC
index 9552c967c84d46d332440361c9ccaf30b07c9bff..563854d9bbbfba0f80c5bc7d841bff19f7ce64c5 100644 (file)
 /* USB */
 #define CONFIG_USB_EHCI_EXYNOS
 
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_SMSC95XX
 
index 4422d5e8d5f4eda810ec78507a143475f2804758..2fc6693579a290b3ce9191fe9f69fc39ac439158 100644 (file)
@@ -58,7 +58,6 @@
 
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       147
 
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_ASIX
 #define CONFIG_USB_ETHER_MCS7830
index 834822df7fc75f8a5dc7a4617e3d42e857f18703..133069abbcd0c0afcac18b7bcb4ae8e06b36ce31 100644 (file)
@@ -41,7 +41,6 @@
 
 /* USB EHCI */
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       183
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
 
 /* commands to include */
 
index a973ce6a62b76963339d495d1710090f1acb91f9..9951980836d4e8e4fbffe0646a7378643ae71fa5 100644 (file)
@@ -17,8 +17,6 @@
  */
 
 /* USB UHH support options */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
-
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 1
 #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 62
 
index eb5e6df9ca7a064263a69c92d621a187ea07fd45..9b650090be8b17cdf9d75783f4497b7b55de974b 100644 (file)
@@ -51,7 +51,6 @@
 #define CONFIG_SYS_I2C_TCA642X_ADDR 0x22
 
 /* USB UHH support options */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET
 
 #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 80
index 88f841dfd88ef0268f166183abb085c8df5d8d08..a14739f282cba0cc42aadbd1a8ccb385fe9bf766 100644 (file)
@@ -97,9 +97,6 @@
 #define CONFIG_RESET_PHY_R
 #define CONFIG_AT91_WANTS_COMMON_PHY
 
-/* USB */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     2
-
 #define CONFIG_SYS_LOAD_ADDR           0x22000000      /* load address */
 
 #define CONFIG_SYS_MEMTEST_START       CONFIG_SYS_SDRAM_BASE
index d59f32a352d54974bf183f755ae07cfa228a6276..d2ecd0dec178e01c384cafbe3fa5b584261d59a9 100644 (file)
@@ -30,7 +30,6 @@
 #define CONFIG_PL01X_SERIAL
 
 /* USB configuration */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
 #define CONFIG_USB_MAX_CONTROLLER_COUNT                2
 #define CONFIG_SYS_USB_EVENT_POLL
 #define CONFIG_USB_HOST_ETHER
index 7f9f0c55344bafb3b5f44774947948126c325cf1..906c821aeffb76dcc2fd375b2022aba93d3f42db 100644 (file)
@@ -63,6 +63,4 @@
 #define CONFIG_USB_OHCI_NEW
 #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS     1
 
-/* xhci host */
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #endif
index 6c9d760995ce0b32a17c0d76bde61c2dd50d6b09..33178879e24abe88e8a89284fea4fac88ad01f7a 100644 (file)
@@ -80,7 +80,4 @@
 #define CONFIG_USB_ETHER_SMSC95XX
 #define CONFIG_USB_ETHER_RTL8152
 
-/* rockchip xhci host driver */
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
-
 #endif
index b25be974b68a3506a581763fd399b8c3aea7462f..401f1987ee8f5f9caf90c742f9c67a19e4fce8c7 100644 (file)
 /* USB */
 #define CONFIG_CMD_USB
 
-#ifdef CONFIG_CMD_USB
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
-#endif
-
 /* USB device */
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_DUALSPEED
index 2c5f2648eeef78922777e562c344b291df42b8e3..47dd99100bafbcac7c9429fee4891e74c7b0eea0 100644 (file)
@@ -60,9 +60,6 @@
 #define CONFIG_TFTP_PORT
 #define CONFIG_TFTP_TSIZE
 
-/* USB */
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     2
-
 /* MMC */
 #define CONFIG_GENERIC_ATMEL_MCI
 
index fefd58f76971fc70529e3ca936770dcdbe50c5af..681c91cf46dcb089a88849bce861927c8b37e5bc 100644 (file)
@@ -310,7 +310,6 @@ extern int soft_i2c_gpio_scl;
 #define CONFIG_USB_OHCI_NEW
 #define CONFIG_USB_OHCI_SUNXI
 #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 #endif
 
 #ifdef CONFIG_USB_MUSB_SUNXI
index a9991fc6b81ebb41e18de3d64be4dd78d24b0493..fb173ebfb4de34610690790bc06a299e8508be14 100644 (file)
@@ -67,7 +67,6 @@
                                        115200}
 /* EHCI */
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       25
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 
 /* commands to include */
 #define CONFIG_CMD_NAND                /* NAND support                 */
index 38f5bd015f82514d8345e424d6127d86df089c7c..08134f4a1e442670e7475d97a6c21256e6fddad1 100644 (file)
 /* USB EHCI */
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       162
 
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_SMSC95XX
 
index 107a0f8803313fd82d4b120a5ba63d008f01a8d4..75d2065177a12f215ff94b482f978a379d4ee40b 100644 (file)
@@ -63,6 +63,5 @@
 /* For USB EHCI controller */
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_USB_EHCI_TXFIFO_THRESH  0x10
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 
 #endif /* _TEGRA114_COMMON_H_ */
index 8cf9bac15680c78c912be71d868eb24227eaf627..0d61753c035c4abfb8b1b33ac4abe842ab47f667 100644 (file)
@@ -65,7 +65,6 @@
 /* For USB EHCI controller */
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_USB_EHCI_TXFIFO_THRESH  0x10
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 
 /* GPU needs setup */
 #define CONFIG_TEGRA_GPU
index db1cc248f45baf102967891b00978f9863e19079..342ffbe5b2b4171a0c2755150b16fcae333febbf 100644 (file)
@@ -82,7 +82,6 @@
  */
 #define CONFIG_USB_EHCI_TXFIFO_THRESH  10
 #define CONFIG_EHCI_IS_TDI
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 
 #define CONFIG_SYS_NAND_SELF_INIT
 #define CONFIG_SYS_NAND_ONFI_DETECTION
index 874fe34d4f4d1796a434c1a5ed1467202ba10ccf..4c05576a909e318b2b498f5a83b6352200b1c4a7 100644 (file)
@@ -68,7 +68,6 @@
 /* For USB EHCI controller */
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_USB_EHCI_TXFIFO_THRESH  0x10
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 
 /* GPU needs setup */
 #define CONFIG_TEGRA_GPU
index 60838474a6398b6aca2ef1b4cd93566b6cccfde8..c2096fbe7ec497660f062bdc56498acbe364f1de 100644 (file)
@@ -64,6 +64,5 @@
 /* For USB EHCI controller */
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_USB_EHCI_TXFIFO_THRESH  0x10
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 
 #endif /* _TEGRA30_COMMON_H_ */
index c6122a0f74a3a7b5b99f2e380c1313f8c8570750..26290ef1b278cee1c10645f7ac0d6a308dddfe2d 100644 (file)
 
 /* USB Configuration */
 #define CONFIG_USB_XHCI_KEYSTONE
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
 #define CONFIG_USB_SS_BASE                     KS2_USB_SS_BASE
 #define CONFIG_USB_HOST_XHCI_BASE              KS2_USB_HOST_XHCI_BASE
 #define CONFIG_DEV_USB_PHY_BASE                        KS2_DEV_USB_PHY_BASE
index cc65f072bc70e7c5ddb8b88646873c68bf95506b..6f5313931ab9dbccbd2ce4934e5af12b4b26f6a1 100644 (file)
 #define CONFIG_SYS_NAND_USE_FLASH_BBT
 #define CONFIG_SYS_NAND_BAD_BLOCK_POS                  0
 
-/* USB */
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     4
-
 /* SD/MMC */
 #define CONFIG_SUPPORT_EMMC_BOOT
 
index dc35b289d42a55de1f0671167173206ffade9e44..adff1b6d7f7100d40100acb891c1c1d485db357a 100644 (file)
 
 #endif
 
-/* USB */
-
-#ifdef CONFIG_CMD_USB
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
-#endif
-
 /* USB device */
 #define CONFIG_USB_ETHER
 #define CONFIG_USB_ETH_RNDIS
index 1be69748b743999676435c37b2b116f2383fa1ad..aa1e505e6903e65ceed59172f558535cc026641b 100644 (file)
  * USB configuration
  */
 #define CONFIG_USB_EHCI_PCI
-#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     12
 #define CONFIG_SYS_USB_EVENT_POLL
 
 #define CONFIG_USB_HOST_ETHER
index c30e37cccadb8c17de6700b807fc7f2c1270e619..7c5ec1924d4f71c1f7bf160e5c7dc5d6f0f64563 100644 (file)
@@ -90,8 +90,6 @@
 #define CONFIG_SYS_LOAD_ADDR           0x8000000
 
 #if defined(CONFIG_ZYNQMP_USB)
-#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
-
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE   0x1800000
 #define DFU_DEFAULT_POLL_TIMEOUT       300
 #define CONFIG_USB_CABLE_CHECK
index f39d3f1171a0d87393571ad96fd2e15cae30077c..7e322d9d2764d4091cd00cf87709a33da991c38f 100644 (file)
@@ -110,7 +110,7 @@ struct dfu_entity {
                struct sf_internal_data sf;
        } data;
 
-       long (*get_medium_size)(struct dfu_entity *dfu);
+       int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
 
        int (*read_medium)(struct dfu_entity *dfu,
                        u64 offset, void *buf, long *len);
@@ -132,7 +132,7 @@ struct dfu_entity {
        u8 *i_buf;
        u8 *i_buf_start;
        u8 *i_buf_end;
-       long r_left;
+       u64 r_left;
        long b_left;
 
        u32 bad_skip;   /* for nand use */
index c5ea391aec169a2c8a17666b0257896dbc4bf45c..c49d287dd6004d9727398d734129c16dbb784139 100644 (file)
@@ -352,6 +352,24 @@ int of_parse_phandle_with_args(const struct device_node *np,
                               const char *list_name, const char *cells_name,
                               int index, struct of_phandle_args *out_args);
 
+/**
+ * of_count_phandle_with_args() - Count the number of phandle in a list
+ *
+ * @np:                pointer to a device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name:        property name that specifies phandles' arguments count
+ * @return number of phandle found, -ENOENT if
+ *     @list_name does not exist, -EINVAL if a phandle was not found,
+ *     @cells_name could not be found, the arguments were truncated or there
+ *     were too many arguments.
+ *
+ * Returns number of phandle found on success, on error returns appropriate
+ * errno value.
+ *
+ */
+int of_count_phandle_with_args(const struct device_node *np,
+                              const char *list_name, const char *cells_name);
+
 /**
  * of_alias_scan() - Scan all properties of the 'aliases' node
  *
index 966ca9309a3c776fbeb1385852b681b01f7f9ca3..210ddb2e5d7464573ef6d8c85cd0cd1d2a85291a 100644 (file)
@@ -434,6 +434,23 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
                                   int index,
                                   struct ofnode_phandle_args *out_args);
 
+/**
+ * ofnode_count_phandle_with_args() - Count number of phandle in a list
+ *
+ * This function is useful to count phandles into a list.
+ * Returns number of phandle on success, on error returns appropriate
+ * errno value.
+ *
+ * @node:      device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name:        property name that specifies phandles' arguments count
+ * @return number of phandle on success, -ENOENT if @list_name does not
+ *      exist, -EINVAL if a phandle was not found, @cells_name could not
+ *      be found.
+ */
+int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
+                                  const char *cells_name);
+
 /**
  * ofnode_path() - find a node by full path
  *
index c2ca7ae34d4b48e31bcb4eba3a1d9c17cde35448..c3a4a5611a70aad6fd7b4669524c0f2d461195dd 100644 (file)
@@ -198,6 +198,24 @@ int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
                                int index,
                                struct ofnode_phandle_args *out_args);
 
+/**
+ * dev_count_phandle_with_args() - Return phandle number in a list
+ *
+ * This function is usefull to get phandle number contained in a property list.
+ * For example, this allows to allocate the right amount of memory to keep
+ * clock's reference contained into the "clocks" property.
+ *
+ *
+ * @dev:       device whose node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name:        property name that specifies phandles' arguments count
+ * @Returns number of phandle found on success, on error returns appropriate
+ * errno value.
+ */
+
+int dev_count_phandle_with_args(struct udevice *dev, const char *list_name,
+                               const char *cells_name);
+
 /**
  * dev_read_addr_cells() - Get the number of address cells for a device's node
  *
@@ -416,6 +434,13 @@ static inline int dev_read_phandle_with_args(struct udevice *dev,
                                              out_args);
 }
 
+static inline int dev_count_phandle_with_args(struct udevice *dev,
+               const char *list_name, const char *cells_name)
+{
+       return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name,
+                                             cells_name);
+}
+
 static inline int dev_read_addr_cells(struct udevice *dev)
 {
        /* NOTE: this call should walk up the parent stack */
index 762704c208e1674663067ac9c1f7f3dfd6ba0971..eac5adc893395e1837008c0166ddec5729c424d6 100644 (file)
@@ -122,6 +122,7 @@ struct phy_ops {
        int     (*power_off)(struct phy *phy);
 };
 
+#ifdef CONFIG_PHY
 
 /**
  * generic_phy_init() - initialize the PHY port
@@ -220,4 +221,56 @@ int generic_phy_get_by_index(struct udevice *user, int index,
 int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
                            struct phy *phy);
 
+#else /* CONFIG_PHY */
+
+static inline int generic_phy_init(struct phy *phy)
+{
+       return 0;
+}
+
+static inline int generic_phy_exit(struct phy *phy)
+{
+       return 0;
+}
+
+static inline int generic_phy_reset(struct phy *phy)
+{
+       return 0;
+}
+
+static inline int generic_phy_power_on(struct phy *phy)
+{
+       return 0;
+}
+
+static inline int generic_phy_power_off(struct phy *phy)
+{
+       return 0;
+}
+
+static inline int generic_phy_get_by_index(struct udevice *user, int index,
+                            struct phy *phy)
+{
+       return 0;
+}
+
+static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
+                           struct phy *phy)
+{
+       return 0;
+}
+
+#endif /* CONFIG_PHY */
+
+/**
+ * generic_phy_valid() - check if PHY port is valid
+ *
+ * @phy:       the PHY port to check
+ * @return TRUE if valid, or FALSE
+ */
+static inline bool generic_phy_valid(struct phy *phy)
+{
+       return phy->dev != NULL;
+}
+
 #endif /*__GENERIC_PHY_H */
index f45fcf88c43cbe205177af0e46e2f5e7b610366c..7185ade7ac5e96a56b0c0e0d3d332641400310ec 100644 (file)
@@ -99,6 +99,15 @@ int reset_get_by_index(struct udevice *dev, int index,
 int reset_get_by_name(struct udevice *dev, const char *name,
                      struct reset_ctl *reset_ctl);
 
+/**
+ * reset_request - Request a reset signal.
+ *
+ * @reset_ctl: A reset control struct.
+ *
+ * @return 0 if OK, or a negative error code.
+ */
+int reset_request(struct reset_ctl *reset_ctl);
+
 /**
  * reset_free - Free a previously requested reset signal.
  *
@@ -135,6 +144,18 @@ int reset_assert(struct reset_ctl *reset_ctl);
  */
 int reset_deassert(struct reset_ctl *reset_ctl);
 
+/**
+ * reset_release_all - Assert/Free an array of previously requested resets.
+ *
+ * For each reset contained in the reset array, this function will check if
+ * reset has been previously requested and then will assert and free it.
+ *
+ * @reset_ctl: A reset struct array that was previously successfully
+ *             requested by reset_get_by_*().
+ * @count      Number of reset contained in the array
+ * @return 0 if OK, or a negative error code.
+ */
+int reset_release_all(struct reset_ctl *reset_ctl, int count);
 #else
 static inline int reset_get_by_index(struct udevice *dev, int index,
                                     struct reset_ctl *reset_ctl)
@@ -162,6 +183,12 @@ static inline int reset_deassert(struct reset_ctl *reset_ctl)
 {
        return 0;
 }
+
+static inline int reset_release_all(struct reset_ctl *reset_ctl, int count)
+{
+       return 0;
+}
+
 #endif
 
 #endif
index 62f051fe535c992d9acd50dbc092f17dbd9051e5..fad04016a348fe1a8afb8f3f4783873c18a47678 100644 (file)
@@ -537,6 +537,21 @@ struct usb_hub_status {
        unsigned short wHubChange;
 } __attribute__ ((packed));
 
+/*
+ * Hub Device descriptor
+ * USB Hub class device protocols
+ */
+#define USB_HUB_PR_FS          0 /* Full speed hub */
+#define USB_HUB_PR_HS_NO_TT    0 /* Hi-speed hub without TT */
+#define USB_HUB_PR_HS_SINGLE_TT        1 /* Hi-speed hub with single TT */
+#define USB_HUB_PR_HS_MULTI_TT 2 /* Hi-speed hub with multiple TT */
+#define USB_HUB_PR_SS          3 /* Super speed hub */
+
+/* Transaction Translator Think Times, in bits */
+#define HUB_TTTT_8_BITS                0x00
+#define HUB_TTTT_16_BITS       0x20
+#define HUB_TTTT_24_BITS       0x40
+#define HUB_TTTT_32_BITS       0x60
 
 /* Hub descriptor */
 struct usb_hub_descriptor {
@@ -546,10 +561,20 @@ struct usb_hub_descriptor {
        unsigned short wHubCharacteristics;
        unsigned char  bPwrOn2PwrGood;
        unsigned char  bHubContrCurrent;
-       unsigned char  DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
-       unsigned char  PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
-       /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
-          bitmaps that hold max 255 entries. (bit0 is ignored) */
+       /* 2.0 and 3.0 hubs differ here */
+       union {
+               struct {
+                       /* add 1 bit for hub status change; round to bytes */
+                       __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
+                       __u8 PortPowerCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
+               } __attribute__ ((packed)) hs;
+
+               struct {
+                       __u8 bHubHdrDecLat;
+                       __le16 wHubDelay;
+                       __le16 DeviceRemovable;
+               } __attribute__ ((packed)) ss;
+       } u;
 } __attribute__ ((packed));
 
 
@@ -560,6 +585,8 @@ struct usb_hub_device {
        ulong connect_timeout;          /* Device connection timeout in ms */
        ulong query_delay;              /* Device query delay in ms */
        int overcurrent_count[USB_MAXCHILDREN]; /* Over-current counter */
+       int hub_depth;                  /* USB 3.0 hub depth */
+       struct usb_tt tt;               /* Transaction Translator */
 };
 
 #ifdef CONFIG_DM_USB
@@ -731,6 +758,14 @@ struct dm_usb_ops {
         * reset_root_port() - Reset usb root port
         */
        int (*reset_root_port)(struct udevice *bus, struct usb_device *udev);
+
+       /**
+        * update_hub_device() - Update HCD's internal representation of hub
+        *
+        * After a hub descriptor is fetched, notify HCD so that its internal
+        * representation of this hub can be updated (xHCI)
+        */
+       int (*update_hub_device)(struct udevice *bus, struct usb_device *udev);
 };
 
 #define usb_get_ops(dev)       ((struct dm_usb_ops *)(dev)->driver->ops)
@@ -765,6 +800,14 @@ struct usb_device *usb_get_dev_index(struct udevice *bus, int index);
 int usb_setup_device(struct usb_device *dev, bool do_read,
                     struct usb_device *parent);
 
+/**
+ * usb_hub_is_root_hub() - Test whether a hub device is root hub or not
+ *
+ * @hub:       USB hub device to test
+ * @return:    true if the hub device is root hub, false otherwise.
+ */
+bool usb_hub_is_root_hub(struct udevice *hub);
+
 /**
  * usb_hub_scan() - Scan a hub and find its devices
  *
@@ -861,24 +904,6 @@ bool usb_device_has_child_on_port(struct usb_device *parent, int port);
 int usb_hub_probe(struct usb_device *dev, int ifnum);
 void usb_hub_reset(void);
 
-/**
- * legacy_hub_port_reset() - reset a port given its usb_device pointer
- *
- * Reset a hub port and see if a device is present on that port, providing
- * sufficient time for it to show itself. The port status is returned.
- *
- * With driver model this moves to hub_port_reset() and is passed a struct
- * udevice.
- *
- * @dev:       USB device to reset
- * @port:      Port number to reset (note ports are numbered from 0 here)
- * @portstat:  Returns port status
- */
-int legacy_hub_port_reset(struct usb_device *dev, int port,
-                         unsigned short *portstat);
-
-int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat);
-
 /*
  * usb_find_usb2_hub_address_port() - Get hub address and port for TT setting
  *
@@ -913,6 +938,17 @@ int usb_new_device(struct usb_device *dev);
 
 int usb_alloc_device(struct usb_device *dev);
 
+/**
+ * update_hub_device() - Update HCD's internal representation of hub
+ *
+ * After a hub descriptor is fetched, notify HCD so that its internal
+ * representation of this hub can be updated.
+ *
+ * @dev:               Hub device
+ * @return 0 if OK, -ve on error
+ */
+int usb_update_hub_device(struct usb_device *dev);
+
 /**
  * usb_emul_setup_device() - Set up a new USB device emulation
  *
@@ -926,7 +962,7 @@ int usb_alloc_device(struct usb_device *dev);
  * @desc_list:         List of points or USB descriptors, terminated by NULL.
  *                     The first entry must be struct usb_device_descriptor,
  *                     and others follow on after that.
- * @return 0 if OK, -ve on error
+ * @return 0 if OK, -ENOSYS if not implemented, other -ve on error
  */
 int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
                          struct usb_string *strings, void **desc_list);
index 8214ba9bf5577093a370ed8cb1144f3b3fc680bd..b7f2eada07d0e7e711124aaa7f664cc130fbcbb4 100644 (file)
@@ -93,6 +93,7 @@
 #define USB_DT_REPORT       (USB_TYPE_CLASS | 0x02)
 #define USB_DT_PHYSICAL     (USB_TYPE_CLASS | 0x03)
 #define USB_DT_HUB          (USB_TYPE_CLASS | 0x09)
+#define USB_DT_SS_HUB       (USB_TYPE_CLASS | 0x0a)
 
 /* Descriptor sizes per descriptor type */
 #define USB_DT_DEVICE_SIZE      18
 
 /*
  * Changes to wPortStatus bit field in USB 3.0
- * See USB 3.0 spec Table 10-11
+ * See USB 3.0 spec Table 10-10
  */
 #define USB_SS_PORT_STAT_LINK_STATE    0x01e0
 #define USB_SS_PORT_STAT_POWER         0x0200
 #define USB_SS_PORT_STAT_SPEED         0x1c00
 #define USB_SS_PORT_STAT_SPEED_5GBPS   0x0000
+/* Bits that are the same from USB 2.0 */
+#define USB_SS_PORT_STAT_MASK          (USB_PORT_STAT_CONNECTION | \
+                                        USB_PORT_STAT_ENABLE | \
+                                        USB_PORT_STAT_OVERCURRENT | \
+                                        USB_PORT_STAT_RESET)
 
 /* wPortChange bits */
 #define USB_PORT_STAT_C_CONNECTION  0x0001
 #define HUB_CHAR_LPSM               0x0003
 #define HUB_CHAR_COMPOUND           0x0004
 #define HUB_CHAR_OCPM               0x0018
+#define HUB_CHAR_TTTT               0x0060 /* TT Think Time mask */
 
 /*
  * Hub Status & Hub Change bit masks
 /* Mask for wIndex in get/set port feature */
 #define USB_HUB_PORT_MASK      0xf
 
+/* Hub class request codes */
+#define USB_REQ_SET_HUB_DEPTH  0x0c
+
+/*
+ * As of USB 2.0, full/low speed devices are segregated into trees.
+ * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
+ * The other type grows from high speed hubs when they connect to
+ * full/low speed devices using "Transaction Translators" (TTs).
+ */
+struct usb_tt {
+       bool            multi;          /* true means one TT per port */
+       unsigned        think_time;     /* think time in ns */
+};
+
 /*
  * CBI style
  */
index 93f0bf47c674012a458f87e0f92009098d900676..2d642de7291c28fbd536e90b0211a8b5d24985bc 100644 (file)
@@ -4868,7 +4868,6 @@ CONFIG_SYS_UNSPEC_STRID
 CONFIG_SYS_USBCTRL
 CONFIG_SYS_USBD_BASE
 CONFIG_SYS_USB_EHCI_CPU_INIT
-CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS
 CONFIG_SYS_USB_EHCI_REGS_BASE
 CONFIG_SYS_USB_FAT_BOOT_PARTITION
 CONFIG_SYS_USB_HOST
@@ -4877,7 +4876,6 @@ CONFIG_SYS_USB_OHCI_CPU_INIT
 CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS
 CONFIG_SYS_USB_OHCI_REGS_BASE
 CONFIG_SYS_USB_OHCI_SLOT_NAME
-CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS
 CONFIG_SYS_USER_SWITCHES_BASE
 CONFIG_SYS_USE_BOOT_NORFLASH
 CONFIG_SYS_USE_DATAFLASH
@@ -5196,7 +5194,6 @@ CONFIG_USB_XHCI_EXYNOS
 CONFIG_USB_XHCI_FSL
 CONFIG_USB_XHCI_KEYSTONE
 CONFIG_USB_XHCI_OMAP
-CONFIG_USB_XHCI_PCI
 CONFIG_USER_LOWLEVEL_INIT
 CONFIG_USE_FDT
 CONFIG_USE_INTERRUPT