summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorMichael Hsu <mhsu@nvidia.com>2011-04-26 15:43:37 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-05-03 01:32:27 -0700
commit9793e01b35cdf6b683b36f45177786c42b820fc4 (patch)
tree936d4575d113bf737e1b00fada1131d9a048acb8 /arch/arm
parent77347c04a1f0ae286c09e5bbf726f5d5746e51e5 (diff)
arm: tegra: hsic: Enable T30 HSIC
Modified cardhu board config for ehci2 to use HSIC. Need to turn on 6416 IO expander gpio for VDDIO_HSIC. Otherwise, VDDIO_HSIC would be 0 Volts. Fix HSIC register differences between T20 / T30. Change-Id: I03079d4691981c8bc5fa220720aa55de507e6f04 Reviewed-on: http://git-master/r/29428 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c22
-rw-r--r--arch/arm/mach-tegra/board-cardhu.h5
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h1
-rw-r--r--arch/arm/mach-tegra/usb_phy.c167
4 files changed, 152 insertions, 43 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 01b232a5673c..5d3219b4fa8d 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -434,6 +434,17 @@ static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
},
};
+static struct tegra_ulpi_config uhsic_phy_config = {
+ .enable_gpio = EN_HSIC_GPIO,
+ .reset_gpio = PM267_SMSC4640_HSIC_HUB_RESET_GPIO,
+};
+
+static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = {
+ .phy_type = TEGRA_USB_PHY_TYPE_HSIC,
+ .phy_config = &uhsic_phy_config,
+ .operating_mode = TEGRA_USB_HOST,
+ .power_down_on_bus_suspend = 1,
+};
static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
[0] = {
@@ -507,15 +518,22 @@ static struct tegra_otg_platform_data tegra_otg_pdata = {
static void cardhu_usb_init(void)
{
+ struct board_info bi;
+
+ tegra_get_board_info(&bi);
+
tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata));
tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
platform_device_register(&tegra_otg_device);
- tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1];
+ if ((bi.board_id == BOARD_PM267) || (bi.board_id == BOARD_E1186)) {
+ tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata;
+ } else {
+ tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1];
+ }
platform_device_register(&tegra_ehci2_device);
-
tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2];
platform_device_register(&tegra_ehci3_device);
diff --git a/arch/arm/mach-tegra/board-cardhu.h b/arch/arm/mach-tegra/board-cardhu.h
index 0978159a8e9d..ae32baaa00a3 100644
--- a/arch/arm/mach-tegra/board-cardhu.h
+++ b/arch/arm/mach-tegra/board-cardhu.h
@@ -28,6 +28,7 @@
#define BOARD_E1186 0x0B56
#define BOARD_E1198 0x0B62
#define BOARD_E1291 0x0C5B
+#define BOARD_PM267 0x0243
#define BOARD_PM269 0x0245
/* External peripheral act as gpio */
@@ -64,6 +65,10 @@
#define PMU_TCA6416_GPIO_PORT17 (PMU_TCA6416_GPIO_BASE + 15)
#define PMU_TCA6416_GPIO_END (PMU_TCA6416_GPIO_BASE + 16)
+/* PMU_TCA6416 GPIO assignment */
+#define EN_HSIC_GPIO PMU_TCA6416_GPIO_PORT11 /* PMU_GPIO25 */
+#define PM267_SMSC4640_HSIC_HUB_RESET_GPIO PMU_TCA6416_GPIO_PORT17 /* PMU_GPIO31 */
+
/* CAM_TCA6416 GPIOs */
#define CAM_TCA6416_GPIO_BASE PMU_TCA6416_GPIO_END
#define CAM1_PWR_DN_GPIO CAM_TCA6416_GPIO_BASE + 0
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index 25b2ccabd64b..26139e81d2ea 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -41,6 +41,7 @@ struct tegra_ulpi_trimmer {
};
struct tegra_ulpi_config {
+ int enable_gpio;
int reset_gpio;
const char *clk;
const struct tegra_ulpi_trimmer *trimmer;
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 3225b78c44fc..bdd5cd6eb3a4 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -142,7 +142,48 @@
#define UTMIP_BIAS_CFG1 0x83c
#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
-#else
+#define UHSIC_PLL_CFG1 0x804
+#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
+#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14)
+
+#define UHSIC_HSRX_CFG0 0x808
+#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2)
+#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8)
+#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13)
+
+#define UHSIC_HSRX_CFG1 0x80c
+#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
+
+#define UHSIC_MISC_CFG0 0x814
+#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7)
+#define UHSIC_DETECT_SHORT_CONNECT (1 << 8)
+#define UHSIC_FORCE_XCVR_MODE (1 << 15)
+
+#define UHSIC_MISC_CFG1 0X818
+#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2)
+
+#define UHSIC_PADS_CFG0 0x81c
+#define UHSIC_TX_RTUNEN 0xf000
+#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12)
+
+#define UHSIC_PADS_CFG1 0x820
+#define UHSIC_PD_BG (1 << 2)
+#define UHSIC_PD_TX (1 << 3)
+#define UHSIC_PD_TRK (1 << 4)
+#define UHSIC_PD_RX (1 << 5)
+#define UHSIC_PD_ZI (1 << 6)
+#define UHSIC_RX_SEL (1 << 7)
+#define UHSIC_RPD_DATA (1 << 9)
+#define UHSIC_RPD_STROBE (1 << 10)
+#define UHSIC_RPU_DATA (1 << 11)
+#define UHSIC_RPU_STROBE (1 << 12)
+
+#define UHSIC_STAT_CFG0 0x828
+#define UHSIC_CONNECT_DETECT (1 << 0)
+
+
+#else /* T30 definitions */
+
#define USB_USBCMD 0x130
#define USB_USBCMD_RS (1 << 0)
@@ -243,7 +284,12 @@
#define HOSTPC1_DEVLC 0x1b4
#define HOSTPC1_DEVLC_PHCD (1 << 22)
#define HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29)
+#define HOSTPC1_DEVLC_PTS_MASK 7
+#define HOSTPC1_DEVLC_PTS_HSIC 4
#define HOSTPC1_DEVLC_STS (1 << 28)
+#define HOSTPC1_DEVLC_PSPD(x) (((x) & 0x3) << 25)
+#define HOSTPC1_DEVLC_PSPD_MASK 3
+#define HOSTPC1_DEVLC_PSPD_HIGH_SPEED 2
#define TEGRA_USB_USBMODE_REG_OFFSET 0x1f8
#define TEGRA_USB_USBMODE_HOST (3 << 0)
@@ -253,8 +299,49 @@
#define TEGRA_PMC_USB_AO_ID_PD_P0 (1 << 3)
#define ICUSB_CTRL 0x15c
+
+#define UHSIC_PLL_CFG1 0xc04
+#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
+#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14)
+
+#define UHSIC_HSRX_CFG0 0xc08
+#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2)
+#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8)
+#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13)
+
+#define UHSIC_HSRX_CFG1 0xc0c
+#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
+
+#define UHSIC_MISC_CFG0 0xc14
+#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7)
+#define UHSIC_DETECT_SHORT_CONNECT (1 << 8)
+#define UHSIC_FORCE_XCVR_MODE (1 << 15)
+
+#define UHSIC_MISC_CFG1 0xc18
+#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2)
+
+#define UHSIC_PADS_CFG0 0xc1c
+#define UHSIC_TX_RTUNEN 0xf000
+#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12)
+
+#define UHSIC_PADS_CFG1 0xc20
+#define UHSIC_PD_BG (1 << 2)
+#define UHSIC_PD_TX (1 << 3)
+#define UHSIC_PD_TRK (1 << 4)
+#define UHSIC_PD_RX (1 << 5)
+#define UHSIC_PD_ZI (1 << 6)
+#define UHSIC_RX_SEL (1 << 7)
+#define UHSIC_RPD_DATA (1 << 9)
+#define UHSIC_RPD_STROBE (1 << 10)
+#define UHSIC_RPU_DATA (1 << 11)
+#define UHSIC_RPU_STROBE (1 << 12)
+
+#define UHSIC_STAT_CFG0 0xc28
+#define UHSIC_CONNECT_DETECT (1 << 0)
#endif
+/* Common registers */
+
#define ULPIS2S_CTRL 0x418
#define ULPIS2S_ENA (1 << 0)
#define ULPIS2S_SUPPORT_DISCONNECT (1 << 2)
@@ -295,51 +382,12 @@
#define UHSIC_PLL_CFG0 0x800
-#define UHSIC_PLL_CFG1 0x804
-#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
-#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14)
-
-#define UHSIC_HSRX_CFG0 0x808
-#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2)
-#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8)
-#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13)
-
-#define UHSIC_HSRX_CFG1 0x80c
-#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
-
#define UHSIC_TX_CFG0 0x810
#define UHSIC_HS_POSTAMBLE_OUTPUT_ENABLE (1 << 6)
-#define UHSIC_MISC_CFG0 0x814
-#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7)
-#define UHSIC_DETECT_SHORT_CONNECT (1 << 8)
-#define UHSIC_FORCE_XCVR_MODE (1 << 15)
-
-#define UHSIC_MISC_CFG1 0X818
-#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2)
-
-#define UHSIC_PADS_CFG0 0x81c
-#define UHSIC_TX_RTUNEN 0xf000
-#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12)
-
-#define UHSIC_PADS_CFG1 0x820
-#define UHSIC_PD_BG (1 << 2)
-#define UHSIC_PD_TX (1 << 3)
-#define UHSIC_PD_TRK (1 << 4)
-#define UHSIC_PD_RX (1 << 5)
-#define UHSIC_PD_ZI (1 << 6)
-#define UHSIC_RX_SEL (1 << 7)
-#define UHSIC_RPD_DATA (1 << 9)
-#define UHSIC_RPD_STROBE (1 << 10)
-#define UHSIC_RPU_DATA (1 << 11)
-#define UHSIC_RPU_STROBE (1 << 12)
-
#define UHSIC_CMD_CFG0 0x824
#define UHSIC_PRETEND_CONNECT_DETECT (1 << 5)
-#define UHSIC_STAT_CFG0 0x828
-#define UHSIC_CONNECT_DETECT (1 << 0)
-
#define UHSIC_SPARE_CFG0 0x82c
@@ -1287,6 +1335,7 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
val &= ~(UHSIC_RESET);
writel(val, base + USB_SUSP_CTRL);
udelay(2);
+
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
val = readl(base + USB_PORTSC1);
val &= ~USB_PORTSC1_PTS(~0);
@@ -1443,10 +1492,32 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
tegra_gpio_enable(ulpi_config->reset_gpio);
gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
gpio_direction_output(ulpi_config->reset_gpio, 0);
-
phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
phy->ulpi->io_priv = regs + ULPI_VIEWPORT;
}
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
+ ulpi_config = config;
+ gpio_request(ulpi_config->enable_gpio,
+ "uhsic_enable");
+ gpio_request(ulpi_config->reset_gpio,
+ "uhsic_reset");
+ /* hsic enable signal deasserted, hsic reset asserted */
+ gpio_direction_output(ulpi_config->enable_gpio,
+ 0 /* deasserted */);
+ gpio_direction_output(ulpi_config->reset_gpio,
+ 0 /* asserted */);
+ tegra_gpio_enable(ulpi_config->enable_gpio);
+ tegra_gpio_enable(ulpi_config->reset_gpio);
+ /* keep hsic reset asserted for 1 ms */
+ udelay(1000);
+ /* enable (power on) hsic */
+ gpio_set_value_cansleep(ulpi_config->enable_gpio, 1);
+ udelay(1000);
+ /* deassert reset */
+ gpio_set_value_cansleep(ulpi_config->reset_gpio, 1);
+ }
+#endif
phy->reg_vdd = regulator_get(NULL, "avdd_usb");
if (WARN_ON(IS_ERR_OR_NULL(phy->reg_vdd))) {
@@ -1623,8 +1694,18 @@ int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy)
{
unsigned long val;
void __iomem *base = phy->regs;
+ struct tegra_ulpi_config *config = phy->config;
if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ /* Change the USB controller PHY type to HSIC */
+ val = readl(base + HOSTPC1_DEVLC);
+ val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK);
+ val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
+ val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
+ val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
+ writel(val, base + HOSTPC1_DEVLC);
+#endif
val = readl(base + UHSIC_MISC_CFG0);
val |= UHSIC_DETECT_SHORT_CONNECT;
writel(val, base + UHSIC_MISC_CFG0);
@@ -1636,7 +1717,9 @@ int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy)
val = readl(base + UHSIC_PADS_CFG1);
val &= ~UHSIC_RPD_STROBE;
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
val |= UHSIC_RPU_STROBE;
+#endif
writel(val, base + UHSIC_PADS_CFG1);
if (utmi_wait_register(base + UHSIC_STAT_CFG0, UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT) < 0) {
@@ -1661,6 +1744,7 @@ int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
void __iomem *base = phy->regs;
if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
val = readl(base + USB_PORTSC1);
val |= USB_PORTSC1_PTC(5);
writel(val, base + USB_PORTSC1);
@@ -1670,6 +1754,7 @@ int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
val &= ~USB_PORTSC1_PTC(~0);
writel(val, base + USB_PORTSC1);
udelay(2);
+#endif
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(0), 0) < 0) {