Loading Documentation/devicetree/bindings/usb/msm-ssusb.txt +3 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,9 @@ Optional properties : capable DWC3 which does not have extcon handle. - qcom,default-mode-host: If present, start host mode on probe for an OTG capable DWC3 which does not have extcon handle. - qcom,no-wakeup-from-pm-suspend: If present, there is no need of SS wakeup events via pwr_event_irq in system suspend scenario. So in system suspend and hibernation, we can suspend the SSPHY. Sub nodes: - Sub node for "DWC3- USB3 controller". Loading arch/arm64/boot/dts/qcom/sa2150p-ccard.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ &usb3 { qcom,ignore-wakeup-src-in-hostmode; qcom,no-wakeup-from-pm-suspend; }; &usb3_extcon { Loading drivers/usb/dwc3/dwc3-msm.c +14 −6 Original line number Diff line number Diff line Loading @@ -333,6 +333,9 @@ struct dwc3_msm { struct device_node *dwc3_node; struct property *num_gsi_eps; /* Enable remote wakeup during system suspend */ bool enable_wakeup; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ Loading Loading @@ -2470,7 +2473,8 @@ static int dwc3_msm_update_bus_bw(struct dwc3_msm *mdwc, enum bus_vote bv) return ret; } static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse) static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse, bool enable_wakeup) { int ret; struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); Loading Loading @@ -2566,7 +2570,8 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse) ((mdwc->hs_phy->flags & (PHY_HSFS_MODE | PHY_LS_MODE)) && !dwc3_msm_is_superspeed(mdwc))); can_suspend_ssphy = dwc->maximum_speed >= USB_SPEED_SUPER && (!mdwc->use_pwr_event_for_wakeup || no_active_ss); (!mdwc->use_pwr_event_for_wakeup || no_active_ss || !enable_wakeup); /* Suspend SS PHY */ if (can_suspend_ssphy) { if (mdwc->in_host_mode) { Loading Loading @@ -3931,10 +3936,13 @@ static int dwc3_msm_probe(struct platform_device *pdev) /* * On platforms with SS PHY that do not support ss_phy_irq for wakeup * events, use pwr_event_irq for wakeup events in superspeed mode. * But some of these platforms do not need SS wakeup events in system * suspend scenario. Accommodate that case as well. */ mdwc->use_pwr_event_for_wakeup = dwc->maximum_speed >= USB_SPEED_SUPER && !mdwc->wakeup_irq[SS_PHY_IRQ].irq; mdwc->enable_wakeup = !of_property_read_bool(node, "qcom,no-wakeup-from-pm-suspend"); /* IOMMU will be reattached upon each resume/connect */ if (mdwc->iommu_map) Loading Loading @@ -4850,7 +4858,7 @@ static int dwc3_msm_pm_suspend(struct device *dev) return 0; } ret = dwc3_msm_suspend(mdwc, false); ret = dwc3_msm_suspend(mdwc, false, mdwc->enable_wakeup); if (!ret) atomic_set(&mdwc->pm_suspended, 1); Loading Loading @@ -4927,7 +4935,7 @@ static int dwc3_msm_pm_freeze(struct device *dev) * Power collapse the core. Hence call dwc3_msm_suspend with * 'force_power_collapse' set to 'true'. */ ret = dwc3_msm_suspend(mdwc, true); ret = dwc3_msm_suspend(mdwc, true, mdwc->enable_wakeup); if (!ret) atomic_set(&mdwc->pm_suspended, 1); Loading Loading @@ -4995,7 +5003,7 @@ static int dwc3_msm_runtime_suspend(struct device *dev) dev_dbg(dev, "DWC3-msm runtime suspend\n"); dbg_event(0xFF, "RT Sus", 0); return dwc3_msm_suspend(mdwc, false); return dwc3_msm_suspend(mdwc, false, false); } static int dwc3_msm_runtime_resume(struct device *dev) Loading drivers/usb/phy/phy-msm-ssusb.c +23 −10 Original line number Diff line number Diff line /* * Copyright (c) 2012-2014,2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2014,2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -63,6 +63,7 @@ struct msm_ssphy { struct clk *cfg_ahb_clk; struct clk *pipe_clk; bool clocks_enabled; bool cable_connected; struct reset_control *phy_com_reset; struct reset_control *phy_reset; Loading Loading @@ -353,23 +354,33 @@ static int msm_ssphy_set_suspend(struct usb_phy *uphy, int suspend) msm_usb_write_readback(phy->base, SS_PHY_CTRL2, REF_SS_PHY_EN, 0); msm_usb_write_readback(phy->base, SS_PHY_CTRL4, REF_USE_PAD, 0); if (!phy->cable_connected) msm_usb_write_readback(phy->base, SS_PHY_CTRL4, TEST_POWERDOWN, TEST_POWERDOWN); msm_ssusb_disable_clocks(phy); if (!phy->cable_connected) { msm_ssusb_ldo_enable(phy, 0); msm_ssusb_config_vdd(phy, 0); } phy->suspended = true; } else { if (!phy->cable_connected) { rc = msm_ssusb_config_vdd(phy, 1); if (rc) return rc; msm_ssusb_ldo_enable(phy, 1); } msm_ssusb_enable_clocks(phy); msm_usb_write_readback(phy->base, SS_PHY_CTRL4, REF_USE_PAD, REF_USE_PAD); msm_usb_write_readback(phy->base, SS_PHY_CTRL2, REF_SS_PHY_EN, REF_SS_PHY_EN); if (!phy->cable_connected) msm_usb_write_readback(phy->base, SS_PHY_CTRL4, TEST_POWERDOWN, 0); Loading @@ -384,6 +395,7 @@ static int msm_ssphy_notify_connect(struct usb_phy *uphy, { struct msm_ssphy *phy = container_of(uphy, struct msm_ssphy, phy); phy->cable_connected = true; if (uphy->flags & PHY_HOST_MODE) return 0; Loading @@ -400,6 +412,7 @@ static int msm_ssphy_notify_disconnect(struct usb_phy *uphy, { struct msm_ssphy *phy = container_of(uphy, struct msm_ssphy, phy); phy->cable_connected = false; if (uphy->flags & PHY_HOST_MODE) return 0; Loading Loading
Documentation/devicetree/bindings/usb/msm-ssusb.txt +3 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,9 @@ Optional properties : capable DWC3 which does not have extcon handle. - qcom,default-mode-host: If present, start host mode on probe for an OTG capable DWC3 which does not have extcon handle. - qcom,no-wakeup-from-pm-suspend: If present, there is no need of SS wakeup events via pwr_event_irq in system suspend scenario. So in system suspend and hibernation, we can suspend the SSPHY. Sub nodes: - Sub node for "DWC3- USB3 controller". Loading
arch/arm64/boot/dts/qcom/sa2150p-ccard.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ &usb3 { qcom,ignore-wakeup-src-in-hostmode; qcom,no-wakeup-from-pm-suspend; }; &usb3_extcon { Loading
drivers/usb/dwc3/dwc3-msm.c +14 −6 Original line number Diff line number Diff line Loading @@ -333,6 +333,9 @@ struct dwc3_msm { struct device_node *dwc3_node; struct property *num_gsi_eps; /* Enable remote wakeup during system suspend */ bool enable_wakeup; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ Loading Loading @@ -2470,7 +2473,8 @@ static int dwc3_msm_update_bus_bw(struct dwc3_msm *mdwc, enum bus_vote bv) return ret; } static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse) static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse, bool enable_wakeup) { int ret; struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); Loading Loading @@ -2566,7 +2570,8 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse) ((mdwc->hs_phy->flags & (PHY_HSFS_MODE | PHY_LS_MODE)) && !dwc3_msm_is_superspeed(mdwc))); can_suspend_ssphy = dwc->maximum_speed >= USB_SPEED_SUPER && (!mdwc->use_pwr_event_for_wakeup || no_active_ss); (!mdwc->use_pwr_event_for_wakeup || no_active_ss || !enable_wakeup); /* Suspend SS PHY */ if (can_suspend_ssphy) { if (mdwc->in_host_mode) { Loading Loading @@ -3931,10 +3936,13 @@ static int dwc3_msm_probe(struct platform_device *pdev) /* * On platforms with SS PHY that do not support ss_phy_irq for wakeup * events, use pwr_event_irq for wakeup events in superspeed mode. * But some of these platforms do not need SS wakeup events in system * suspend scenario. Accommodate that case as well. */ mdwc->use_pwr_event_for_wakeup = dwc->maximum_speed >= USB_SPEED_SUPER && !mdwc->wakeup_irq[SS_PHY_IRQ].irq; mdwc->enable_wakeup = !of_property_read_bool(node, "qcom,no-wakeup-from-pm-suspend"); /* IOMMU will be reattached upon each resume/connect */ if (mdwc->iommu_map) Loading Loading @@ -4850,7 +4858,7 @@ static int dwc3_msm_pm_suspend(struct device *dev) return 0; } ret = dwc3_msm_suspend(mdwc, false); ret = dwc3_msm_suspend(mdwc, false, mdwc->enable_wakeup); if (!ret) atomic_set(&mdwc->pm_suspended, 1); Loading Loading @@ -4927,7 +4935,7 @@ static int dwc3_msm_pm_freeze(struct device *dev) * Power collapse the core. Hence call dwc3_msm_suspend with * 'force_power_collapse' set to 'true'. */ ret = dwc3_msm_suspend(mdwc, true); ret = dwc3_msm_suspend(mdwc, true, mdwc->enable_wakeup); if (!ret) atomic_set(&mdwc->pm_suspended, 1); Loading Loading @@ -4995,7 +5003,7 @@ static int dwc3_msm_runtime_suspend(struct device *dev) dev_dbg(dev, "DWC3-msm runtime suspend\n"); dbg_event(0xFF, "RT Sus", 0); return dwc3_msm_suspend(mdwc, false); return dwc3_msm_suspend(mdwc, false, false); } static int dwc3_msm_runtime_resume(struct device *dev) Loading
drivers/usb/phy/phy-msm-ssusb.c +23 −10 Original line number Diff line number Diff line /* * Copyright (c) 2012-2014,2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2014,2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -63,6 +63,7 @@ struct msm_ssphy { struct clk *cfg_ahb_clk; struct clk *pipe_clk; bool clocks_enabled; bool cable_connected; struct reset_control *phy_com_reset; struct reset_control *phy_reset; Loading Loading @@ -353,23 +354,33 @@ static int msm_ssphy_set_suspend(struct usb_phy *uphy, int suspend) msm_usb_write_readback(phy->base, SS_PHY_CTRL2, REF_SS_PHY_EN, 0); msm_usb_write_readback(phy->base, SS_PHY_CTRL4, REF_USE_PAD, 0); if (!phy->cable_connected) msm_usb_write_readback(phy->base, SS_PHY_CTRL4, TEST_POWERDOWN, TEST_POWERDOWN); msm_ssusb_disable_clocks(phy); if (!phy->cable_connected) { msm_ssusb_ldo_enable(phy, 0); msm_ssusb_config_vdd(phy, 0); } phy->suspended = true; } else { if (!phy->cable_connected) { rc = msm_ssusb_config_vdd(phy, 1); if (rc) return rc; msm_ssusb_ldo_enable(phy, 1); } msm_ssusb_enable_clocks(phy); msm_usb_write_readback(phy->base, SS_PHY_CTRL4, REF_USE_PAD, REF_USE_PAD); msm_usb_write_readback(phy->base, SS_PHY_CTRL2, REF_SS_PHY_EN, REF_SS_PHY_EN); if (!phy->cable_connected) msm_usb_write_readback(phy->base, SS_PHY_CTRL4, TEST_POWERDOWN, 0); Loading @@ -384,6 +395,7 @@ static int msm_ssphy_notify_connect(struct usb_phy *uphy, { struct msm_ssphy *phy = container_of(uphy, struct msm_ssphy, phy); phy->cable_connected = true; if (uphy->flags & PHY_HOST_MODE) return 0; Loading @@ -400,6 +412,7 @@ static int msm_ssphy_notify_disconnect(struct usb_phy *uphy, { struct msm_ssphy *phy = container_of(uphy, struct msm_ssphy, phy); phy->cable_connected = false; if (uphy->flags & PHY_HOST_MODE) return 0; Loading