Merge branch 'master' of git://git.denx.de/u-boot-video
diff --git a/arch/arm/include/asm/arch-exynos/ehci.h b/arch/arm/include/asm/arch-exynos/ehci.h
index d79f25c..d2d70bd 100644
--- a/arch/arm/include/asm/arch-exynos/ehci.h
+++ b/arch/arm/include/asm/arch-exynos/ehci.h
@@ -29,6 +29,20 @@
 #define EHCICTRL_ENAINCR8			(1 << 27)
 #define EHCICTRL_ENAINCR16			(1 << 26)
 
+#define HSIC_CTRL_REFCLKSEL                     (0x2)
+#define HSIC_CTRL_REFCLKSEL_MASK                (0x3)
+#define HSIC_CTRL_REFCLKSEL_SHIFT               (23)
+
+#define HSIC_CTRL_REFCLKDIV_12                  (0x24)
+#define HSIC_CTRL_REFCLKDIV_MASK                (0x7f)
+#define HSIC_CTRL_REFCLKDIV_SHIFT               (16)
+
+#define HSIC_CTRL_SIDDQ                         (0x1 << 6)
+#define HSIC_CTRL_FORCESLEEP                    (0x1 << 5)
+#define HSIC_CTRL_FORCESUSPEND                  (0x1 << 4)
+#define HSIC_CTRL_UTMISWRST                     (0x1 << 2)
+#define HSIC_CTRL_PHYSWRST                      (0x1 << 0)
+
 /* Register map for PHY control */
 struct exynos_usb_phy {
 	unsigned int usbphyctrl0;
diff --git a/board/samsung/arndale/arndale.c b/board/samsung/arndale/arndale.c
index 052fecd..9efc355 100644
--- a/board/samsung/arndale/arndale.c
+++ b/board/samsung/arndale/arndale.c
@@ -5,12 +5,33 @@
  */
 
 #include <common.h>
+#include <usb.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/dwmmc.h>
+#include <asm/arch/gpio.h>
 #include <asm/arch/power.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_USB_EHCI_EXYNOS
+int board_usb_init(int index, enum usb_init_type init)
+{
+	struct exynos5_gpio_part1 *gpio = (struct exynos5_gpio_part1 *)
+						samsung_get_base_gpio_part1();
+
+	/* Configure gpios for usb 3503 hub:
+	 * disconnect, toggle reset and connect
+	 */
+	s5p_gpio_direction_output(&gpio->d1, 7, 0);
+	s5p_gpio_direction_output(&gpio->x3, 5, 0);
+
+	s5p_gpio_direction_output(&gpio->x3, 5, 1);
+	s5p_gpio_direction_output(&gpio->d1, 7, 1);
+
+	return 0;
+}
+#endif
+
 int board_init(void)
 {
 	gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
index 99487f4..5f557d5 100644
--- a/common/cmd_usb_mass_storage.c
+++ b/common/cmd_usb_mass_storage.c
@@ -42,6 +42,30 @@
 
 	g_dnl_register("ums");
 
+	/* Timeout unit: seconds */
+	int cable_ready_timeout = UMS_CABLE_READY_TIMEOUT;
+
+	if (!usb_cable_connected()) {
+		puts("Please connect USB cable.\n");
+
+		while (!usb_cable_connected()) {
+			if (ctrlc()) {
+				puts("\rCTRL+C - Operation aborted.\n");
+				goto exit;
+			}
+			if (!cable_ready_timeout) {
+				puts("\rUSB cable not detected.\n" \
+				     "Command exit.\n");
+				goto exit;
+			}
+
+			printf("\rAuto exit in: %.2d s.", cable_ready_timeout);
+			mdelay(1000);
+			cable_ready_timeout--;
+		}
+		puts("\r\n");
+	}
+
 	while (1) {
 		usb_gadget_handle_interrupts();
 
diff --git a/drivers/usb/gadget/fotg210.c b/drivers/usb/gadget/fotg210.c
index 6e19db1..3acf6a1 100644
--- a/drivers/usb/gadget/fotg210.c
+++ b/drivers/usb/gadget/fotg210.c
@@ -245,6 +245,7 @@
 		if (ep->id == 0) {
 			/* Wait until cx/ep0 fifo empty */
 			fotg210_cxwait(chip, CXFIFO_CXFIFOE);
+			udelay(1);
 			writel(DMAFIFO_CX, &regs->dma_fifo);
 		} else {
 			/* Wait until epx fifo empty */
@@ -847,6 +848,13 @@
 	/* CX interrupts */
 	if (gisr & GISR_GRP0) {
 		st = readl(&regs->gisr0);
+		/*
+		 * Write 1 and then 0 works for both W1C & RW.
+		 *
+		 * HW v1.11.0+: It's a W1C register (write 1 clear)
+		 * HW v1.10.0-: It's a R/W register (write 0 clear)
+		 */
+		writel(st & GISR0_CXABORT, &regs->gisr0);
 		writel(0, &regs->gisr0);
 
 		if (st & GISR0_CXERR)
@@ -873,6 +881,13 @@
 	/* Device Status Interrupts */
 	if (gisr & GISR_GRP2) {
 		st = readl(&regs->gisr2);
+		/*
+		 * Write 1 and then 0 works for both W1C & RW.
+		 *
+		 * HW v1.11.0+: It's a W1C register (write 1 clear)
+		 * HW v1.10.0-: It's a R/W register (write 0 clear)
+		 */
+		writel(st, &regs->gisr2);
 		writel(0, &regs->gisr2);
 
 		if (st & GISR2_RESET)
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 66b4de0..9356878 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -88,6 +88,8 @@
 /* Setup the EHCI host controller. */
 static void setup_usb_phy(struct exynos_usb_phy *usb)
 {
+	u32 hsic_ctrl;
+
 	set_usbhost_mode(USB20_PHY_CFG_HOST_LINK_EN);
 
 	set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_EN);
@@ -112,6 +114,32 @@
 	clrbits_le32(&usb->usbphyctrl0,
 			HOST_CTRL0_LINKSWRST |
 			HOST_CTRL0_UTMISWRST);
+
+	/* HSIC Phy Setting */
+	hsic_ctrl = (HSIC_CTRL_FORCESUSPEND |
+			HSIC_CTRL_FORCESLEEP |
+			HSIC_CTRL_SIDDQ);
+
+	clrbits_le32(&usb->hsicphyctrl1, hsic_ctrl);
+	clrbits_le32(&usb->hsicphyctrl2, hsic_ctrl);
+
+	hsic_ctrl = (((HSIC_CTRL_REFCLKDIV_12 & HSIC_CTRL_REFCLKDIV_MASK)
+				<< HSIC_CTRL_REFCLKDIV_SHIFT)
+			| ((HSIC_CTRL_REFCLKSEL & HSIC_CTRL_REFCLKSEL_MASK)
+				<< HSIC_CTRL_REFCLKSEL_SHIFT)
+			| HSIC_CTRL_UTMISWRST);
+
+	setbits_le32(&usb->hsicphyctrl1, hsic_ctrl);
+	setbits_le32(&usb->hsicphyctrl2, hsic_ctrl);
+
+	udelay(10);
+
+	clrbits_le32(&usb->hsicphyctrl1, HSIC_CTRL_PHYSWRST |
+					HSIC_CTRL_UTMISWRST);
+
+	clrbits_le32(&usb->hsicphyctrl2, HSIC_CTRL_PHYSWRST |
+					HSIC_CTRL_UTMISWRST);
+
 	udelay(20);
 
 	/* EHCI Ctrl setting */
@@ -125,6 +153,8 @@
 /* Reset the EHCI host controller. */
 static void reset_usb_phy(struct exynos_usb_phy *usb)
 {
+	u32 hsic_ctrl;
+
 	/* HOST_PHY reset */
 	setbits_le32(&usb->usbphyctrl0,
 			HOST_CTRL0_PHYSWRST |
@@ -133,6 +163,15 @@
 			HOST_CTRL0_FORCESUSPEND |
 			HOST_CTRL0_FORCESLEEP);
 
+	/* HSIC Phy reset */
+	hsic_ctrl = (HSIC_CTRL_FORCESUSPEND |
+			HSIC_CTRL_FORCESLEEP |
+			HSIC_CTRL_SIDDQ |
+			HSIC_CTRL_PHYSWRST);
+
+	setbits_le32(&usb->hsicphyctrl1, hsic_ctrl);
+	setbits_le32(&usb->hsicphyctrl2, hsic_ctrl);
+
 	set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE);
 }
 
@@ -164,6 +203,8 @@
 
 	setup_usb_phy(ctx->usb);
 
+	board_usb_init(index, init);
+
 	*hccr = ctx->hcd;
 	*hcor = (struct ehci_hcor *)((uint32_t) *hccr
 				+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index 7e367f3..9584d82 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -117,6 +117,10 @@
 #define CONFIG_USB_EHCI_EXYNOS
 #define CONFIG_USB_STORAGE
 
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS	3
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+
 /* MMC SPL */
 #define CONFIG_EXYNOS_SPL
 #define CONFIG_SPL
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h
index 9df3adc..058dcf1 100644
--- a/include/usb_mass_storage.h
+++ b/include/usb_mass_storage.h
@@ -20,6 +20,9 @@
 #define UMS_NUM_SECTORS		0
 #endif
 
+/* Wait at maximum 60 seconds for cable connection */
+#define UMS_CABLE_READY_TIMEOUT	60
+
 struct ums {
 	int (*read_sector)(struct ums *ums_dev,
 			   ulong start, lbaint_t blkcnt, void *buf);