msm: kgsl: Process all idle checks

Rather than ignore some categories of idle events,
bin the events with small timelines and process all
events with the GPU DCVS algorithm.

CRs-Fixed: 427559
Signed-off-by: Lucille Sylvester <lsylvest@codeaurora.org>
Change-Id: I1a5e8d8af6020a08cf95a9daa934e825bc5f2854
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 8ebca50..8b43024 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -475,7 +475,7 @@
 	    device->state == KGSL_STATE_ACTIVE &&
 		device->requested_state == KGSL_STATE_NONE) {
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
-		kgsl_pwrscale_idle(device, 1);
+		kgsl_pwrscale_idle(device);
 		if (kgsl_pwrctrl_sleep(device) != 0)
 			mod_timer(&device->idle_timer,
 				  jiffies +
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 54eae2b..1eb12a0 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1008,7 +1008,7 @@
 
 	mutex_lock(&device->mutex);
 	if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
-		kgsl_pwrscale_idle(device, 0);
+		kgsl_pwrscale_idle(device);
 
 		if (kgsl_pwrctrl_sleep(device) != 0) {
 			mod_timer(&device->idle_timer,
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index aad1a8d..d46f552 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -242,13 +242,13 @@
 					&device->pwrscale);
 }
 
-void kgsl_pwrscale_idle(struct kgsl_device *device, unsigned int ignore_idle)
+void kgsl_pwrscale_idle(struct kgsl_device *device)
 {
 	if (PWRSCALE_ACTIVE(device) && device->pwrscale.policy->idle)
 		if (device->requested_state != KGSL_STATE_SLUMBER &&
 			device->requested_state != KGSL_STATE_SLEEP)
 			device->pwrscale.policy->idle(device,
-					&device->pwrscale, ignore_idle);
+					&device->pwrscale);
 }
 EXPORT_SYMBOL(kgsl_pwrscale_idle);
 
diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h
index ba9b1af..85d5b82 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.h
+++ b/drivers/gpu/msm/kgsl_pwrscale.h
@@ -23,8 +23,7 @@
 	void (*close)(struct kgsl_device *device,
 		struct kgsl_pwrscale *pwrscale);
 	void (*idle)(struct kgsl_device *device,
-		struct kgsl_pwrscale *pwrscale,
-		unsigned int ignore_idle);
+		struct kgsl_pwrscale *pwrscale);
 	void (*busy)(struct kgsl_device *device,
 		struct kgsl_pwrscale *pwrscale);
 	void (*sleep)(struct kgsl_device *device,
@@ -64,8 +63,7 @@
 	struct kgsl_pwrscale_policy *policy);
 void kgsl_pwrscale_detach_policy(struct kgsl_device *device);
 
-void kgsl_pwrscale_idle(struct kgsl_device *device,
-				unsigned int ignore_idle);
+void kgsl_pwrscale_idle(struct kgsl_device *device);
 void kgsl_pwrscale_busy(struct kgsl_device *device);
 void kgsl_pwrscale_sleep(struct kgsl_device *device);
 void kgsl_pwrscale_wake(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
index fc58dd1..cd432c6 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
@@ -131,7 +131,7 @@
 }
 
 static void idlestats_idle(struct kgsl_device *device,
-		struct kgsl_pwrscale *pwrscale, unsigned int ignore_idle)
+		struct kgsl_pwrscale *pwrscale)
 {
 	int i, nr_cpu;
 	struct idlestats_priv *priv = pwrscale->priv;
diff --git a/drivers/gpu/msm/kgsl_pwrscale_msm.c b/drivers/gpu/msm/kgsl_pwrscale_msm.c
index c680d57..073e474 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_msm.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_msm.c
@@ -132,7 +132,7 @@
 }
 
 static void msm_idle(struct kgsl_device *device,
-		struct kgsl_pwrscale *pwrscale, unsigned int ignore_idle)
+		struct kgsl_pwrscale *pwrscale)
 {
 	struct msm_priv *priv = pwrscale->priv;
 
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index e01932b..3e81e56 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -30,9 +30,14 @@
 	int governor;
 	unsigned int no_switch_cnt;
 	unsigned int skip_cnt;
+	struct kgsl_power_stats bin;
 };
 spinlock_t tz_lock;
 
+/* FLOOR is 5msec to capture up to 3 re-draws
+ * per frame for 60fps content.
+ */
+#define FLOOR			5000
 #define SWITCH_OFF		200
 #define SWITCH_OFF_RESET_TH	40
 #define SKIP_COUNTER		500
@@ -119,24 +124,27 @@
 					device->pwrctrl.default_pwrlevel);
 }
 
-static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale,
-						unsigned int ignore_idle)
+static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
 {
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	struct tz_priv *priv = pwrscale->priv;
 	struct kgsl_power_stats stats;
 	int val, idle;
 
-	if (ignore_idle)
-		return;
-
 	/* In "performance" mode the clock speed always stays
 	   the same */
 	if (priv->governor == TZ_GOVERNOR_PERFORMANCE)
 		return;
 
 	device->ftbl->power_stats(device, &stats);
-	if (stats.total_time == 0)
+	priv->bin.total_time += stats.total_time;
+	priv->bin.busy_time += stats.busy_time;
+	/* Do not waste CPU cycles running this algorithm if
+	 * the GPU just started, or if less than FLOOR time
+	 * has passed since the last run.
+	 */
+	if ((stats.total_time == 0) ||
+		(priv->bin.total_time < FLOOR))
 		return;
 
 	/* If the GPU has stayed in turbo mode for a while, *
@@ -155,7 +163,9 @@
 		priv->no_switch_cnt = 0;
 	}
 
-	idle = stats.total_time - stats.busy_time;
+	idle = priv->bin.total_time - priv->bin.busy_time;
+	priv->bin.total_time = 0;
+	priv->bin.busy_time = 0;
 	idle = (idle > 0) ? idle : 0;
 	val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
 	if (val)
@@ -176,6 +186,8 @@
 
 	__secure_tz_entry(TZ_RESET_ID, 0, device->id);
 	priv->no_switch_cnt = 0;
+	priv->bin.total_time = 0;
+	priv->bin.busy_time = 0;
 }
 
 #ifdef CONFIG_MSM_SCM