aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorPavankumar Kondeti <pkondeti@codeaurora.org>2011-05-04 00:49:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-06 21:27:49 -0400
commit04aebcbb1b6dccadc8862b2765265f65a946db57 (patch)
tree33996708dc4e3fdfd1d8bc12157f2e22e54520ff /drivers/usb
parent11aa5c478e743712228ff2da881b85100800c1ee (diff)
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/otg/msm_otg.c64
1 files changed, 54 insertions, 10 deletions
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 628ba7d943da..1cdda6c05238 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -163,6 +163,32 @@ put_3p3:
163 return rc; 163 return rc;
164} 164}
165 165
166#ifdef CONFIG_PM_SLEEP
167#define USB_PHY_SUSP_DIG_VOL 500000
168static int msm_hsusb_config_vddcx(int high)
169{
170 int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
171 int min_vol;
172 int ret;
173
174 if (high)
175 min_vol = USB_PHY_VDD_DIG_VOL_MIN;
176 else
177 min_vol = USB_PHY_SUSP_DIG_VOL;
178
179 ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
180 if (ret) {
181 pr_err("%s: unable to set the voltage for regulator "
182 "HSUSB_VDDCX\n", __func__);
183 return ret;
184 }
185
186 pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
187
188 return ret;
189}
190#endif
191
166static int msm_hsusb_ldo_set_mode(int on) 192static int msm_hsusb_ldo_set_mode(int on)
167{ 193{
168 int ret = 0; 194 int ret = 0;
@@ -434,27 +460,28 @@ static int msm_otg_suspend(struct msm_otg *motg)
434 460
435 disable_irq(motg->irq); 461 disable_irq(motg->irq);
436 /* 462 /*
463 * Chipidea 45-nm PHY suspend sequence:
464 *
437 * Interrupt Latch Register auto-clear feature is not present 465 * Interrupt Latch Register auto-clear feature is not present
438 * in all PHY versions. Latch register is clear on read type. 466 * in all PHY versions. Latch register is clear on read type.
439 * Clear latch register to avoid spurious wakeup from 467 * Clear latch register to avoid spurious wakeup from
440 * low power mode (LPM). 468 * low power mode (LPM).
441 */ 469 *
442 ulpi_read(otg, 0x14);
443
444 /*
445 * PHY comparators are disabled when PHY enters into low power 470 * PHY comparators are disabled when PHY enters into low power
446 * mode (LPM). Keep PHY comparators ON in LPM only when we expect 471 * mode (LPM). Keep PHY comparators ON in LPM only when we expect
447 * VBUS/Id notifications from USB PHY. Otherwise turn off USB 472 * VBUS/Id notifications from USB PHY. Otherwise turn off USB
448 * PHY comparators. This save significant amount of power. 473 * PHY comparators. This save significant amount of power.
449 */ 474 *
450 if (pdata->otg_control == OTG_PHY_CONTROL)
451 ulpi_write(otg, 0x01, 0x30);
452
453 /*
454 * PLL is not turned off when PHY enters into low power mode (LPM). 475 * PLL is not turned off when PHY enters into low power mode (LPM).
455 * Disable PLL for maximum power savings. 476 * Disable PLL for maximum power savings.
456 */ 477 */
457 ulpi_write(otg, 0x08, 0x09); 478
479 if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) {
480 ulpi_read(otg, 0x14);
481 if (pdata->otg_control == OTG_PHY_CONTROL)
482 ulpi_write(otg, 0x01, 0x30);
483 ulpi_write(otg, 0x08, 0x09);
484 }
458 485
459 /* 486 /*
460 * PHY may take some time or even fail to enter into low power 487 * 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)
485 */ 512 */
486 writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); 513 writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD);
487 514
515 if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
516 motg->pdata->otg_control == OTG_PMIC_CONTROL)
517 writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL);
518
488 clk_disable(motg->pclk); 519 clk_disable(motg->pclk);
489 clk_disable(motg->clk); 520 clk_disable(motg->clk);
490 if (motg->core_clk) 521 if (motg->core_clk)
@@ -493,6 +524,12 @@ static int msm_otg_suspend(struct msm_otg *motg)
493 if (!IS_ERR(motg->pclk_src)) 524 if (!IS_ERR(motg->pclk_src))
494 clk_disable(motg->pclk_src); 525 clk_disable(motg->pclk_src);
495 526
527 if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
528 motg->pdata->otg_control == OTG_PMIC_CONTROL) {
529 msm_hsusb_ldo_set_mode(0);
530 msm_hsusb_config_vddcx(0);
531 }
532
496 if (device_may_wakeup(otg->dev)) 533 if (device_may_wakeup(otg->dev))
497 enable_irq_wake(motg->irq); 534 enable_irq_wake(motg->irq);
498 if (bus) 535 if (bus)
@@ -524,6 +561,13 @@ static int msm_otg_resume(struct msm_otg *motg)
524 if (motg->core_clk) 561 if (motg->core_clk)
525 clk_enable(motg->core_clk); 562 clk_enable(motg->core_clk);
526 563
564 if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
565 motg->pdata->otg_control == OTG_PMIC_CONTROL) {
566 msm_hsusb_ldo_set_mode(1);
567 msm_hsusb_config_vddcx(1);
568 writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL);
569 }
570
527 temp = readl(USB_USBCMD); 571 temp = readl(USB_USBCMD);
528 temp &= ~ASYNC_INTR_CTRL; 572 temp &= ~ASYNC_INTR_CTRL;
529 temp &= ~ULPI_STP_CTRL; 573 temp &= ~ULPI_STP_CTRL;