USB: OTG: msm: Add PHY suspend support for MSM8960
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
11aa5c478e
Коммит
04aebcbb1b
|
@ -163,6 +163,32 @@ put_3p3:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#define USB_PHY_SUSP_DIG_VOL 500000
|
||||
static int msm_hsusb_config_vddcx(int high)
|
||||
{
|
||||
int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
|
||||
int min_vol;
|
||||
int ret;
|
||||
|
||||
if (high)
|
||||
min_vol = USB_PHY_VDD_DIG_VOL_MIN;
|
||||
else
|
||||
min_vol = USB_PHY_SUSP_DIG_VOL;
|
||||
|
||||
ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
|
||||
if (ret) {
|
||||
pr_err("%s: unable to set the voltage for regulator "
|
||||
"HSUSB_VDDCX\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int msm_hsusb_ldo_set_mode(int on)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -434,27 +460,28 @@ static int msm_otg_suspend(struct msm_otg *motg)
|
|||
|
||||
disable_irq(motg->irq);
|
||||
/*
|
||||
* Chipidea 45-nm PHY suspend sequence:
|
||||
*
|
||||
* Interrupt Latch Register auto-clear feature is not present
|
||||
* in all PHY versions. Latch register is clear on read type.
|
||||
* Clear latch register to avoid spurious wakeup from
|
||||
* low power mode (LPM).
|
||||
*/
|
||||
ulpi_read(otg, 0x14);
|
||||
|
||||
/*
|
||||
*
|
||||
* PHY comparators are disabled when PHY enters into low power
|
||||
* mode (LPM). Keep PHY comparators ON in LPM only when we expect
|
||||
* VBUS/Id notifications from USB PHY. Otherwise turn off USB
|
||||
* PHY comparators. This save significant amount of power.
|
||||
*/
|
||||
if (pdata->otg_control == OTG_PHY_CONTROL)
|
||||
ulpi_write(otg, 0x01, 0x30);
|
||||
|
||||
/*
|
||||
*
|
||||
* PLL is not turned off when PHY enters into low power mode (LPM).
|
||||
* Disable PLL for maximum power savings.
|
||||
*/
|
||||
ulpi_write(otg, 0x08, 0x09);
|
||||
|
||||
if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) {
|
||||
ulpi_read(otg, 0x14);
|
||||
if (pdata->otg_control == OTG_PHY_CONTROL)
|
||||
ulpi_write(otg, 0x01, 0x30);
|
||||
ulpi_write(otg, 0x08, 0x09);
|
||||
}
|
||||
|
||||
/*
|
||||
* PHY may take some time or even fail to enter into low power
|
||||
|
@ -485,6 +512,10 @@ static int msm_otg_suspend(struct msm_otg *motg)
|
|||
*/
|
||||
writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD);
|
||||
|
||||
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
|
||||
motg->pdata->otg_control == OTG_PMIC_CONTROL)
|
||||
writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL);
|
||||
|
||||
clk_disable(motg->pclk);
|
||||
clk_disable(motg->clk);
|
||||
if (motg->core_clk)
|
||||
|
@ -493,6 +524,12 @@ static int msm_otg_suspend(struct msm_otg *motg)
|
|||
if (!IS_ERR(motg->pclk_src))
|
||||
clk_disable(motg->pclk_src);
|
||||
|
||||
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
|
||||
motg->pdata->otg_control == OTG_PMIC_CONTROL) {
|
||||
msm_hsusb_ldo_set_mode(0);
|
||||
msm_hsusb_config_vddcx(0);
|
||||
}
|
||||
|
||||
if (device_may_wakeup(otg->dev))
|
||||
enable_irq_wake(motg->irq);
|
||||
if (bus)
|
||||
|
@ -524,6 +561,13 @@ static int msm_otg_resume(struct msm_otg *motg)
|
|||
if (motg->core_clk)
|
||||
clk_enable(motg->core_clk);
|
||||
|
||||
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
|
||||
motg->pdata->otg_control == OTG_PMIC_CONTROL) {
|
||||
msm_hsusb_ldo_set_mode(1);
|
||||
msm_hsusb_config_vddcx(1);
|
||||
writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL);
|
||||
}
|
||||
|
||||
temp = readl(USB_USBCMD);
|
||||
temp &= ~ASYNC_INTR_CTRL;
|
||||
temp &= ~ULPI_STP_CTRL;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define USB_PORTSC (MSM_USB_BASE + 0x0184)
|
||||
#define USB_OTGSC (MSM_USB_BASE + 0x01A4)
|
||||
#define USB_USBMODE (MSM_USB_BASE + 0x01A8)
|
||||
#define USB_PHY_CTRL (MSM_USB_BASE + 0x0240)
|
||||
|
||||
#define USBCMD_RESET 2
|
||||
#define USB_USBINTR (MSM_USB_BASE + 0x0148)
|
||||
|
@ -42,6 +43,7 @@
|
|||
|
||||
#define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */
|
||||
#define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */
|
||||
#define PHY_RETEN (1 << 1) /* PHY retention enable/disable */
|
||||
|
||||
/* OTG definitions */
|
||||
#define OTGSC_INTSTS_MASK (0x7f << 16)
|
||||
|
|
Загрузка…
Ссылка в новой задаче