scsi: ufs-qcom: do clock gating and hibern8 @10ms

This change enables the aggressive clock gating along with hibern8 at
every 10ms. As hibern8 enter was already @10ms, we are now merging it
with clock gating which will also be @10ms after this change. This change
is needed to save power for real life usecases.

Change-Id: I297d0f7d1c379f0b402298dc5dddd92ac33f6f25
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
Subhash Jadavani 2015-07-16 17:20:07 -07:00 committed by David Keitel
parent 0cdd14268f
commit 4f4ab265a8
2 changed files with 19 additions and 5 deletions

View file

@ -1226,9 +1226,9 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba)
{ {
struct ufs_qcom_host *host = ufshcd_get_variant(hba); struct ufs_qcom_host *host = ufshcd_get_variant(hba);
hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_CLK_SCALING; hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
hba->caps |= UFSHCD_CAP_CLK_SCALING;
hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND; hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
hba->caps |= UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;
if (host->hw_ver.major >= 0x2) { if (host->hw_ver.major >= 0x2) {
hba->caps |= UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8; hba->caps |= UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8;

View file

@ -1332,6 +1332,8 @@ out:
/* host lock must be held before calling this variant */ /* host lock must be held before calling this variant */
static void __ufshcd_release(struct ufs_hba *hba, bool no_sched) static void __ufshcd_release(struct ufs_hba *hba, bool no_sched)
{ {
unsigned long delay_in_jiffies;
if (!ufshcd_is_clkgating_allowed(hba)) if (!ufshcd_is_clkgating_allowed(hba))
return; return;
@ -1346,8 +1348,20 @@ static void __ufshcd_release(struct ufs_hba *hba, bool no_sched)
hba->clk_gating.state = REQ_CLKS_OFF; hba->clk_gating.state = REQ_CLKS_OFF;
trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state); trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state);
schedule_delayed_work(&hba->clk_gating.gate_work,
msecs_to_jiffies(hba->clk_gating.delay_ms)); /*
* Scheduling the delayed work after 1 jiffies will make the work to
* get schedule any time from 0ms to 1000/HZ ms which is not desirable
* for hibern8 enter work as it may impact the performance if it gets
* scheduled almost immediately. Hence make sure that hibern8 enter
* work gets scheduled atleast after 2 jiffies (any time between
* 1000/HZ ms to 2000/HZ ms).
*/
delay_in_jiffies = msecs_to_jiffies(hba->clk_gating.delay_ms);
if (delay_in_jiffies == 1)
delay_in_jiffies++;
schedule_delayed_work(&hba->clk_gating.gate_work, delay_in_jiffies);
} }
void ufshcd_release(struct ufs_hba *hba, bool no_sched) void ufshcd_release(struct ufs_hba *hba, bool no_sched)
@ -1423,7 +1437,7 @@ static void ufshcd_init_clk_gating(struct ufs_hba *hba)
if (!ufshcd_is_clkgating_allowed(hba)) if (!ufshcd_is_clkgating_allowed(hba))
return; return;
hba->clk_gating.delay_ms = 50; hba->clk_gating.delay_ms = 10;
INIT_DELAYED_WORK(&hba->clk_gating.gate_work, ufshcd_gate_work); INIT_DELAYED_WORK(&hba->clk_gating.gate_work, ufshcd_gate_work);
INIT_WORK(&hba->clk_gating.ungate_work, ufshcd_ungate_work); INIT_WORK(&hba->clk_gating.ungate_work, ufshcd_ungate_work);