mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "scsi: ufs-qcom: Refactor phy_power_on/off calls"
This commit is contained in:
commit
32e8550ed0
2 changed files with 80 additions and 42 deletions
|
|
@ -450,6 +450,46 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_qcom_phy_power_on(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
struct phy *phy = host->generic_phy;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&host->phy_mutex);
|
||||
if (!host->is_phy_pwr_on) {
|
||||
ret = phy_power_on(phy);
|
||||
if (ret) {
|
||||
mutex_unlock(&host->phy_mutex);
|
||||
return ret;
|
||||
}
|
||||
host->is_phy_pwr_on = true;
|
||||
}
|
||||
mutex_unlock(&host->phy_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_qcom_phy_power_off(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
struct phy *phy = host->generic_phy;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&host->phy_mutex);
|
||||
if (host->is_phy_pwr_on) {
|
||||
ret = phy_power_off(phy);
|
||||
if (ret) {
|
||||
mutex_unlock(&host->phy_mutex);
|
||||
return ret;
|
||||
}
|
||||
host->is_phy_pwr_on = false;
|
||||
}
|
||||
mutex_unlock(&host->phy_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
|
|
@ -469,28 +509,22 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
|
|||
submode = UFS_QCOM_PHY_SUBMODE_NON_G4;
|
||||
phy_set_mode_ext(phy, mode, submode);
|
||||
|
||||
/* phy initialization - calibrate the phy */
|
||||
ret = phy_init(phy);
|
||||
ret = ufs_qcom_phy_power_on(hba);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "%s: phy init failed, ret = %d\n",
|
||||
__func__, ret);
|
||||
dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
|
||||
__func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* power on phy - start serdes and phy's power and clocks */
|
||||
ret = phy_power_on(phy);
|
||||
ret = phy_calibrate(phy);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
|
||||
__func__, ret);
|
||||
goto out_disable_phy;
|
||||
dev_err(hba->dev, "%s: Failed to calibrate PHY %d\n",
|
||||
__func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ufs_qcom_select_unipro_mode(host);
|
||||
|
||||
return 0;
|
||||
|
||||
out_disable_phy:
|
||||
phy_exit(phy);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -899,8 +933,7 @@ out:
|
|||
static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
|
||||
{
|
||||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
struct phy *phy = host->generic_phy;
|
||||
int ret = 0;
|
||||
int err = 0;
|
||||
|
||||
/*
|
||||
* If UniPro link is not active or OFF, PHY ref_clk, main PHY analog
|
||||
|
|
@ -909,38 +942,22 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
|
|||
*/
|
||||
if (!ufs_qcom_is_link_active(hba)) {
|
||||
ufs_qcom_disable_lane_clks(host);
|
||||
if (host->is_phy_pwr_on) {
|
||||
phy_power_off(phy);
|
||||
host->is_phy_pwr_on = false;
|
||||
}
|
||||
if (host->vddp_ref_clk && ufs_qcom_is_link_off(hba))
|
||||
ret = ufs_qcom_disable_vreg(hba->dev,
|
||||
err = ufs_qcom_disable_vreg(hba->dev,
|
||||
host->vddp_ref_clk);
|
||||
if (host->vccq_parent && !hba->auto_bkops_enabled)
|
||||
ufs_qcom_config_vreg(hba->dev,
|
||||
host->vccq_parent, false);
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
|
||||
{
|
||||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
struct phy *phy = host->generic_phy;
|
||||
int err;
|
||||
|
||||
if (!host->is_phy_pwr_on) {
|
||||
err = phy_power_on(phy);
|
||||
if (err) {
|
||||
dev_err(hba->dev, "%s: failed enabling regs, err = %d\n",
|
||||
__func__, err);
|
||||
return 0;
|
||||
}
|
||||
host->is_phy_pwr_on = true;
|
||||
}
|
||||
|
||||
if (host->vddp_ref_clk && (hba->rpm_lvl > UFS_PM_LVL_3 ||
|
||||
hba->spm_lvl > UFS_PM_LVL_3))
|
||||
ufs_qcom_enable_vreg(hba->dev,
|
||||
|
|
@ -952,7 +969,6 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
hba->is_sys_suspended = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1596,11 +1612,26 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
|
|||
if (!ufs_qcom_is_link_active(hba)) {
|
||||
/* disable device ref_clk */
|
||||
ufs_qcom_dev_ref_clk_ctrl(host, false);
|
||||
|
||||
/* power off PHY during aggressive clk gating */
|
||||
err = ufs_qcom_phy_power_off(hba);
|
||||
if (err) {
|
||||
dev_err(hba->dev, "%s: phy power off failed, ret = %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case POST_CHANGE:
|
||||
if (on) {
|
||||
err = ufs_qcom_phy_power_on(hba);
|
||||
if (err) {
|
||||
dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* enable the device ref clock for HS mode*/
|
||||
if (ufshcd_is_hs_mode(&hba->pwr_info))
|
||||
ufs_qcom_dev_ref_clk_ctrl(host, true);
|
||||
|
|
@ -2144,14 +2175,20 @@ static int ufs_qcom_init(struct ufs_hba *hba)
|
|||
err = ufs_qcom_parse_reg_info(host, "qcom,vddp-ref-clk",
|
||||
&host->vddp_ref_clk);
|
||||
|
||||
phy_init(host->generic_phy);
|
||||
err = phy_init(host->generic_phy);
|
||||
if (err) {
|
||||
dev_err(hba->dev, "%s: phy init failed, err %d\n",
|
||||
__func__, err);
|
||||
goto out_variant_clear;
|
||||
}
|
||||
mutex_init(&host->phy_mutex);
|
||||
|
||||
if (host->vddp_ref_clk) {
|
||||
err = ufs_qcom_enable_vreg(dev, host->vddp_ref_clk);
|
||||
if (err) {
|
||||
dev_err(dev, "%s: failed enabling ref clk supply: %d\n",
|
||||
__func__, err);
|
||||
goto out_unregister_bus;
|
||||
goto out_phy_exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2180,7 +2217,9 @@ static int ufs_qcom_init(struct ufs_hba *hba)
|
|||
ufs_qcom_advertise_quirks(hba);
|
||||
|
||||
ufs_qcom_set_bus_vote(hba, true);
|
||||
ufs_qcom_setup_clocks(hba, true, POST_CHANGE);
|
||||
/* enable the device ref clock for HS mode*/
|
||||
if (ufshcd_is_hs_mode(&hba->pwr_info))
|
||||
ufs_qcom_dev_ref_clk_ctrl(host, true);
|
||||
|
||||
if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
|
||||
ufs_qcom_hosts[hba->dev->id] = host;
|
||||
|
|
@ -2213,7 +2252,7 @@ out_set_load_vccq_parent:
|
|||
out_disable_vddp:
|
||||
if (host->vddp_ref_clk)
|
||||
ufs_qcom_disable_vreg(dev, host->vddp_ref_clk);
|
||||
out_unregister_bus:
|
||||
out_phy_exit:
|
||||
phy_exit(host->generic_phy);
|
||||
out_variant_clear:
|
||||
devm_kfree(dev, host);
|
||||
|
|
@ -2227,10 +2266,7 @@ static void ufs_qcom_exit(struct ufs_hba *hba)
|
|||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
|
||||
ufs_qcom_disable_lane_clks(host);
|
||||
if (host->is_phy_pwr_on) {
|
||||
phy_power_off(host->generic_phy);
|
||||
host->is_phy_pwr_on = false;
|
||||
}
|
||||
ufs_qcom_phy_power_off(hba);
|
||||
phy_exit(host->generic_phy);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -331,6 +331,8 @@ struct ufs_qcom_host {
|
|||
struct ufs_vreg *vccq_parent;
|
||||
bool work_pending;
|
||||
bool is_phy_pwr_on;
|
||||
/* Protect the usage of is_phy_pwr_on against racing */
|
||||
struct mutex phy_mutex;
|
||||
};
|
||||
|
||||
static inline u32
|
||||
|
|
|
|||
Loading…
Reference in a new issue