Baytrail uses the RPS wait-boosting mechanism of Sandybridge+ but also has a very lax downclocking strategy (upclock if more than 90% busy over 76ms, downclock if less than 70% busy over 450ms). This causes Baytrail to use maximum clocks, and for them to stay high, when doing simple tasks such as scrolling through webpages. However, we can take a leaf out of the same wait-boost mechansim and apply the aggressive downclocking strategy from Sandybridge+ as well. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_pm.c | 50 +++++++++++++---------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7005ea3595e2..009f81a922e4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3090,14 +3090,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) /* Downclock if less than 85% busy over 32ms */ I915_WRITE(GEN6_RP_DOWN_EI, 25000); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 21250); - - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_AVG); break; case BETWEEN: @@ -3108,14 +3100,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) /* Downclock if less than 75% busy over 32ms */ I915_WRITE(GEN6_RP_DOWN_EI, 25000); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 18750); - - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_AVG); break; case HIGH_POWER: @@ -3126,17 +3110,17 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) /* Downclock if less than 60% busy over 32ms */ I915_WRITE(GEN6_RP_DOWN_EI, 25000); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 15000); - - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_AVG); break; } + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_MEDIA_HW_NORMAL_MODE | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_AVG); + dev_priv->rps.power = new_power; dev_priv->rps.last_adj = 0; } @@ -3210,29 +3194,25 @@ void gen6_set_rps(struct drm_device *dev, u8 val) */ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) { + u32 val = dev_priv->rps.min_freq_softlimit; + /* * When we are idle. Drop to min voltage state. */ - - if (dev_priv->rps.cur_freq <= dev_priv->rps.min_freq_softlimit) + if (dev_priv->rps.cur_freq <= val) return; /* Mask turbo interrupt so that they will not come in between */ I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); - vlv_force_gfx_clock(dev_priv, true); - dev_priv->rps.cur_freq = dev_priv->rps.min_freq_softlimit; - - vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, - dev_priv->rps.min_freq_softlimit); - + gen6_set_rps_thresholds(dev_priv, val); + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS)) & GENFREQSTATUS) == 0, 5)) DRM_ERROR("timed out waiting for Punit\n"); vlv_force_gfx_clock(dev_priv, false); - I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); } @@ -3280,8 +3260,10 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) dev_priv->rps.cur_freq, vlv_gpu_freq(dev_priv, val), val); - if (val != dev_priv->rps.cur_freq) + if (val != dev_priv->rps.cur_freq) { + gen6_set_rps_thresholds(dev_priv, val); vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + } I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); -- 2.0.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx