summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra11x_usb_phy.c
diff options
context:
space:
mode:
authorVenu Byravarasu <vbyravarasu@nvidia.com>2012-10-26 16:50:15 +0530
committerSimone Willett <swillett@nvidia.com>2012-11-06 18:12:32 -0800
commitc2958491e5a392be8f52824d59eabadb34b82060 (patch)
tree1aa9d8a6afa2dde71bed13e1ba085ed18c895746 /arch/arm/mach-tegra/tegra11x_usb_phy.c
parentb712909c11b9d18b8634d1b89e3b1e71a966695e (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.c775
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;
}