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

Commit a6037aef authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Saket Saurabh
Browse files

usb: phy: msm: Add support for vdd min without phy retention



As a part of usb disconnect, usb will be put into low power mode
by putting phy into retention, voting for xo shutdown and vdd
minimization, also turning off LDOs. But on 8x10 platform,turning
off regulators is causing leakage current due to hardware limitation.
Hence add support for vdd minimization without putting phy into
retention to prevent power consumption. Also disable id pull up
as recommended by hardware team.

Change-Id: I2eeffde361b11b481d0bd4506882195c80b012ce
Signed-off-by: default avatarSaket Saurabh <ssaurabh@codeaurora.org>
parent abedad47
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@ Optional properties :
	runs using PNOC clock and synchronous to it. Hence it is must to have proper
	"qcom,msm_bus,vectors" to have high bus frequency. User shouldn't try to
	enable this feature without proper bus voting.
- qti,disable-retention-with-vdd-min: If present don't allow phy retention but allow
	vdd min.

Example HSUSB OTG controller device node :
	usb@f9690000 {
@@ -132,6 +134,7 @@ Example HSUSB OTG controller device node :
				<87 512 60000000 960000000>;
		qcom,hsusb-otg-vddmin-gpio = <&pm8019_mpps 6 0>;
		qcom,hsusb-otg-rw-during-lpm-workaround = <1>;
		qti,disable-retention-with-vdd-min;
	};

MSM HSUSB EHCI controller
+39 −4
Original line number Diff line number Diff line
@@ -631,6 +631,10 @@ static int msm_otg_reset(struct usb_phy *phy)
		pm8xxx_usb_id_pullup(1);
	}

	if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)
		writel_relaxed(readl_relaxed(USB_OTGSC) & ~(OTGSC_IDPU),
								USB_OTGSC);

	return 0;
}

@@ -891,6 +895,7 @@ static int msm_otg_suspend(struct msm_otg *motg)
	u32 phy_ctrl_val = 0, cmd_val;
	unsigned ret;
	u32 portsc, config2;
	u32 func_ctrl;

	if (atomic_read(&motg->in_lpm))
		return 0;
@@ -958,6 +963,15 @@ static int msm_otg_suspend(struct msm_otg *motg)
		ulpi_write(phy, 0x08, 0x09);
	}

	if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED) {
		/* put the controller in non-driving mode */
		func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL);
		func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
		func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
		ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL);
		ulpi_write(phy, ULPI_IFC_CTRL_AUTORESUME,
						ULPI_CLR(ULPI_IFC_CTRL));
	}

	/* Set the PHCD bit, only if it is not set by the controller.
	 * PHY may take some time or even fail to enter into low power
@@ -1023,9 +1037,14 @@ static int msm_otg_suspend(struct msm_otg *motg)
		}
		if (host_bus_suspend)
			phy_ctrl_val |= PHY_CLAMP_DPDMSE_EN;

		if (!(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
			writel_relaxed(phy_ctrl_val & ~PHY_RETEN,
						motg->usb_phy_ctrl_reg);
			motg->lpm_flags |= PHY_RETENTIONED;
		} else {
			writel_relaxed(phy_ctrl_val, motg->usb_phy_ctrl_reg);
		}
	} else if (device_bus_suspend && !dcp &&
			(pdata->mpm_dpshv_int || pdata->mpm_dmshv_int)) {
		/* DP DM HV interrupts are used for bus resume from XO off */
@@ -1088,7 +1107,8 @@ static int msm_otg_suspend(struct msm_otg *motg)
		motg->lpm_flags |= PHY_REGULATORS_LPM;
	}

	if (motg->lpm_flags & PHY_RETENTIONED) {
	if (motg->lpm_flags & PHY_RETENTIONED ||
		(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
		msm_hsusb_config_vddcx(0);
		msm_hsusb_mhl_switch_enable(motg, 0);
	}
@@ -1147,6 +1167,7 @@ static int msm_otg_resume(struct msm_otg *motg)
	bool in_device_mode;
	bool bus_is_suspended;
	bool is_remote_wakeup;
	u32 func_ctrl;

	if (!atomic_read(&motg->in_lpm))
		return 0;
@@ -1190,7 +1211,8 @@ static int msm_otg_resume(struct msm_otg *motg)
		motg->lpm_flags &= ~PHY_REGULATORS_LPM;
	}

	if (motg->lpm_flags & PHY_RETENTIONED) {
	if (motg->lpm_flags & PHY_RETENTIONED ||
		(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
		msm_hsusb_mhl_switch_enable(motg, 1);
		msm_hsusb_config_vddcx(1);
		phy_ctrl_val = readl_relaxed(motg->usb_phy_ctrl_reg);
@@ -1270,6 +1292,14 @@ static int msm_otg_resume(struct msm_otg *motg)
	}

skip_phy_resume:
	if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED) {
		/* put the controller in normal mode */
		func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL);
		func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
		func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
		ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL);
	}

	if (device_may_wakeup(phy->dev)) {
		if (motg->async_irq)
			disable_irq_wake(motg->async_irq);
@@ -4292,6 +4322,8 @@ struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev)
				"qcom,hsusb-l1-supported");
	pdata->enable_ahb2ahb_bypass = of_property_read_bool(node,
				"qcom,ahb-async-bridge-bypass");
	pdata->disable_retention_with_vdd_min = of_property_read_bool(node,
				"qti,disable-retention-with-vdd-min");

	res_gpio = of_get_named_gpio(node, "qcom,hsusb-otg-vddmin-gpio", 0);
	if (res_gpio < 0)
@@ -4711,6 +4743,9 @@ static int __init msm_otg_probe(struct platform_device *pdev)
	if (motg->pdata->enable_lpm_on_dev_suspend)
		motg->caps |= ALLOW_LPM_ON_DEV_SUSPEND;

	if (motg->pdata->disable_retention_with_vdd_min)
		motg->caps |= ALLOW_VDD_MIN_WITH_RETENTION_DISABLED;

	wake_lock(&motg->wlock);
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
+8 −0
Original line number Diff line number Diff line
@@ -238,6 +238,8 @@ enum usb_vdd_value {
 *		applied.
 * @enable_ahb2ahb_bypass: Indicates whether enable AHB2AHB BYPASS
 *		mode with controller in device mode.
 * @bool disable_retention_with_vdd_min: Indicates whether to enable
		allowing VDDmin without putting PHY into retention.
 */
struct msm_otg_platform_data {
	int *phy_init_seq;
@@ -269,6 +271,7 @@ struct msm_otg_platform_data {
	int vddmin_gpio;
	bool rw_during_lpm_workaround;
	bool enable_ahb2ahb_bypass;
	bool disable_retention_with_vdd_min;
};

/* phy related flags */
@@ -443,6 +446,11 @@ struct msm_otg {
	 * voltage regulator(VDDCX) during host mode.
	 */
#define ALLOW_HOST_PHY_RETENTION	BIT(4)
	/*
	* Allow VDD minimization without putting PHY into retention
	* for fixing PHY current leakage issue when LDOs ar turned off.
	*/
#define ALLOW_VDD_MIN_WITH_RETENTION_DISABLED BIT(5)
	unsigned long lpm_flags;
#define PHY_PWR_COLLAPSED		BIT(0)
#define PHY_RETENTIONED			BIT(1)