diff options
author | Venu Byravarasu <vbyravarasu@nvidia.com> | 2012-10-26 16:50:15 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-11-06 18:12:32 -0800 |
commit | c2958491e5a392be8f52824d59eabadb34b82060 (patch) | |
tree | 1aa9d8a6afa2dde71bed13e1ba085ed18c895746 /arch/arm/mach-tegra/tegra11x_usb_phy.c | |
parent | b712909c11b9d18b8634d1b89e3b1e71a966695e (diff) |
arm: tegra: Separating out pmc from usb phy.
Taking out PMC from Tegra11x USB phy driver.
This would facilitate in having common PMC interface between XUSB and USB.
Change-Id: I695ac2794ff8324d73e3ed8e679ad5da54593fd4
Signed-off-by: Venu Byravarasu <vbyravarasu@nvidia.com>
Reviewed-on: http://git-master/r/147480
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra11x_usb_phy.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra11x_usb_phy.c | 775 |
1 files changed, 127 insertions, 648 deletions
diff --git a/arch/arm/mach-tegra/tegra11x_usb_phy.c b/arch/arm/mach-tegra/tegra11x_usb_phy.c index a20ea34912c9..1d137b4ca7e0 100644 --- a/arch/arm/mach-tegra/tegra11x_usb_phy.c +++ b/arch/arm/mach-tegra/tegra11x_usb_phy.c @@ -35,6 +35,7 @@ #include "tegra_usb_phy.h" #include "gpio-names.h" #include "fuse.h" +#include "tegra_usb_pmc.h" #define USB_USBCMD 0x130 #define USB_USBCMD_RS (1 << 0) @@ -58,35 +59,6 @@ #define ICUSB_CTRL 0x15c -#define USB_PORTSC 0x174 -#define USB_PORTSC_PHCD (1 << 23) -#define USB_PORTSC_WKOC (1 << 22) -#define USB_PORTSC_WKDS (1 << 21) -#define USB_PORTSC_WKCN (1 << 20) -#define USB_PORTSC_PTC(x) (((x) & 0xf) << 16) -#define USB_PORTSC_PP (1 << 12) -#define USB_PORTSC_LS(x) (((x) & 0x3) << 10) -#define USB_PORTSC_SUSP (1 << 7) -#define USB_PORTSC_RESUME (1 << 6) -#define USB_PORTSC_OCC (1 << 5) -#define USB_PORTSC_PEC (1 << 3) -#define USB_PORTSC_PE (1 << 2) -#define USB_PORTSC_CSC (1 << 1) -#define USB_PORTSC_CCS (1 << 0) -#define USB_PORTSC_RWC_BITS (USB_PORTSC_CSC | USB_PORTSC_PEC | USB_PORTSC_OCC) -#define USB_PORTSC_PSPD_MASK 3 - -#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 HOSTPC1_DEVLC_NYT_ASUS 1 - #define USB_USBMODE 0x1f8 #define USB_USBMODE_MASK (3 << 0) #define USB_USBMODE_HOST (3 << 0) @@ -227,16 +199,10 @@ #define FUSE_SETUP_SEL (1 << 3) #define FUSE_ATERM_SEL (1 << 4) -#define UTMIP_PMC_WAKEUP0 0x84c -#define UHSIC_PMC_WAKEUP0 0xc34 -#define EVENT_INT_ENB (1 << 0) - #define UTMIP_BIAS_STS0 0x840 #define UTMIP_RCTRL_VAL(x) (((x) & 0xffff) << 0) #define UTMIP_TCTRL_VAL(x) (((x) & (0xffff << 16)) >> 16) -#define UHSIC_INST(inst, x, y) ((inst == 1) ? x : y) - #define UHSIC_PLL_CFG1 0xc04 #define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) #define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14) @@ -282,13 +248,6 @@ #define UHSIC_STAT_CFG0 0xc28 #define UHSIC_CONNECT_DETECT (1 << 0) -#define PMC_UHSIC_TRIGGERS(inst) UHSIC_INST(inst, 0x1ec, 0x27c) -#define UHSIC_CLR_WALK_PTR(inst) (1 << UHSIC_INST(inst, 3, 0)) -#define UHSIC_CLR_WAKE_ALARM(inst) (1 << UHSIC_INST(inst, 15, 3)) - -#define PMC_UHSIC_SLEEPWALK_CFG(inst) UHSIC_INST(inst, 0x200, 0x288) -#define UHSIC_LINEVAL_WALK_EN(inst) (1 << UHSIC_INST(inst, 31, 7)) - #define UHSIC_STATUS(inst) UHSIC_INST(inst, 0x214, 0x290) #define UHSIC_WAKE_ALARM(inst) (1 << UHSIC_INST(inst, 19, 4)) #define UHSIC_WALK_PTR_VAL(inst) (0x3 << UHSIC_INST(inst, 6, 0)) @@ -298,134 +257,8 @@ #define UHSIC_CMD_CFG0 0xc24 #define UHSIC_PRETEND_CONNECT_DETECT (1 << 5) -#define PMC_UHSIC_SLEEP_CFG(inst) UHSIC_INST(inst, 0x1fc, 0x284) -#define UHSIC_MASTER_ENABLE(inst) (1 << UHSIC_INST(inst, 24, 0)) -#define UHSIC_WAKE_VAL(inst, x) (((x) & 0xf) << UHSIC_INST(inst, 28, 4)) -#define WAKE_VAL_SD10 0x2 - #define USB_USBINTR 0x138 -#define PMC_UHSIC_MASTER_CONFIG(inst) UHSIC_INST(inst, 0x274, 0x29c) -#define UHSIC_PWR(inst) (1 << UHSIC_INST(inst, 3, 0)) - -#define PMC_UHSIC_FAKE(inst) UHSIC_INST(inst, 0x218, 0x294) -#define UHSIC_FAKE_STROBE_VAL(inst) (1 << UHSIC_INST(inst, 12, 0)) -#define UHSIC_FAKE_DATA_VAL(inst) (1 << UHSIC_INST(inst, 13, 1)) - -#define PMC_SLEEPWALK_UHSIC(inst) UHSIC_INST(inst, 0x210, 0x28c) -#define UHSIC_STROBE_RPD_A (1 << 0) -#define UHSIC_DATA_RPD_A (1 << 1) -#define UHSIC_STROBE_RPU_A (1 << 2) -#define UHSIC_DATA_RPU_A (1 << 3) -#define UHSIC_STROBE_RPD_B (1 << 8) -#define UHSIC_DATA_RPD_B (1 << 9) -#define UHSIC_STROBE_RPU_B (1 << 10) -#define UHSIC_DATA_RPU_B (1 << 11) -#define UHSIC_STROBE_RPD_C (1 << 16) -#define UHSIC_DATA_RPD_C (1 << 17) -#define UHSIC_STROBE_RPU_C (1 << 18) -#define UHSIC_DATA_RPU_C (1 << 19) -#define UHSIC_STROBE_RPD_D (1 << 24) -#define UHSIC_DATA_RPD_D (1 << 25) -#define UHSIC_STROBE_RPU_D (1 << 26) -#define UHSIC_DATA_RPU_D (1 << 27) -#define UHSIC_LINE_DEB_CNT(x) (((x) & 0xf) << 20) - -#define PMC_USB_DEBOUNCE 0xec -#define UTMIP_LINE_DEB_CNT(x) (((x) & 0xf) << 16) - -#define PMC_USB_AO 0xf0 -#define HSIC_RESERVED(inst) (3 << UHSIC_INST(inst, 14, 18)) -#define STROBE_VAL_PD(inst) (1 << UHSIC_INST(inst, 12, 16)) -#define DATA_VAL_PD(inst) (1 << UHSIC_INST(inst, 13, 17)) -#define PMC_POWER_DOWN_MASK 0xffff -#define USB_ID_PD(inst) (1 << ((4*(inst))+3)) -#define VBUS_WAKEUP_PD(inst) (1 << ((4*(inst))+2)) -#define USBON_VAL_PD(inst) (1 << ((4*(inst))+1)) -#define USBON_VAL_PD_P2 (1 << 9) -#define USBON_VAL_PD_P1 (1 << 5) -#define USBON_VAL_PD_P0 (1 << 1) -#define USBOP_VAL_PD(inst) (1 << (4*(inst))) -#define USBOP_VAL_PD_P2 (1 << 8) -#define USBOP_VAL_PD_P1 (1 << 4) -#define USBOP_VAL_PD_P0 (1 << 0) -#define PMC_USB_AO_PD_P2 (0xf << 8) -#define PMC_USB_AO_ID_PD_P0 (1 << 3) -#define PMC_USB_AO_VBUS_WAKEUP_PD_P0 (1 << 2) - -#define PMC_TRIGGERS 0x1ec -#define UTMIP_CLR_WALK_PTR(inst) (1 << (inst)) -#define UTMIP_CLR_WALK_PTR_P2 (1 << 2) -#define UTMIP_CLR_WALK_PTR_P1 (1 << 1) -#define UTMIP_CLR_WALK_PTR_P0 (1 << 0) -#define UTMIP_CAP_CFG(inst) (1 << ((inst)+4)) -#define UTMIP_CAP_CFG_P2 (1 << 6) -#define UTMIP_CAP_CFG_P1 (1 << 5) -#define UTMIP_CAP_CFG_P0 (1 << 4) -#define UTMIP_CLR_WAKE_ALARM(inst) (1 << ((inst)+12)) -#define UTMIP_CLR_WAKE_ALARM_P2 (1 << 14) - -#define PMC_PAD_CFG (0x1f4) - -#define PMC_UTMIP_TERM_PAD_CFG 0x1f8 -#define PMC_TCTRL_VAL(x) (((x) & 0x1f) << 5) -#define PMC_RCTRL_VAL(x) (((x) & 0x1f) << 0) - -#define PMC_SLEEP_CFG 0x1fc -#define UTMIP_TCTRL_USE_PMC(inst) (1 << ((8*(inst))+3)) -#define UTMIP_TCTRL_USE_PMC_P2 (1 << 19) -#define UTMIP_TCTRL_USE_PMC_P1 (1 << 11) -#define UTMIP_TCTRL_USE_PMC_P0 (1 << 3) -#define UTMIP_RCTRL_USE_PMC(inst) (1 << ((8*(inst))+2)) -#define UTMIP_RCTRL_USE_PMC_P2 (1 << 18) -#define UTMIP_RCTRL_USE_PMC_P1 (1 << 10) -#define UTMIP_RCTRL_USE_PMC_P0 (1 << 2) -#define UTMIP_FSLS_USE_PMC(inst) (1 << ((8*(inst))+1)) -#define UTMIP_FSLS_USE_PMC_P2 (1 << 17) -#define UTMIP_FSLS_USE_PMC_P1 (1 << 9) -#define UTMIP_FSLS_USE_PMC_P0 (1 << 1) -#define UTMIP_MASTER_ENABLE(inst) (1 << (8*(inst))) -#define UTMIP_MASTER_ENABLE_P2 (1 << 16) -#define UTMIP_MASTER_ENABLE_P1 (1 << 8) -#define UTMIP_MASTER_ENABLE_P0 (1 << 0) - -#define PMC_SLEEPWALK_CFG 0x200 -#define UTMIP_LINEVAL_WALK_EN(inst) (1 << ((8*(inst))+7)) -#define UTMIP_LINEVAL_WALK_EN_P2 (1 << 23) -#define UTMIP_LINEVAL_WALK_EN_P1 (1 << 15) -#define UTMIP_LINEVAL_WALK_EN_P0 (1 << 7) -#define UTMIP_WAKE_VAL(inst, x) (((x) & 0xf) << ((8*(inst))+4)) -#define UTMIP_WAKE_VAL_P2(x) (((x) & 0xf) << 20) -#define UTMIP_WAKE_VAL_P1(x) (((x) & 0xf) << 12) -#define UTMIP_WAKE_VAL_P0(x) (((x) & 0xf) << 4) -#define WAKE_VAL_NONE 0xc -#define WAKE_VAL_ANY 0xF -#define WAKE_VAL_FSJ 0x2 -#define WAKE_VAL_FSK 0x1 -#define WAKE_VAL_SE0 0x0 - -#define PMC_SLEEPWALK_REG(inst) (0x204 + (4*(inst))) -#define UTMIP_USBOP_RPD_A (1 << 0) -#define UTMIP_USBON_RPD_A (1 << 1) -#define UTMIP_AP_A (1 << 4) -#define UTMIP_AN_A (1 << 5) -#define UTMIP_HIGHZ_A (1 << 6) -#define UTMIP_USBOP_RPD_B (1 << 8) -#define UTMIP_USBON_RPD_B (1 << 9) -#define UTMIP_AP_B (1 << 12) -#define UTMIP_AN_B (1 << 13) -#define UTMIP_HIGHZ_B (1 << 14) -#define UTMIP_USBOP_RPD_C (1 << 16) -#define UTMIP_USBON_RPD_C (1 << 17) -#define UTMIP_AP_C (1 << 20) -#define UTMIP_AN_C (1 << 21) -#define UTMIP_HIGHZ_C (1 << 22) -#define UTMIP_USBOP_RPD_D (1 << 24) -#define UTMIP_USBON_RPD_D (1 << 25) -#define UTMIP_AP_D (1 << 28) -#define UTMIP_AN_D (1 << 29) -#define UTMIP_HIGHZ_D (1 << 30) - #define UTMIP_STATUS 0x214 #define UTMIP_WALK_PTR_VAL(inst) (0x3 << ((inst)*2)) #define UTMIP_USBOP_VAL(inst) (1 << ((2*(inst)) + 8)) @@ -449,22 +282,6 @@ #define USB2_PREFETCH_ID 18 #define USB3_PREFETCH_ID 17 -#define PMC_UTMIP_FAKE 0x218 -#define USBON_VAL(inst) (1 << ((4*(inst))+1)) -#define USBON_VAL_P2 (1 << 9) -#define USBON_VAL_P1 (1 << 5) -#define USBON_VAL_P0 (1 << 1) -#define USBOP_VAL(inst) (1 << (4*(inst))) -#define USBOP_VAL_P2 (1 << 8) -#define USBOP_VAL_P1 (1 << 4) -#define USBOP_VAL_P0 (1 << 0) - -#define PMC_UTMIP_BIAS_MASTER_CNTRL 0x270 -#define BIAS_MASTER_PROG_VAL (1 << 1) - -#define PMC_UTMIP_MASTER_CONFIG 0x274 -#define UTMIP_PWR(inst) (1 << (inst)) - #define FUSE_USB_CALIB_0 0x1F0 #define XCVR_SETUP(x) (((x) & 0x7F) << 0) #define XCVR_SETUP_LSB_MASK 0xF @@ -490,25 +307,13 @@ /* Force port resume wait time in micro second on remote resume */ #define FPR_WAIT_TIME_US 25000 -#ifdef DEBUG -#define DBG(stuff...) pr_info("tegra11x_usb_phy: " stuff) -#else -#define DBG(stuff...) do {} while (0) -#endif - -#if 0 -#define PHY_DBG(stuff...) pr_info("tegra11x_usb_phy: " stuff) -#else -#define PHY_DBG(stuff...) do {} while (0) -#endif - /* define HSIC phy params */ #define HSIC_SYNC_START_DELAY 9 #define HSIC_IDLE_WAIT_DELAY 17 #define HSIC_ELASTIC_UNDERRUN_LIMIT 16 #define HSIC_ELASTIC_OVERRUN_LIMIT 16 -static u32 utmip_rctrl_val, utmip_tctrl_val; +struct tegra_usb_pmc_data pmc_data[3]; static DEFINE_SPINLOCK(utmip_pad_lock); static int utmip_pad_count; @@ -582,6 +387,22 @@ static struct tegra_xtal_freq uhsic_freq_table[] = { }, }; +static int is_port_connected(struct tegra_usb_phy *phy) +{ + void __iomem *base = phy->regs; + + /* check for port connect status */ + return (readl(base + USB_PORTSC) & USB_PORTSC_CCS) ? 0 : -ENXIO; +} + +static void pmc_init(struct tegra_usb_phy *phy) +{ + pmc_data[phy->inst].instance = phy->inst; + pmc_data[phy->inst].phy_type = phy->pdata->phy_intf; + pmc_data[phy->inst].controller_type = TEGRA_USB_2_0; + tegra_usb_pmc_init(&pmc_data[phy->inst]); +} + static int _usb_phy_init(struct tegra_usb_phy *phy) { unsigned long val; @@ -642,188 +463,6 @@ static int usb_phy_reset(struct tegra_usb_phy *phy) return 0; } -static void utmip_setup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val, pmc_pad_cfg_val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->inst; - void __iomem *base = phy->regs; - bool port_connected; - enum usb_phy_port_speed port_speed; - - DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - - /* check for port connect status */ - val = readl(base + USB_PORTSC); - port_connected = val & USB_PORTSC_CCS; - - if (!port_connected) - return; - - port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) & - HOSTPC1_DEVLC_PSPD_MASK; - /*Set PMC MASTER bits to do the following - * a. Take over the UTMI drivers - * b. set up such that it will take over resume - * if remote wakeup is detected - * Prepare PMC to take over suspend-wake detect-drive resume until USB - * controller ready - */ - - /* disable master enable in PMC */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_SLEEP_CFG); - - /* UTMIP_PWR_PX=1 for power savings mode */ - val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); - val |= UTMIP_PWR(inst); - writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); - - /* config debouncer */ - val = readl(pmc_base + PMC_USB_DEBOUNCE); - val &= ~UTMIP_LINE_DEB_CNT(~0); - val |= UTMIP_LINE_DEB_CNT(4); - writel(val, pmc_base + PMC_USB_DEBOUNCE); - - /* Make sure nothing is happening on the line with respect to PMC */ - val = readl(pmc_base + PMC_UTMIP_FAKE); - val &= ~USBOP_VAL(inst); - val &= ~USBON_VAL(inst); - writel(val, pmc_base + PMC_UTMIP_FAKE); - - /* Make sure wake value for line is none */ - val = readl(pmc_base + PMC_SLEEPWALK_CFG); - val &= ~UTMIP_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_SLEEPWALK_CFG); - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, ~0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_SLEEP_CFG); - - /* turn off pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - /* Remove fake values and make synchronizers work a bit */ - val = readl(pmc_base + PMC_UTMIP_FAKE); - val &= ~USBOP_VAL(inst); - val &= ~USBON_VAL(inst); - writel(val, pmc_base + PMC_UTMIP_FAKE); - - /* Enable which type of event can trigger a walk, - * in this case usb_line_wake */ - val = readl(pmc_base + PMC_SLEEPWALK_CFG); - val |= UTMIP_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_SLEEPWALK_CFG); - - /* Capture FS/LS pad configurations */ - pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG); - val = readl(pmc_base + PMC_TRIGGERS); - val |= UTMIP_CAP_CFG(inst); - writel(val, pmc_base + PMC_TRIGGERS); - udelay(1); - pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG); - - /* BIAS MASTER_ENABLE=0 */ - val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - val &= ~BIAS_MASTER_PROG_VAL; - writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - - /* program walk sequence, maintain a J, followed by a driven K - * to signal a resume once an wake event is detected */ - val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); - val &= ~UTMIP_AP_A; - val |= UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_AN_A |UTMIP_HIGHZ_A | - UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_AP_B | UTMIP_AN_B | - UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_AP_C | UTMIP_AN_C | - UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_AP_D | UTMIP_AN_D; - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - - if (port_speed == USB_PHY_PORT_SPEED_LOW) { - val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); - val &= ~(UTMIP_AN_B | UTMIP_HIGHZ_B | UTMIP_AN_C | - UTMIP_HIGHZ_C | UTMIP_AN_D | UTMIP_HIGHZ_D); - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - } else { - val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); - val &= ~(UTMIP_AP_B | UTMIP_HIGHZ_B | UTMIP_AP_C | - UTMIP_HIGHZ_C | UTMIP_AP_D | UTMIP_HIGHZ_D); - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - } - - /* turn on pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val &= ~(USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - /* Add small delay before usb detectors provide stable line values */ - mdelay(1); - - /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ - val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); - val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); - writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); - - phy->remote_wakeup = false; - - /* Turn over pad configuration to PMC for line wake events*/ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, ~0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_ANY); - val |= UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst); - val |= UTMIP_MASTER_ENABLE(inst) | UTMIP_FSLS_USE_PMC(inst); - writel(val, pmc_base + PMC_SLEEP_CFG); - - val = readl(base + UTMIP_PMC_WAKEUP0); - val |= EVENT_INT_ENB; - writel(val, base + UTMIP_PMC_WAKEUP0); - PHY_DBG("%s ENABLE_PMC inst = %d\n", __func__, inst); -} - -static void utmip_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->inst; - void __iomem *base = phy->regs; - - DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, 0xF); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_SLEEP_CFG); - - val = readl(base + UTMIP_PMC_WAKEUP0); - val &= ~EVENT_INT_ENB; - writel(val, base + UTMIP_PMC_WAKEUP0); - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | - UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst)); - writel(val, pmc_base + PMC_SLEEP_CFG); - - val = readl(pmc_base + PMC_TRIGGERS); - val &= ~UTMIP_CAP_CFG(inst); - writel(val, pmc_base + PMC_TRIGGERS); - - /* turn off pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - val = readl(pmc_base + PMC_TRIGGERS); - val |= UTMIP_CLR_WALK_PTR(inst); - val |= UTMIP_CLR_WAKE_ALARM(inst); - writel(val, pmc_base + PMC_TRIGGERS); - - phy->remote_wakeup = false; - PHY_DBG("%s DISABLE_PMC inst = %d\n", __func__, inst); -} - static bool utmi_phy_remotewake_detected(struct tegra_usb_phy *phy) { void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); @@ -907,8 +546,8 @@ static void utmi_phy_enable_trking_data(struct tegra_usb_phy *phy) /* Read RCTRL and TCTRL from UTMIP space */ val = readl(base + UTMIP_BIAS_STS0); - utmip_rctrl_val = ffz(UTMIP_RCTRL_VAL(val)); - utmip_tctrl_val = ffz(UTMIP_TCTRL_VAL(val)); + pmc_data[phy->inst].utmip_rctrl_val = ffz(UTMIP_RCTRL_VAL(val)); + pmc_data[phy->inst].utmip_tctrl_val = ffz(UTMIP_TCTRL_VAL(val)); /* PD_TRK=1 */ val = readl(base + UTMIP_BIAS_CFG1); @@ -917,62 +556,13 @@ static void utmi_phy_enable_trking_data(struct tegra_usb_phy *phy) /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); - val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); + val = PMC_TCTRL_VAL(pmc_data[phy->inst].utmip_tctrl_val) | + PMC_RCTRL_VAL(pmc_data[phy->inst].utmip_rctrl_val); writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); clk_disable(phy->utmi_pad_clk); init_done = true; } -static void utmip_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->inst; - - /* power down UTMIP interfaces */ - val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); - val |= UTMIP_PWR(inst); - writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); - - /* setup sleep walk usb controller */ - val = UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_HIGHZ_A | - UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_HIGHZ_B | - UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_HIGHZ_C | - UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_HIGHZ_D; - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - - /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ - val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); - val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); - writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); - - /* Turn over pad configuration to PMC */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, ~0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE) | - UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | - UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_SLEEP_CFG); - PHY_DBG("%s ENABLE_PMC inst = %d\n", __func__, inst); -} - -static void utmip_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->inst; - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | - UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst)); - writel(val, pmc_base + PMC_SLEEP_CFG); - mdelay(1); - PHY_DBG("%s DISABLE_PMC inst = %d\n", __func__, inst); -} - - - static int usb_phy_bringup_host_controller(struct tegra_usb_phy *phy) { unsigned long val; @@ -1129,6 +719,7 @@ static int utmi_phy_open(struct tegra_usb_phy *phy) pr_err("%s: can't get utmip pad clock\n", __func__); return PTR_ERR(phy->utmi_pad_clk); } + pmc_init(phy); phy->utmi_xcvr_setup = utmi_phy_xcvr_setup_value(phy); @@ -1149,7 +740,7 @@ static int utmi_phy_open(struct tegra_usb_phy *phy) val &= ~(PMC_USB_AO_VBUS_WAKEUP_PD_P0 | PMC_USB_AO_ID_PD_P0); writel((val | PMC_USB_AO_PD_P2), (pmc_base + PMC_USB_AO)); - utmip_powerup_pmc_wake_detect(phy); + pmc_data[phy->inst].pmc_ops->powerup_pmc_wake_detect(&pmc_data[phy->inst]); return 0; } @@ -1291,12 +882,19 @@ static int utmi_phy_post_resume(struct tegra_usb_phy *phy) unsigned long val; void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); unsigned int inst = phy->inst; + void __iomem *base = phy->regs; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); val = readl(pmc_base + PMC_SLEEP_CFG); /* if PMC is not disabled by now then disable it */ if (val & UTMIP_MASTER_ENABLE(inst)) { - utmip_phy_disable_pmc_bus_ctrl(phy); + + val = readl(base + UTMIP_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; } return 0; @@ -1307,12 +905,19 @@ static int utmi_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) unsigned long val; void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); unsigned int inst = phy->inst; + void __iomem *base = phy->regs; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); val = readl(pmc_base + PMC_SLEEP_CFG); if (val & UTMIP_MASTER_ENABLE(inst)) { - if (!remote_wakeup) - utmip_phy_disable_pmc_bus_ctrl(phy); + if (!remote_wakeup) { + val = readl(base + UTMIP_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; + } } return 0; @@ -1322,6 +927,7 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) { unsigned long val; void __iomem *base = phy->regs; + int ret; PHY_DBG("%s(%d) inst:[%d] BEGIN\n", __func__, __LINE__, phy->inst); if (!phy->phy_clk_on) { @@ -1331,7 +937,7 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) } if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { - utmip_powerdown_pmc_wake_detect(phy); + pmc_data[phy->inst].pmc_ops->powerdown_pmc_wake_detect(&pmc_data[phy->inst]); val = readl(base + USB_SUSP_CTRL); val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0); @@ -1358,7 +964,19 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) pr_err("%s: timeout waiting for USB_USBSTS_HCH\n" , __func__); } - utmip_setup_pmc_wake_detect(phy); + + /* check for port connect status */ + ret = is_port_connected(phy); + if (ret) + return ret; + + pmc_data[phy->inst].pmc_ops->setup_pmc_wake_detect(&pmc_data[phy->inst]); + + val = readl(base + UTMIP_PMC_WAKEUP0); + val |= EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + PHY_DBG("%s ENABLE_PMC inst = %d\n", __func__, phy->inst); + } if (!phy->hot_plug) { @@ -1559,8 +1177,18 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) val |= HOSTPC1_DEVLC_STS; writel(val, base + HOSTPC1_DEVLC); + pmc_data[phy->inst].port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) & + HOSTPC1_DEVLC_PSPD_MASK; + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) - utmip_powerup_pmc_wake_detect(phy); + pmc_data[phy->inst].pmc_ops->powerup_pmc_wake_detect(&pmc_data[phy->inst]); + + phy->remote_wakeup = false; + + val = readl(base + UTMIP_PMC_WAKEUP0); + val |= EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + phy->phy_clk_on = true; phy->hw_accessible = true; PHY_DBG("%s(%d) End inst:[%d]\n", __func__, __LINE__, phy->inst); @@ -1572,6 +1200,7 @@ static void utmi_phy_restore_start(struct tegra_usb_phy *phy) unsigned long val; void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); int inst = phy->inst; + void __iomem *base = phy->regs; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); val = readl(pmc_base + UTMIP_STATUS); @@ -1588,8 +1217,15 @@ static void utmi_phy_restore_start(struct tegra_usb_phy *phy) phy->remote_wakeup = true; } else if (!phy->remote_wakeup) { val = readl(pmc_base + PMC_SLEEP_CFG); - if (val & UTMIP_MASTER_ENABLE(inst)) - utmip_phy_disable_pmc_bus_ctrl(phy); + if (val & UTMIP_MASTER_ENABLE(inst)) { + val = readl(base + UTMIP_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + + phy->remote_wakeup = false; + } } } @@ -1610,7 +1246,7 @@ static void utmi_phy_restore_end(struct tegra_usb_phy *phy) if (wait_time_us == 0) { PHY_DBG("%s PMC FPR" \ "timeout val = 0x%x instance = %d\n", \ - __func__, val, phy->inst); + __func__, (u32)val, phy->inst); utmi_phy_post_resume(phy); return; } @@ -1620,7 +1256,11 @@ static void utmi_phy_restore_end(struct tegra_usb_phy *phy) /* wait for 25 ms to port resume complete */ msleep(25); /* disable PMC master control */ - utmip_phy_disable_pmc_bus_ctrl(phy); + val = readl(base + UTMIP_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; /* Clear PCI and SRI bits to avoid an interrupt upon resume */ val = readl(base + USB_USBSTS); @@ -1733,203 +1373,6 @@ static bool utmi_phy_charger_detect(struct tegra_usb_phy *phy) return status; } -static void uhsic_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->inst; - - DBG("%s:%d\n", __func__, __LINE__); - - /* turn on pad detectors for HSIC*/ - val = readl(pmc_base + PMC_USB_AO); - val &= ~(HSIC_RESERVED(inst) | STROBE_VAL_PD(inst) | DATA_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~(UHSIC_MASTER_ENABLE(inst)); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - mdelay(1); -} - -static void uhsic_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->inst; - - DBG("%s:%d\n", __func__, __LINE__); - - /* turn off pad detectors for HSIC*/ - val = readl(pmc_base + PMC_USB_AO); - val |= (HSIC_RESERVED(inst) | STROBE_VAL_PD(inst) | DATA_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - /* enable pull downs on HSIC PMC */ - val = UHSIC_STROBE_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STROBE_RPD_B | - UHSIC_DATA_RPD_B | UHSIC_STROBE_RPD_C | UHSIC_DATA_RPD_C | - UHSIC_STROBE_RPD_D | UHSIC_DATA_RPD_D; - writel(val, pmc_base + PMC_SLEEPWALK_UHSIC(inst)); - - /* Turn over pad configuration to PMC */ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~UHSIC_WAKE_VAL(inst, ~0); - val |= UHSIC_WAKE_VAL(inst, WAKE_VAL_NONE) | UHSIC_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); -} - -static void uhsic_setup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - void __iomem *base = phy->regs; - bool port_connected; - unsigned int inst = phy->inst; - - DBG("%s:%d\n", __func__, __LINE__); - - /* check for port connect status */ - val = readl(base + USB_PORTSC); - port_connected = val & USB_PORTSC_CCS; - - if (!port_connected) - return; - - /*Set PMC MASTER bits to do the following - * a. Take over the hsic drivers - * b. set up such that it will take over resume - * if remote wakeup is detected - * Prepare PMC to take over suspend-wake detect-drive resume until USB - * controller ready - */ - - /* disable master enable in PMC */ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~UHSIC_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - - /* UTMIP_PWR_PX=1 for power savings mode */ - val = readl(pmc_base + PMC_UHSIC_MASTER_CONFIG(inst)); - val |= UHSIC_PWR(inst); - writel(val, pmc_base + PMC_UHSIC_MASTER_CONFIG(inst)); - - /* Make sure nothing is happening on the line with respect to PMC */ - val = readl(pmc_base + PMC_UHSIC_FAKE(inst)); - val &= ~UHSIC_FAKE_STROBE_VAL(inst); - val &= ~UHSIC_FAKE_DATA_VAL(inst); - writel(val, pmc_base + PMC_UHSIC_FAKE(inst)); - - /* Clear walk enable */ - val = readl(pmc_base + PMC_UHSIC_SLEEPWALK_CFG(inst)); - val &= ~UHSIC_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_UHSIC_SLEEPWALK_CFG(inst)); - - /* Make sure wake value for line is none */ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~UHSIC_WAKE_VAL(inst, WAKE_VAL_ANY); - val |= UHSIC_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - - /* turn on pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val &= ~(STROBE_VAL_PD(inst) | DATA_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - /* Add small delay before usb detectors provide stable line values */ - udelay(1); - - /* Enable which type of event can trigger a walk, - * in this case usb_line_wake */ - val = readl(pmc_base + PMC_UHSIC_SLEEPWALK_CFG(inst)); - val |= UHSIC_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_UHSIC_SLEEPWALK_CFG(inst)); - - /* program walk sequence, maintain a J, followed by a driven K - * to signal a resume once an wake event is detected */ - - val = readl(pmc_base + PMC_SLEEPWALK_UHSIC(inst)); - - val &= ~UHSIC_DATA_RPU_A; - val |= UHSIC_DATA_RPD_A; - val &= ~UHSIC_STROBE_RPD_A; - val |= UHSIC_STROBE_RPU_A; - - val &= ~UHSIC_DATA_RPD_B; - val |= UHSIC_DATA_RPU_B; - val &= ~UHSIC_STROBE_RPU_B; - val |= UHSIC_STROBE_RPD_B; - - val &= ~UHSIC_DATA_RPD_C; - val |= UHSIC_DATA_RPU_C; - val &= ~UHSIC_STROBE_RPU_C; - val |= UHSIC_STROBE_RPD_C; - - val &= ~UHSIC_DATA_RPD_D; - val |= UHSIC_DATA_RPU_D; - val &= ~UHSIC_STROBE_RPU_D; - val |= UHSIC_STROBE_RPD_D; - writel(val, pmc_base + PMC_SLEEPWALK_UHSIC(inst)); - - phy->remote_wakeup = false; - - /* Setting Wake event*/ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~UHSIC_WAKE_VAL(inst, WAKE_VAL_ANY); - val |= UHSIC_WAKE_VAL(inst, WAKE_VAL_SD10); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - - /* Clear the walk pointers and wake alarm */ - val = readl(pmc_base + PMC_UHSIC_TRIGGERS(inst)); - val |= UHSIC_CLR_WAKE_ALARM(inst) | UHSIC_CLR_WALK_PTR(inst); - writel(val, pmc_base + PMC_UHSIC_TRIGGERS(inst)); - - /* Turn over pad configuration to PMC for line wake events*/ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val |= UHSIC_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - - val = readl(base + UHSIC_PMC_WAKEUP0); - val |= EVENT_INT_ENB; - writel(val, base + UHSIC_PMC_WAKEUP0); - - DBG("%s:PMC enabled for HSIC remote wakeup\n", __func__); -} - -static void uhsic_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - void __iomem *base = phy->regs; - unsigned int inst = phy->inst; - - DBG("%s (%d)\n", __func__, __LINE__); - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~UHSIC_WAKE_VAL(inst, WAKE_VAL_ANY); - val |= UHSIC_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - - val = readl(base + UHSIC_PMC_WAKEUP0); - val &= ~EVENT_INT_ENB; - writel(val, base + UHSIC_PMC_WAKEUP0); - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - val &= ~(UHSIC_MASTER_ENABLE(inst)); - writel(val, pmc_base + PMC_UHSIC_SLEEP_CFG(inst)); - - /* turn off pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val |= (STROBE_VAL_PD(inst) | DATA_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - val = readl(pmc_base + PMC_UHSIC_TRIGGERS(inst)); - val |= (UHSIC_CLR_WALK_PTR(inst) | UHSIC_CLR_WAKE_ALARM(inst)); - writel(val, pmc_base + PMC_UHSIC_TRIGGERS(inst)); - - phy->remote_wakeup = false; -} - static bool uhsic_phy_remotewake_detected(struct tegra_usb_phy *phy) { void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); @@ -1990,7 +1433,13 @@ static void uhsic_phy_restore_start(struct tegra_usb_phy *phy) pr_info("%s: uhsic remote wakeup detected\n", __func__); } else { if (!((UHSIC_STROBE_VAL(inst) | UHSIC_DATA_VAL(inst)) & val)) { - uhsic_phy_disable_pmc_bus_ctrl(phy); + + val = readl(base + UHSIC_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UHSIC_PMC_WAKEUP0); + + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; } else { DBG("%s(%d): setting pretend connect\n", __func__, __LINE__); val = readl(base + UHSIC_CMD_CFG0); @@ -2016,7 +1465,12 @@ static void uhsic_phy_restore_end(struct tegra_usb_phy *phy) val = readl(base + USB_PORTSC); udelay(1); if (wait_time_us == 0) { - uhsic_phy_disable_pmc_bus_ctrl(phy); + val = readl(base + UHSIC_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UHSIC_PMC_WAKEUP0); + + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; uhsic_phy_post_resume(phy); return; } @@ -2025,8 +1479,12 @@ static void uhsic_phy_restore_end(struct tegra_usb_phy *phy) /* wait for 25 ms to port resume complete */ msleep(25); /* disable PMC master control */ - uhsic_phy_disable_pmc_bus_ctrl(phy); + val = readl(base + UHSIC_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UHSIC_PMC_WAKEUP0); + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; /* Clear PCI and SRI bits to avoid an interrupt upon resume */ val = readl(base + USB_USBSTS); writel(val, base + USB_USBSTS); @@ -2037,7 +1495,12 @@ static void uhsic_phy_restore_end(struct tegra_usb_phy *phy) } uhsic_phy_post_resume(phy); } else { - uhsic_phy_disable_pmc_bus_ctrl(phy); + val = readl(base + UHSIC_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UHSIC_PMC_WAKEUP0); + + pmc_data[phy->inst].pmc_ops->disable_pmc_bus_ctrl(&pmc_data[phy->inst]); + phy->remote_wakeup = false; } /* Set RUN bit */ @@ -2119,7 +1582,8 @@ static int uhsic_phy_open(struct tegra_usb_phy *phy) return -EINVAL; } - uhsic_powerup_pmc_wake_detect(phy); + pmc_init(phy); + pmc_data[phy->inst].pmc_ops->powerup_pmc_wake_detect(&pmc_data[phy->inst]); return 0; } @@ -2129,7 +1593,7 @@ static void uhsic_phy_close(struct tegra_usb_phy *phy) int ret; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - uhsic_powerdown_pmc_wake_detect(phy); + pmc_data[phy->inst].pmc_ops->powerdown_pmc_wake_detect(&pmc_data[phy->inst]); ret = uhsic_rail_disable(phy); if (ret < 0) @@ -2286,6 +1750,7 @@ static int uhsic_phy_power_off(struct tegra_usb_phy *phy) { unsigned long val; void __iomem *base = phy->regs; + int ret; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); if (!phy->phy_clk_on) { @@ -2298,8 +1763,22 @@ static int uhsic_phy_power_off(struct tegra_usb_phy *phy) writel(0, base + USB_USBINTR); if (phy->pmc_sleepwalk == false) { - uhsic_setup_pmc_wake_detect(phy); + + ret = is_port_connected(phy); +/* + FixMe: To be uncommented. However seen failures with + this uncommented during LP0 wakeups. + + if (ret) + return ret; +*/ + pmc_data[phy->inst].pmc_ops->setup_pmc_wake_detect(&pmc_data[phy->inst]); + phy->remote_wakeup = false; phy->pmc_sleepwalk = true; + + val = readl(base + UHSIC_PMC_WAKEUP0); + val |= EVENT_INT_ENB; + writel(val, base + UHSIC_PMC_WAKEUP0); } val = readl(base + HOSTPC1_DEVLC); @@ -3069,7 +2548,7 @@ int tegra11x_usb_phy_init_ops(struct tegra_usb_phy *phy) phy->ops = phy_ops[phy->pdata->phy_intf]; /* FIXME: uncommenting below line to make USB host mode fail*/ - /* usb_phy_power_down_pmc(); */ + /* pmc_data[phy->inst].pmc_ops->power_down_pmc(&pmc_data[phy->inst]); */ return 0; } |