]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drm/i915: Fix computation of last_adjustment for RPS autotuning
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 7 Apr 2015 15:20:29 +0000 (16:20 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 10 Apr 2015 06:56:01 +0000 (08:56 +0200)
The issue is that by computing the last_adj value after applying the
clamping, we can end up with a bogus value for feeding into the next RPS
autotuning step.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Deepak S <deepak.s@linux.intel.com>
Reviewed-by: Deepak S <deepak.s@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_irq.c

index 128a6f40b45093a0a67d7fef6ecf81038a8570a3..8b5e0358c59287d4a85750a6b347e02e6702a089 100644 (file)
@@ -1095,21 +1095,20 @@ static void gen6_pm_rps_work(struct work_struct *work)
        pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir);
 
        adj = dev_priv->rps.last_adj;
+       new_delay = dev_priv->rps.cur_freq;
        if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
                if (adj > 0)
                        adj *= 2;
-               else {
-                       /* CHV needs even encode values */
-                       adj = IS_CHERRYVIEW(dev_priv->dev) ? 2 : 1;
-               }
-               new_delay = dev_priv->rps.cur_freq + adj;
-
+               else /* CHV needs even encode values */
+                       adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1;
                /*
                 * For better performance, jump directly
                 * to RPe if we're below it.
                 */
-               if (new_delay < dev_priv->rps.efficient_freq)
+               if (new_delay < dev_priv->rps.efficient_freq - adj) {
                        new_delay = dev_priv->rps.efficient_freq;
+                       adj = 0;
+               }
        } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
                if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq)
                        new_delay = dev_priv->rps.efficient_freq;
@@ -1119,24 +1118,22 @@ static void gen6_pm_rps_work(struct work_struct *work)
        } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
                if (adj < 0)
                        adj *= 2;
-               else {
-                       /* CHV needs even encode values */
-                       adj = IS_CHERRYVIEW(dev_priv->dev) ? -2 : -1;
-               }
-               new_delay = dev_priv->rps.cur_freq + adj;
+               else /* CHV needs even encode values */
+                       adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1;
        } else { /* unknown event */
-               new_delay = dev_priv->rps.cur_freq;
+               adj = 0;
        }
 
+       dev_priv->rps.last_adj = adj;
+
        /* sysfs frequency interfaces may have snuck in while servicing the
         * interrupt
         */
+       new_delay += adj;
        new_delay = clamp_t(int, new_delay,
                            dev_priv->rps.min_freq_softlimit,
                            dev_priv->rps.max_freq_softlimit);
 
-       dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_freq;
-
        intel_set_rps(dev_priv->dev, new_delay);
 
        mutex_unlock(&dev_priv->rps.hw_lock);