diff options
author | Michael Hsu <mhsu@nvidia.com> | 2011-04-26 15:43:37 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-05-03 01:32:27 -0700 |
commit | 9793e01b35cdf6b683b36f45177786c42b820fc4 (patch) | |
tree | 936d4575d113bf737e1b00fada1131d9a048acb8 /arch/arm | |
parent | 77347c04a1f0ae286c09e5bbf726f5d5746e51e5 (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.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/usb_phy.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/usb_phy.c | 167 |
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) { |