diff options
| -rw-r--r-- | arch/arm/include/asm/arch-exynos/ehci.h | 14 | ||||
| -rw-r--r-- | board/samsung/arndale/arndale.c | 21 | ||||
| -rw-r--r-- | common/cmd_usb_mass_storage.c | 24 | ||||
| -rw-r--r-- | drivers/usb/gadget/fotg210.c | 15 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-exynos.c | 41 | ||||
| -rw-r--r-- | include/configs/arndale.h | 4 | ||||
| -rw-r--r-- | include/usb_mass_storage.h | 3 | 
7 files changed, 122 insertions, 0 deletions
| diff --git a/arch/arm/include/asm/arch-exynos/ehci.h b/arch/arm/include/asm/arch-exynos/ehci.h index d79f25c0c..d2d70bd82 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 052fecdd5..9efc355da 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 99487f4d0..5f557d5f8 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -42,6 +42,30 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,  	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 6e19db15f..3acf6a1f4 100644 --- a/drivers/usb/gadget/fotg210.c +++ b/drivers/usb/gadget/fotg210.c @@ -245,6 +245,7 @@ static int fotg210_dma(struct fotg210_ep *ep, struct fotg210_request *req)  		if (ep->id == 0) {  			/* Wait until cx/ep0 fifo empty */  			fotg210_cxwait(chip, CXFIFO_CXFIFOE); +			udelay(1);  			writel(DMAFIFO_CX, ®s->dma_fifo);  		} else {  			/* Wait until epx fifo empty */ @@ -847,6 +848,13 @@ int usb_gadget_handle_interrupts(void)  	/* CX interrupts */  	if (gisr & GISR_GRP0) {  		st = readl(®s->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, ®s->gisr0);  		writel(0, ®s->gisr0);  		if (st & GISR0_CXERR) @@ -873,6 +881,13 @@ int usb_gadget_handle_interrupts(void)  	/* Device Status Interrupts */  	if (gisr & GISR_GRP2) {  		st = readl(®s->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, ®s->gisr2);  		writel(0, ®s->gisr2);  		if (st & GISR2_RESET) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 66b4de0b2..9356878eb 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -88,6 +88,8 @@ static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)  /* 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 @@ static void setup_usb_phy(struct exynos_usb_phy *usb)  	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 @@ static void setup_usb_phy(struct exynos_usb_phy *usb)  /* 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 @@ static void reset_usb_phy(struct exynos_usb_phy *usb)  			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 @@ int ehci_hcd_init(int index, enum usb_init_type init,  	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 7e367f39b..9584d82af 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 9df3adcf2..058dcf117 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); |