usb: phy: qusb: Reset clock mux to avoid leakage on vdd rail
Reset the clock mux when cable is disconnected and suspended to avoid leakage on vdd rail. Also, add missing clock reset when usb cable connect is notified. Change-Id: If5485379934a222f19f5dd20b8d4f44769470e8d Signed-off-by: Vamsi Krishna Samavedam <vskrishn@codeaurora.org>
This commit is contained in:
parent
4e2a8a0fa1
commit
982bc86081
1 changed files with 23 additions and 1 deletions
|
@ -63,6 +63,7 @@
|
|||
#define LINESTATE_DM BIT(1)
|
||||
|
||||
#define QUSB2PHY_PLL_ANALOG_CONTROLS_ONE 0x0
|
||||
#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x4
|
||||
|
||||
unsigned int phy_tune1;
|
||||
module_param(phy_tune1, uint, S_IRUGO | S_IWUSR);
|
||||
|
@ -541,6 +542,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
|
|||
{
|
||||
struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
|
||||
u32 linestate = 0, intr_mask = 0;
|
||||
static u8 analog_ctrl_two;
|
||||
int ret;
|
||||
|
||||
if (qphy->suspended && suspend) {
|
||||
|
@ -554,6 +556,14 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
|
|||
if (qphy->cable_connected ||
|
||||
(qphy->phy.flags & PHY_HOST_MODE)) {
|
||||
|
||||
/* store clock settings like cmos/cml */
|
||||
analog_ctrl_two =
|
||||
readl_relaxed(qphy->base +
|
||||
QUSB2PHY_PLL_ANALOG_CONTROLS_TWO);
|
||||
|
||||
writel_relaxed(0x1b,
|
||||
qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO);
|
||||
|
||||
/* enable clock bypass */
|
||||
writel_relaxed(0x90,
|
||||
qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_ONE);
|
||||
|
@ -599,6 +609,9 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
|
|||
dev_err(phy->dev, "%s: phy_reset deassert failed\n",
|
||||
__func__);
|
||||
|
||||
writel_relaxed(0x1b,
|
||||
qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO);
|
||||
|
||||
/* enable clock bypass */
|
||||
writel_relaxed(0x90,
|
||||
qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_ONE);
|
||||
|
@ -620,6 +633,10 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
|
|||
(qphy->phy.flags & PHY_HOST_MODE)) {
|
||||
qusb_phy_enable_clocks(qphy, true);
|
||||
|
||||
/* restore the default clock settings */
|
||||
writel_relaxed(analog_ctrl_two,
|
||||
qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO);
|
||||
|
||||
/* disable clock bypass */
|
||||
writel_relaxed(0x80,
|
||||
qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_ONE);
|
||||
|
@ -639,12 +656,17 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
|
|||
*/
|
||||
wmb();
|
||||
|
||||
qusb_phy_enable_power(qphy, true, true);
|
||||
ret = reset_control_assert(qphy->phy_reset);
|
||||
if (ret)
|
||||
dev_err(phy->dev, "%s: phy_reset assert failed\n",
|
||||
__func__);
|
||||
usleep_range(100, 150);
|
||||
ret = reset_control_deassert(qphy->phy_reset);
|
||||
if (ret)
|
||||
dev_err(phy->dev, "%s: phy_reset deassert failed\n",
|
||||
__func__);
|
||||
|
||||
qusb_phy_enable_power(qphy, true, true);
|
||||
qusb_phy_enable_clocks(qphy, true);
|
||||
}
|
||||
qphy->suspended = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue