From e2844f4fdba0c8f8c6955aef975f29a59ebbd6d9 Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Mon, 26 Sep 2016 15:49:49 -0700 Subject: [PATCH] scsi: ufs: gate ref_clk during aggressive clk gating The clock gating work has been moved to using hrtimer based delay guaranteeing hibern8 to finish before we gate the clocks. This allows us to gate the ref clock along with other ufs clocks during aggressive clock gating. The latencies involved in voting/ devoting ref clk is acceptable and helps in saving more power. Change-Id: I92b86fad25041311d00fbfc58b3d5620ade7ee38 Signed-off-by: Venkat Gopalakrishnan --- drivers/scsi/ufs/ufs-qcom.c | 19 ++++++++----------- drivers/scsi/ufs/ufshcd.c | 7 ++++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index ad4b6ffef36e..1a1dd804ffb3 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1498,10 +1498,14 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, /* M-PHY RMMI interface clocks can be turned off */ ufs_qcom_phy_disable_iface_clk(host->generic_phy); - if (!ufs_qcom_is_link_active(hba)) { - if (!is_gating_context) - /* turn off UFS local PHY ref_clk */ - ufs_qcom_phy_disable_ref_clk(host->generic_phy); + /* + * If auto hibern8 is supported then the link will already + * be in hibern8 state and the ref clock can be gated. + */ + if (ufshcd_is_auto_hibern8_supported(hba) || + !ufs_qcom_is_link_active(hba)) { + /* turn off UFS local PHY ref_clk */ + ufs_qcom_phy_disable_ref_clk(host->generic_phy); /* disable device ref_clk */ ufs_qcom_dev_ref_clk_ctrl(host, false); } @@ -1956,13 +1960,6 @@ static int ufs_qcom_init(struct ufs_hba *hba) host->hba = hba; ufshcd_set_variant(hba, host); - /* - * voting/devoting device ref_clk source is time consuming hence - * skip devoting it during aggressive clock gating. This clock - * will still be gated off during runtime suspend. - */ - hba->no_ref_clk_gating = true; - err = ufs_qcom_ice_get_dev(host); if (err == -EPROBE_DEFER) { /* diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d254faacfcfe..53fed74eaefc 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1356,7 +1356,12 @@ static void ufshcd_gate_work(struct work_struct *work) ufshcd_set_link_hibern8(hba); } - if (!ufshcd_is_link_active(hba) && !hba->no_ref_clk_gating) + /* + * If auto hibern8 is supported then the link will already + * be in hibern8 state and the ref clock can be gated. + */ + if ((ufshcd_is_auto_hibern8_supported(hba) || + !ufshcd_is_link_active(hba)) && !hba->no_ref_clk_gating) ufshcd_disable_clocks(hba, true); else /* If link is active, device ref_clk can't be switched off */