msm: dcvs: force on the slack timer,
For performance reasons the kernel should execute
a ONLINE call on TZ when the governor starts. The return
values from ONLINE call are a new frequency and a new
slack timer.
This new frequency would be queued up for the thread to set it up
on that core.
The way we handle the new slack timer is interesting. When the
governor starts we really dont know what the state of idle pulses
is, this is indicated by setting idle_entered = -1. However we
want to start the slack timer. To handle this situation create
a function to force on the hrtimer without checking idle_entered or
pending_freq.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
(cherry picked from commit 973671aee4b5f2955a0bb85107022189bc12e75c)
Signed-off-by: Ram Kumar Chakravarthy Chebathini <rcheba@codeaurora.org>
(cherry picked from commit 082cbae484c44d4d0096b0f406dc89e18a96bf8d)
Change-Id: I7f6cd678323588f6d411c17526dc04a5748ed9b4
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/mach-msm/msm_dcvs.c b/arch/arm/mach-msm/msm_dcvs.c
index 98e3722..2dca4a7 100644
--- a/arch/arm/mach-msm/msm_dcvs.c
+++ b/arch/arm/mach-msm/msm_dcvs.c
@@ -146,6 +146,29 @@
spin_unlock_irqrestore(&core->idle_state_change_lock, flags);
}
+static void force_start_slack_timer(struct dcvs_core *core, int slack_us)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&core->idle_state_change_lock, flags);
+
+ /*
+ * only start the timer if governor is not stopped
+ */
+ if (slack_us != 0) {
+ ret = hrtimer_start(&core->slack_timer,
+ ktime_set(0, slack_us * 1000),
+ HRTIMER_MODE_REL_PINNED);
+ if (ret) {
+ pr_err("%s Failed to start timer ret = %d\n",
+ core->core_name, ret);
+ }
+ }
+
+ spin_unlock_irqrestore(&core->idle_state_change_lock, flags);
+}
+
static void stop_slack_timer(struct dcvs_core *core)
{
unsigned long flags;
@@ -825,6 +848,8 @@
struct dcvs_core *core = NULL;
uint32_t ret1;
unsigned long flags;
+ int new_freq;
+ int timer_interval_us;
if (dcvs_core_id < CPU_OFFSET || dcvs_core_id > CORES_MAX) {
__err("%s invalid dcvs_core_id = %d returning -EINVAL\n",
@@ -850,6 +875,21 @@
/* Notify TZ to start receiving idle info for the core */
ret = msm_dcvs_update_freq(core, MSM_DCVS_SCM_DCVS_ENABLE, 1, &ret1);
+ ret = msm_dcvs_scm_event(
+ core->dcvs_core_id, MSM_DCVS_SCM_CORE_ONLINE, core->actual_freq,
+ 0, &new_freq, &timer_interval_us);
+ if (ret)
+ __err("Error (%d) DCVS sending online for %s\n",
+ ret, core->core_name);
+
+ if (new_freq != 0) {
+ spin_lock_irqsave(&core->pending_freq_lock, flags);
+ request_freq_change(core, new_freq);
+ spin_unlock_irqrestore(&core->pending_freq_lock, flags);
+ }
+ force_start_slack_timer(core, timer_interval_us);
+
+
core->idle_enable(core->type_core_num, MSM_DCVS_ENABLE_IDLE_PULSE);
return 0;
}