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;
|
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)
|
static int msm_hsusb_ldo_set_mode(int on)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -434,27 +460,28 @@ static int msm_otg_suspend(struct msm_otg *motg)
|
||||||
|
|
||||||
disable_irq(motg->irq);
|
disable_irq(motg->irq);
|
||||||
/*
|
/*
|
||||||
|
* Chipidea 45-nm PHY suspend sequence:
|
||||||
|
*
|
||||||
* Interrupt Latch Register auto-clear feature is not present
|
* Interrupt Latch Register auto-clear feature is not present
|
||||||
* in all PHY versions. Latch register is clear on read type.
|
* in all PHY versions. Latch register is clear on read type.
|
||||||
* Clear latch register to avoid spurious wakeup from
|
* Clear latch register to avoid spurious wakeup from
|
||||||
* low power mode (LPM).
|
* low power mode (LPM).
|
||||||
*/
|
*
|
||||||
ulpi_read(otg, 0x14);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PHY comparators are disabled when PHY enters into low power
|
* PHY comparators are disabled when PHY enters into low power
|
||||||
* mode (LPM). Keep PHY comparators ON in LPM only when we expect
|
* mode (LPM). Keep PHY comparators ON in LPM only when we expect
|
||||||
* VBUS/Id notifications from USB PHY. Otherwise turn off USB
|
* VBUS/Id notifications from USB PHY. Otherwise turn off USB
|
||||||
* PHY comparators. This save significant amount of power.
|
* 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).
|
* PLL is not turned off when PHY enters into low power mode (LPM).
|
||||||
* Disable PLL for maximum power savings.
|
* 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
|
* 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);
|
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->pclk);
|
||||||
clk_disable(motg->clk);
|
clk_disable(motg->clk);
|
||||||
if (motg->core_clk)
|
if (motg->core_clk)
|
||||||
|
@ -493,6 +524,12 @@ static int msm_otg_suspend(struct msm_otg *motg)
|
||||||
if (!IS_ERR(motg->pclk_src))
|
if (!IS_ERR(motg->pclk_src))
|
||||||
clk_disable(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))
|
if (device_may_wakeup(otg->dev))
|
||||||
enable_irq_wake(motg->irq);
|
enable_irq_wake(motg->irq);
|
||||||
if (bus)
|
if (bus)
|
||||||
|
@ -524,6 +561,13 @@ static int msm_otg_resume(struct msm_otg *motg)
|
||||||
if (motg->core_clk)
|
if (motg->core_clk)
|
||||||
clk_enable(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 = readl(USB_USBCMD);
|
||||||
temp &= ~ASYNC_INTR_CTRL;
|
temp &= ~ASYNC_INTR_CTRL;
|
||||||
temp &= ~ULPI_STP_CTRL;
|
temp &= ~ULPI_STP_CTRL;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define USB_PORTSC (MSM_USB_BASE + 0x0184)
|
#define USB_PORTSC (MSM_USB_BASE + 0x0184)
|
||||||
#define USB_OTGSC (MSM_USB_BASE + 0x01A4)
|
#define USB_OTGSC (MSM_USB_BASE + 0x01A4)
|
||||||
#define USB_USBMODE (MSM_USB_BASE + 0x01A8)
|
#define USB_USBMODE (MSM_USB_BASE + 0x01A8)
|
||||||
|
#define USB_PHY_CTRL (MSM_USB_BASE + 0x0240)
|
||||||
|
|
||||||
#define USBCMD_RESET 2
|
#define USBCMD_RESET 2
|
||||||
#define USB_USBINTR (MSM_USB_BASE + 0x0148)
|
#define USB_USBINTR (MSM_USB_BASE + 0x0148)
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
|
|
||||||
#define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */
|
#define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */
|
||||||
#define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */
|
#define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */
|
||||||
|
#define PHY_RETEN (1 << 1) /* PHY retention enable/disable */
|
||||||
|
|
||||||
/* OTG definitions */
|
/* OTG definitions */
|
||||||
#define OTGSC_INTSTS_MASK (0x7f << 16)
|
#define OTGSC_INTSTS_MASK (0x7f << 16)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче