Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 982bc860 authored by Vamsi Krishna Samavedam's avatar Vamsi Krishna Samavedam
Browse files

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: default avatarVamsi Krishna Samavedam <vskrishn@codeaurora.org>
parent 4e2a8a0f
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -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;