Loading drivers/usb/phy/phy-msm-ssusb-qmp.c +48 −9 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ #define PCIE_USB3_PHY_START 0x608 #define PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL 0x64C #define PCIE_USB3_PHY_POWER_STATE_CONFIG2 0x654 #define PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL 0x6BC #define PCIE_USB3_PHY_PCS_STATUS 0x728 Loading @@ -86,6 +87,11 @@ #define INIT_MAX_TIME_USEC 1000 /* PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL bits */ #define ARCVR_DTCT_EN BIT(0) #define ALFPS_DTCT_EN BIT(1) #define ARCVR_DTCT_EVENT_SEL BIT(4) struct msm_ssphy_qmp { struct usb_phy phy; Loading @@ -102,6 +108,30 @@ struct msm_ssphy_qmp { bool suspend_allowed; }; static void msm_ssusb_qmp_enable_autonomous(struct msm_ssphy_qmp *phy, bool detached) { u8 val; dev_dbg(phy->phy.dev, "enabling QMP autonomous mode with cable %s\n", (detached ? "detached" : "attached")); val = readb_relaxed(phy->base + PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL); val |= ARCVR_DTCT_EN; if (!detached) { val |= ALFPS_DTCT_EN; /* Detect detach */ val &= ~ARCVR_DTCT_EVENT_SEL; } else { val &= ~ALFPS_DTCT_EN; /* Detect attach */ val |= ARCVR_DTCT_EVENT_SEL; } writeb_relaxed(val, phy->base + PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL); } static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high) { int min, ret; Loading @@ -114,7 +144,7 @@ static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high) return ret; } dev_dbg(phy->phy.dev, "%s: min_vol:%d max_vol:%d\n", __func__, dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n", phy->vdd_levels[min], phy->vdd_levels[2]); return ret; } Loading Loading @@ -238,7 +268,7 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) int ret; unsigned init_timeout_usec = INIT_MAX_TIME_USEC; dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "Initializing QMP phy\n"); if (!phy->clk_enabled) { ret = msm_ssphy_qmp_init_clocks(phy); Loading Loading @@ -330,7 +360,7 @@ static int msm_ssphy_qmp_reset(struct usb_phy *uphy) phy); int ret; dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "Resetting QMP phy\n"); if (!phy->clk_enabled) { ret = msm_ssphy_qmp_init_clocks(phy); Loading Loading @@ -386,7 +416,7 @@ deassert_phy_com_reset: static int msm_ssphy_qmp_set_params(struct usb_phy *uphy) { dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "Setting phy parameters\n"); return 0; } Loading @@ -402,24 +432,30 @@ static int msm_ssphy_qmp_set_suspend(struct usb_phy *uphy, int suspend) struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "%s: suspend state: current :%d new:%d\n", __func__, phy->suspend_allowed, suspend); dev_dbg(uphy->dev, "suspend state: current :%d new:%d\n", phy->suspend_allowed, suspend); if (!!suspend == phy->suspend_allowed) { pr_debug("%s(): USB PHY is already suspended.\n", __func__); pr_debug("USB PHY is already suspended.\n"); return 0; } if (suspend) { msm_ssusb_qmp_enable_autonomous(phy, false); clk_disable_unprepare(phy->pipe_clk); clk_disable_unprepare(phy->cfg_ahb_clk); clk_disable_unprepare(phy->aux_clk); phy->suspend_allowed = true; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); } else { clk_prepare_enable(phy->aux_clk); clk_prepare_enable(phy->cfg_ahb_clk); clk_prepare_enable(phy->pipe_clk); msm_ssusb_qmp_enable_autonomous(phy, false); phy->suspend_allowed = false; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); } return 0; Loading @@ -431,8 +467,9 @@ static int msm_ssphy_qmp_notify_connect(struct usb_phy *uphy, struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "QMP phy connect notification\n"); phy->suspend_allowed = true; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); return 0; } Loading @@ -442,8 +479,10 @@ static int msm_ssphy_qmp_notify_disconnect(struct usb_phy *uphy, struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "QMP phy disconnect notification\n"); phy->suspend_allowed = false; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); msm_ssusb_qmp_enable_autonomous(phy, true); return 0; } Loading Loading
drivers/usb/phy/phy-msm-ssusb-qmp.c +48 −9 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ #define PCIE_USB3_PHY_START 0x608 #define PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL 0x64C #define PCIE_USB3_PHY_POWER_STATE_CONFIG2 0x654 #define PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL 0x6BC #define PCIE_USB3_PHY_PCS_STATUS 0x728 Loading @@ -86,6 +87,11 @@ #define INIT_MAX_TIME_USEC 1000 /* PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL bits */ #define ARCVR_DTCT_EN BIT(0) #define ALFPS_DTCT_EN BIT(1) #define ARCVR_DTCT_EVENT_SEL BIT(4) struct msm_ssphy_qmp { struct usb_phy phy; Loading @@ -102,6 +108,30 @@ struct msm_ssphy_qmp { bool suspend_allowed; }; static void msm_ssusb_qmp_enable_autonomous(struct msm_ssphy_qmp *phy, bool detached) { u8 val; dev_dbg(phy->phy.dev, "enabling QMP autonomous mode with cable %s\n", (detached ? "detached" : "attached")); val = readb_relaxed(phy->base + PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL); val |= ARCVR_DTCT_EN; if (!detached) { val |= ALFPS_DTCT_EN; /* Detect detach */ val &= ~ARCVR_DTCT_EVENT_SEL; } else { val &= ~ALFPS_DTCT_EN; /* Detect attach */ val |= ARCVR_DTCT_EVENT_SEL; } writeb_relaxed(val, phy->base + PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL); } static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high) { int min, ret; Loading @@ -114,7 +144,7 @@ static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high) return ret; } dev_dbg(phy->phy.dev, "%s: min_vol:%d max_vol:%d\n", __func__, dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n", phy->vdd_levels[min], phy->vdd_levels[2]); return ret; } Loading Loading @@ -238,7 +268,7 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) int ret; unsigned init_timeout_usec = INIT_MAX_TIME_USEC; dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "Initializing QMP phy\n"); if (!phy->clk_enabled) { ret = msm_ssphy_qmp_init_clocks(phy); Loading Loading @@ -330,7 +360,7 @@ static int msm_ssphy_qmp_reset(struct usb_phy *uphy) phy); int ret; dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "Resetting QMP phy\n"); if (!phy->clk_enabled) { ret = msm_ssphy_qmp_init_clocks(phy); Loading Loading @@ -386,7 +416,7 @@ deassert_phy_com_reset: static int msm_ssphy_qmp_set_params(struct usb_phy *uphy) { dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "Setting phy parameters\n"); return 0; } Loading @@ -402,24 +432,30 @@ static int msm_ssphy_qmp_set_suspend(struct usb_phy *uphy, int suspend) struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "%s: suspend state: current :%d new:%d\n", __func__, phy->suspend_allowed, suspend); dev_dbg(uphy->dev, "suspend state: current :%d new:%d\n", phy->suspend_allowed, suspend); if (!!suspend == phy->suspend_allowed) { pr_debug("%s(): USB PHY is already suspended.\n", __func__); pr_debug("USB PHY is already suspended.\n"); return 0; } if (suspend) { msm_ssusb_qmp_enable_autonomous(phy, false); clk_disable_unprepare(phy->pipe_clk); clk_disable_unprepare(phy->cfg_ahb_clk); clk_disable_unprepare(phy->aux_clk); phy->suspend_allowed = true; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); } else { clk_prepare_enable(phy->aux_clk); clk_prepare_enable(phy->cfg_ahb_clk); clk_prepare_enable(phy->pipe_clk); msm_ssusb_qmp_enable_autonomous(phy, false); phy->suspend_allowed = false; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); } return 0; Loading @@ -431,8 +467,9 @@ static int msm_ssphy_qmp_notify_connect(struct usb_phy *uphy, struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "QMP phy connect notification\n"); phy->suspend_allowed = true; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); return 0; } Loading @@ -442,8 +479,10 @@ static int msm_ssphy_qmp_notify_disconnect(struct usb_phy *uphy, struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "%s\n", __func__); dev_dbg(uphy->dev, "QMP phy disconnect notification\n"); phy->suspend_allowed = false; dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed); msm_ssusb_qmp_enable_autonomous(phy, true); return 0; } Loading