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

Commit 505af1fb authored by Xiaozhe Shi's avatar Xiaozhe Shi Committed by Mayank Rana
Browse files

usb: phy: qusb: Make sure to have expected pulse width



In some cases it is observed that request to generate pulse with
DP/DM line is being schedule out due to usage of usleep_range()
which results into bigger pulse width (bigger than 20ms) than
expected (minimum 20us and max 20ms). Bigger pulse width results
into over voltage condition with charger. Hence fix this issue
by using spinlock to complete pulse generation operation atomically.

Change-Id: Iad6e3deb034b3cf30972d762b55643bd47a2ccf9
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 85125f66
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ struct qusb_phy {
	int			phy_pll_reset_seq_len;
	int			*emu_dcm_reset_seq;
	int			emu_dcm_reset_seq_len;
	spinlock_t		pulse_lock;
};

static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
@@ -303,9 +304,11 @@ err_vdd:
	return ret;
}

#define PHY_PULSE_TIME_USEC		250
static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
{
	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
	unsigned long flags;
	int ret = 0;
	u32 reg;

@@ -369,7 +372,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
		break;

	case POWER_SUPPLY_DP_DM_DP0P6_DM3P3:
		dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DP0P6_DM3P3\n");
		dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DP0PHVDCP_36_DM3P3\n");
		/* Set DP to 0.6v */
		writel_relaxed(VDP_SRC_EN, qphy->base + QUSB2PHY_PORT_QC1);
		/* Set DM to 3.075v */
@@ -381,7 +384,8 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)

	case POWER_SUPPLY_DP_DM_DP_PULSE:
		dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DP_PULSE\n");
		/*Set DP to 3.075v, sleep 2-3ms */
		spin_lock_irqsave(&qphy->pulse_lock, flags);
		/*Set DP to 3.075v, sleep for .25 ms */
		reg = readl_relaxed(qphy->base + QUSB2PHY_PORT_QC2);
		reg |= (RDP_UP_EN | RPUP_LOW_EN);
		writel_relaxed(reg, qphy->base + QUSB2PHY_PORT_QC2);
@@ -393,7 +397,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
		 * It is recommended to wait here to get voltage change on
		 * DP/DM line.
		 */
		usleep_range(2000, 3000);
		udelay(PHY_PULSE_TIME_USEC);

		 /* Set DP to 0.6v, sleep 2-3ms */
		reg = readl_relaxed(qphy->base + QUSB2PHY_PORT_QC1);
@@ -405,6 +409,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
		writel_relaxed(reg, qphy->base + QUSB2PHY_PORT_QC2);
		/* complete above write */
		mb();
		spin_unlock_irqrestore(&qphy->pulse_lock, flags);
		/*
		 * It is recommended to wait here to get voltage change on
		 * DP/DM line.
@@ -414,7 +419,8 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)

	case POWER_SUPPLY_DP_DM_DM_PULSE:
		dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DM_PULSE\n");
		/* Set DM to 0.6v, sleep 2-3ms */
		spin_lock_irqsave(&qphy->pulse_lock, flags);
		/* Set DM to 0.6v, sleep .25 ms */
		reg = readl_relaxed(qphy->base + QUSB2PHY_PORT_QC1);
		reg |= VDM_SRC_EN;
		writel_relaxed(reg, qphy->base + QUSB2PHY_PORT_QC1);
@@ -430,7 +436,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
		 * It is recommended to wait here to get voltage change on
		 * DP/DM line.
		 */
		usleep_range(2000, 3000);
		udelay(PHY_PULSE_TIME_USEC);

		/* DM to 3.075v, sleep 2-3ms */
		reg = readl_relaxed(qphy->base + QUSB2PHY_PORT_QC2);
@@ -443,6 +449,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)

		/* complete above write */
		mb();
		spin_unlock_irqrestore(&qphy->pulse_lock, flags);

		/*
		 * It is recommended to wait here to get voltage change on
@@ -815,6 +822,7 @@ static int qusb_phy_probe(struct platform_device *pdev)
		return -ENOMEM;

	qphy->phy.dev = dev;
	spin_lock_init(&qphy->pulse_lock);

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"qusb_phy_base");