CHROMIUM: exynos: reset external HSIC hub
authorVincent Palatin <vpalatin@chromium.org>
Fri, 26 Oct 2012 16:24:51 +0000 (09:24 -0700)
committerChromeBot <chrome-bot@google.com>
Thu, 10 Jan 2013 21:56:31 +0000 (13:56 -0800)
The former code was only ensuring that the reset line was released but
neither doing an actual reset pulse if it was already before nor
ensuring we had proper reset timings.
If the HSIC hub was used before booting (e.g on Spring, the external
USB2 port is connected the HSIC hub, so the bootloader is using it to
boot from USB), we need to do a proper 100us low reset pulse, then wait
for 4 ms for the hub to finish initialization (as per SMSC 3503
datasheet).

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=chrome-os-partner:14490
TEST=boot on Spring from a USB key connected to the external USB2 port
(which is connected to the HSIC hub
boot on Snow, do a "lsusb" and see the internal USB peripherals
connected the HSIC hub are there (e.g."ID 1410:a021 Novatel wireless"
 and "ID 2232:1037" which is webcam).

Change-Id: Idb15188aa1b1d502387a5e67b3598d016eeb6ab7
Reviewed-on: https://gerrit.chromium.org/gerrit/36693
Reviewed-by: Doug Anderson <dianders@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
arch/arm/boot/dts/cros5250-common.dtsi
arch/arm/mach-exynos/setup-usb-phy.c

index 1349822..2bbff97 100644 (file)
                regulator-name = "hsichub-reset-l";
                gpio = <&gpe1 0 1 0 0>;
                enable-active-high;
-               regulator-always-on;
        };
 
        // NB: nodes must be at root for regulator-fixed to probe
index 635d90b..9b5a3fc 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <mach/regs-pmu.h>
 #include <mach/regs-usb-phy.h>
 #include <plat/cpu.h>
@@ -345,6 +346,7 @@ static int exynos5_usb_phy20_init(struct platform_device *pdev)
        u32 refclk_freq;
        u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl, ehcictrl;
        struct clk *host_clk = NULL;
+       struct regulator *hub_reset;
 
        atomic_inc(&host_usage);
 
@@ -401,6 +403,20 @@ static int exynos5_usb_phy20_init(struct platform_device *pdev)
        writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
 
        /* HSIC phy reset */
+       hub_reset = regulator_get(NULL, "hsichub-reset-l");
+       if (!IS_ERR(hub_reset)) {
+               /*
+                * toggle the reset line of the HSIC hub chip.
+                */
+               regulator_force_disable(hub_reset);
+               /* keep reset active during 100 us */
+               udelay(100);
+               regulator_enable(hub_reset);
+               regulator_put(hub_reset);
+               /* Hub init phase takes up to 4 ms */
+               usleep_range(4000, 10000);
+       }
+
        hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2)
                                                | HSIC_CTRL_PHYSWRST);
        writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);