Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: phy: mxs: add wakeup enable for imx7ulp

This wakeup setting can enable USB wakeup function even the
controller's power is lost, and both A7 and M4 are in VLLS mode.

Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Link: https://lore.kernel.org/r/20240726113207.3393247-4-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Xu Yang and committed by
Greg Kroah-Hartman
c99b27ef 82c7a816

+39 -2
+39 -2
drivers/usb/phy/phy-mxs-usb.c
··· 118 118 #define BM_ANADIG_USB2_MISC_RX_VPIN_FS BIT(29) 119 119 #define BM_ANADIG_USB2_MISC_RX_VMIN_FS BIT(28) 120 120 121 + /* System Integration Module (SIM) Registers */ 122 + #define SIM_GPR1 0x30 123 + 124 + #define USB_PHY_VLLS_WAKEUP_EN BIT(0) 125 + 121 126 #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) 122 127 123 128 /* Do disconnection between PHY and controller without vbus */ ··· 219 214 struct clk *clk; 220 215 const struct mxs_phy_data *data; 221 216 struct regmap *regmap_anatop; 217 + struct regmap *regmap_sim; 222 218 int port_id; 223 219 u32 tx_reg_set; 224 220 u32 tx_reg_mask; ··· 778 772 } 779 773 } 780 774 775 + /* Currently, only imx7ulp has SIM module */ 776 + if (of_get_property(np, "nxp,sim", NULL)) { 777 + mxs_phy->regmap_sim = syscon_regmap_lookup_by_phandle 778 + (np, "nxp,sim"); 779 + if (IS_ERR(mxs_phy->regmap_sim)) { 780 + dev_dbg(&pdev->dev, 781 + "failed to find regmap for sim\n"); 782 + return PTR_ERR(mxs_phy->regmap_sim); 783 + } 784 + } 785 + 781 786 /* Precompute which bits of the TX register are to be updated, if any */ 782 787 if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) && 783 788 val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) { ··· 866 849 } 867 850 868 851 #ifdef CONFIG_PM_SLEEP 852 + static void mxs_phy_wakeup_enable(struct mxs_phy *mxs_phy, bool on) 853 + { 854 + u32 mask = USB_PHY_VLLS_WAKEUP_EN; 855 + 856 + /* If the SoCs don't have SIM, quit */ 857 + if (!mxs_phy->regmap_sim) 858 + return; 859 + 860 + if (on) { 861 + regmap_update_bits(mxs_phy->regmap_sim, SIM_GPR1, mask, mask); 862 + udelay(500); 863 + } else { 864 + regmap_update_bits(mxs_phy->regmap_sim, SIM_GPR1, mask, 0); 865 + } 866 + } 867 + 869 868 static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on) 870 869 { 871 870 unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR; ··· 902 869 { 903 870 struct mxs_phy *mxs_phy = dev_get_drvdata(dev); 904 871 905 - if (device_may_wakeup(dev)) 872 + if (device_may_wakeup(dev)) { 906 873 mxs_phy_enable_ldo_in_suspend(mxs_phy, true); 874 + mxs_phy_wakeup_enable(mxs_phy, true); 875 + } 907 876 908 877 return 0; 909 878 } ··· 914 879 { 915 880 struct mxs_phy *mxs_phy = dev_get_drvdata(dev); 916 881 917 - if (device_may_wakeup(dev)) 882 + if (device_may_wakeup(dev)) { 918 883 mxs_phy_enable_ldo_in_suspend(mxs_phy, false); 884 + mxs_phy_wakeup_enable(mxs_phy, false); 885 + } 919 886 920 887 return 0; 921 888 }