Loading Documentation/devicetree/bindings/usb/msm-hsusb.txt +3 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading drivers/usb/phy/phy-msm-usb.c +39 −4 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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); } Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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) Loading Loading @@ -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); Loading include/linux/usb/msm_hsusb.h +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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) Loading Loading
Documentation/devicetree/bindings/usb/msm-hsusb.txt +3 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading
drivers/usb/phy/phy-msm-usb.c +39 −4 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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); } Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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) Loading Loading @@ -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); Loading
include/linux/usb/msm_hsusb.h +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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) Loading