summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorSteve Lin <stlin@nvidia.com>2011-11-29 14:01:28 -0800
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-21 12:06:22 +0530
commit71653d7720a77add116228c7e5717c5a74553f18 (patch)
treeb390b86a29501aa9be691087279e3850fdecf393 /arch
parenta43895ffdda87f651ef75f74b6f0e98524775a8d (diff)
arm: tegra: usb: Support tegra2 null ULPI phy restore function
Adding tegra2 null ULPI phy restore function and clean up code in usb_phy. Bug 907350 Bug 912407 Change-Id: I93aa191cd7f9fdace7f80a66fedbf034728e2fe9 Signed-off-by: Steve Lin <stlin@nvidia.com> Reviewed-on: http://git-master/r/67189 Reviewed-by: Martin Chabot <mchabot@nvidia.com> Tested-by: Martin Chabot <mchabot@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Tested-by: Jonathan Roux <jroux@nvidia.com> Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/board-enterprise-baseband.c17
-rw-r--r--arch/arm/mach-tegra/board-whistler-baseband.c12
-rw-r--r--arch/arm/mach-tegra/board-whistler-baseband.h5
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h4
-rw-r--r--arch/arm/mach-tegra/usb_phy.c57
5 files changed, 64 insertions, 31 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-baseband.c b/arch/arm/mach-tegra/board-enterprise-baseband.c
index 0084c06f6a8c..1463a066fca5 100644
--- a/arch/arm/mach-tegra/board-enterprise-baseband.c
+++ b/arch/arm/mach-tegra/board-enterprise-baseband.c
@@ -46,6 +46,12 @@
#define AP2MDM_ACK2 TEGRA_GPIO_PE2
#define MDM2AP_ACK2 TEGRA_GPIO_PV0
+/* ULPI GPIO */
+#define ULPI_STP TEGRA_GPIO_PY3
+#define ULPI_DIR TEGRA_GPIO_PY1
+#define ULPI_D0 TEGRA_GPIO_PO1
+#define ULPI_D1 TEGRA_GPIO_PO2
+
static struct wake_lock mdm_wake_lock;
static struct gpio modem_gpios[] = {
@@ -55,9 +61,10 @@ static struct gpio modem_gpios[] = {
{MDM2AP_ACK, GPIOF_IN, "MDM2AP_ACK"},
{AP2MDM_ACK2, GPIOF_OUT_INIT_HIGH, "AP2MDM ACK2"},
{AP2MDM_ACK, GPIOF_OUT_INIT_LOW, "AP2MDM ACK"},
- {TEGRA_GPIO_PY3, GPIOF_IN, "ULPI_STP"},
- {TEGRA_GPIO_PO1, GPIOF_OUT_INIT_LOW, "ULPI_D0"},
- {TEGRA_GPIO_PO2, GPIOF_OUT_INIT_LOW, "ULPI_D1"},
+ {ULPI_STP, GPIOF_IN, "ULPI_STP"},
+ {ULPI_DIR, GPIOF_OUT_INIT_LOW, "ULPI_DIR"},
+ {ULPI_D0, GPIOF_OUT_INIT_LOW, "ULPI_D0"},
+ {ULPI_D1, GPIOF_OUT_INIT_LOW, "ULPI_D1"},
};
static int baseband_phy_on(void);
@@ -73,6 +80,10 @@ static struct tegra_ulpi_config ehci2_null_ulpi_phy_config = {
.pre_phy_off = baseband_phy_off,
.phy_restore_start = baseband_phy_restore_start,
.phy_restore_end = baseband_phy_restore_end,
+ .phy_restore_gpio = MDM2AP_ACK,
+ .ulpi_dir_gpio = ULPI_DIR,
+ .ulpi_d0_gpio = ULPI_D0,
+ .ulpi_d1_gpio = ULPI_D1,
};
static struct tegra_ehci_platform_data ehci2_null_ulpi_platform_data = {
diff --git a/arch/arm/mach-tegra/board-whistler-baseband.c b/arch/arm/mach-tegra/board-whistler-baseband.c
index ff376d260306..143d14a8721d 100644
--- a/arch/arm/mach-tegra/board-whistler-baseband.c
+++ b/arch/arm/mach-tegra/board-whistler-baseband.c
@@ -38,10 +38,10 @@ static struct gpio modem_gpios[] = {
{MDM2AP_ACK, GPIOF_IN, "MDM2AP_ACK"},
{AP2MDM_ACK2, GPIOF_OUT_INIT_HIGH, "AP2MDM ACK2"},
{AP2MDM_ACK, GPIOF_OUT_INIT_LOW, "AP2MDM ACK"},
- {TEGRA_GPIO_PY3, GPIOF_IN, "ULPI_STP"},
- {TEGRA_GPIO_PY1, GPIOF_OUT_INIT_LOW, "ULPI_DIR"},
- {TEGRA_GPIO_PO1, GPIOF_OUT_INIT_LOW, "ULPI_D0"},
- {TEGRA_GPIO_PO2, GPIOF_OUT_INIT_LOW, "ULPI_D1"},
+ {ULPI_STP, GPIOF_IN, "ULPI_STP"},
+ {ULPI_DIR, GPIOF_OUT_INIT_LOW, "ULPI_DIR"},
+ {ULPI_D0, GPIOF_OUT_INIT_LOW, "ULPI_D0"},
+ {ULPI_D1, GPIOF_OUT_INIT_LOW, "ULPI_D1"},
};
static __initdata struct tegra_pingroup_config whistler_null_ulpi_pinmux[] = {
@@ -65,6 +65,10 @@ static struct tegra_ulpi_config ehci2_null_ulpi_phy_config = {
.pre_phy_off = baseband_phy_off,
.phy_restore_start = baseband_phy_restore_start,
.phy_restore_end = baseband_phy_restore_end,
+ .phy_restore_gpio = MDM2AP_ACK,
+ .ulpi_dir_gpio = ULPI_DIR,
+ .ulpi_d0_gpio = ULPI_D0,
+ .ulpi_d1_gpio = ULPI_D1,
};
static struct tegra_ehci_platform_data ehci2_null_ulpi_platform_data = {
diff --git a/arch/arm/mach-tegra/board-whistler-baseband.h b/arch/arm/mach-tegra/board-whistler-baseband.h
index b9e107f166f4..aceef6cd9676 100644
--- a/arch/arm/mach-tegra/board-whistler-baseband.h
+++ b/arch/arm/mach-tegra/board-whistler-baseband.h
@@ -63,6 +63,11 @@
#define MDM2AP_ACK2 TEGRA_GPIO_PV2
#define BB_RST_OUT TEGRA_GPIO_PV3
+/* ULPI GPIO */
+#define ULPI_STP TEGRA_GPIO_PY3
+#define ULPI_DIR TEGRA_GPIO_PY1
+#define ULPI_D0 TEGRA_GPIO_PO1
+#define ULPI_D1 TEGRA_GPIO_PO2
struct whistler_baseband {
struct tegra_clk_init_table *clk_init;
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index 64ba2e83d2e8..6e3a9f90bdd9 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -53,6 +53,10 @@ struct tegra_ulpi_config {
int (*post_phy_off)(void);
void (*phy_restore_start)(void);
void (*phy_restore_end)(void);
+ int phy_restore_gpio; /* null phy restore ack from device */
+ int ulpi_dir_gpio; /* ulpi dir */
+ int ulpi_d0_gpio; /* usb linestate[0] */
+ int ulpi_d1_gpio; /* usb linestate[1] */
};
struct tegra_uhsic_config {
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 532bf73c10d1..9ba8b68297ea 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -33,12 +33,8 @@
#include <mach/usb_phy.h>
#include <mach/iomap.h>
#include <mach/pinmux.h>
-#include "gpio-names.h"
#include "fuse.h"
-/* Modem hibernate test parameters */
-#define TRIGGER_BY_MDM2AP_ACK 1
-/* ------------------------------- */
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
#define USB_USBCMD 0x140
@@ -1846,9 +1842,9 @@ static inline void null_phy_set_tristate(bool enable)
int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
#else
tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate);
tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate);
@@ -1868,54 +1864,62 @@ static inline void null_phy_set_tristate(bool enable)
static void null_phy_restore_start(struct tegra_usb_phy *phy,
enum tegra_usb_phy_port_speed port_speed)
{
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
struct tegra_ulpi_config *config = phy->config;
if (config->phy_restore_start)
config->phy_restore_start();
-#endif
}
static void null_phy_restore_end(struct tegra_usb_phy *phy)
{
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
unsigned long val;
void __iomem *base = phy->regs;
struct tegra_ulpi_config *config = phy->config;
- int retry = 20000;
/* disable ULPI pinmux bypass */
ulpi_pinmux_bypass(phy, false);
/* driving linestate using GPIO */
- gpio_set_value(TEGRA_GPIO_PO1, 0);
- gpio_set_value(TEGRA_GPIO_PO2, 0);
+ gpio_set_value(config->ulpi_d0_gpio, 0);
+ gpio_set_value(config->ulpi_d1_gpio, 0);
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ /* driving DIR high */
+ gpio_set_value(config->ulpi_dir_gpio, 1);
+#endif
- /* remove ULPI tristate except DIR */
+ /* remove ULPI tristate */
null_phy_set_tristate(false);
if (config->phy_restore_end)
config->phy_restore_end();
- while (retry) {
-#if TRIGGER_BY_MDM2AP_ACK
- if (gpio_get_value(TEGRA_GPIO_PU5)) /* poll MDM2AP_ACK high */
- break;
-#else
- if (gpio_get_value(TEGRA_GPIO_PY3)) /* poll STP high */
- break;
-#endif
- retry--;
- }
+ if (gpio_is_valid(config->phy_restore_gpio)) {
+ int phy_restore_gpio = config->phy_restore_gpio;
+ int retry = 20000;
- if (retry == 0)
- pr_info("MDM2AP_ACK timeout\n");
+ while (retry) {
+ /* poll phy_restore_gpio high */
+ if (gpio_get_value(phy_restore_gpio))
+ break;
+ retry--;
+ }
+
+ if (retry == 0)
+ pr_info("phy_restore_gpio timeout\n");
+ }
/* enable ULPI CLK output pad */
val = readl(base + ULPI_TIMING_CTRL_0);
val |= ULPI_CLK_PADOUT_ENA;
writel(val, base + ULPI_TIMING_CTRL_0);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ udelay(5); /* wait for CLK stabilize */
+
+ /* enable ULPI pinmux bypass */
+ ulpi_pinmux_bypass(phy, true);
+#else
/* enable ULPI pinmux bypass */
ulpi_pinmux_bypass(phy, true);
udelay(5);
@@ -1960,8 +1964,13 @@ static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
/* set timming parameters */
val = readl(base + ULPI_TIMING_CTRL_0);
val |= ULPI_SHADOW_CLK_LOOPBACK_EN;
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
val &= ~ULPI_SHADOW_CLK_SEL;
val &= ~ULPI_LBK_PAD_EN;
+#else
+ val |= ULPI_SHADOW_CLK_SEL;
+ val |= ULPI_LBK_PAD_EN;
+#endif
val |= ULPI_SHADOW_CLK_DELAY(config->trimmer->shadow_clk_delay);
val |= ULPI_CLOCK_OUT_DELAY(config->trimmer->clock_out_delay);
val |= ULPI_LBK_PAD_E_INPUT_OR;