aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff McGee <jeff.mcgee@intel.com>2014-02-04 12:32:31 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-07 04:25:10 -0500
commitdd0a1aa19bd3d7203e58157b84cea78bbac605ac (patch)
treeb59d3c4fc62b0c0b0a0757868167e31d17b19bf1
parent1f70999f9052f5a1b0ce1a55aff3808f2ec9fe42 (diff)
drm/i915: Restore rps/rc6 on reset
A check of rps/rc6 state after i915_reset determined that the ring MAX_IDLE registers were returned to their hardware defaults and that the GEN6_PMIMR register was set to mask all interrupts. This change restores those values to their pre-reset states by re-initializing rps/rc6 in i915_reset. A full re-initialization was opted for versus a targeted set of restore operations for simplicity and maintain- ability. Note that the re-initialization is not done for Ironlake, due to a past comment that it causes problems. Also updated the rps initialization sequence to preserve existing min/max values in the case of a re-init. We assume the values were validated upon being set and do not do further range checking. The debugfs interface for changing min/max was updated with range checking to ensure this condition (already present in sysfs interface). v2: fix rps logging to output hw_max and hw_min, not rps.max_delay and rps.min_delay which don't strictly represent hardware limits. Add igt testcase to signed-off-by section. Testcase: igt/pm_rps/reset Signed-off-by: Jeff McGee <jeff.mcgee@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c49
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c11
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c35
3 files changed, 76 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index bc8707f9656f..2dc05c30b800 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3223,6 +3223,7 @@ i915_max_freq_set(void *data, u64 val)
3223{ 3223{
3224 struct drm_device *dev = data; 3224 struct drm_device *dev = data;
3225 struct drm_i915_private *dev_priv = dev->dev_private; 3225 struct drm_i915_private *dev_priv = dev->dev_private;
3226 u32 rp_state_cap, hw_max, hw_min;
3226 int ret; 3227 int ret;
3227 3228
3228 if (!(IS_GEN6(dev) || IS_GEN7(dev))) 3229 if (!(IS_GEN6(dev) || IS_GEN7(dev)))
@@ -3241,14 +3242,29 @@ i915_max_freq_set(void *data, u64 val)
3241 */ 3242 */
3242 if (IS_VALLEYVIEW(dev)) { 3243 if (IS_VALLEYVIEW(dev)) {
3243 val = vlv_freq_opcode(dev_priv, val); 3244 val = vlv_freq_opcode(dev_priv, val);
3244 dev_priv->rps.max_delay = val; 3245
3245 valleyview_set_rps(dev, val); 3246 hw_max = valleyview_rps_max_freq(dev_priv);
3247 hw_min = valleyview_rps_min_freq(dev_priv);
3246 } else { 3248 } else {
3247 do_div(val, GT_FREQUENCY_MULTIPLIER); 3249 do_div(val, GT_FREQUENCY_MULTIPLIER);
3248 dev_priv->rps.max_delay = val; 3250
3249 gen6_set_rps(dev, val); 3251 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
3252 hw_max = dev_priv->rps.hw_max;
3253 hw_min = (rp_state_cap >> 16) & 0xff;
3254 }
3255
3256 if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
3257 mutex_unlock(&dev_priv->rps.hw_lock);
3258 return -EINVAL;
3250 } 3259 }
3251 3260
3261 dev_priv->rps.max_delay = val;
3262
3263 if (IS_VALLEYVIEW(dev))
3264 valleyview_set_rps(dev, val);
3265 else
3266 gen6_set_rps(dev, val);
3267
3252 mutex_unlock(&dev_priv->rps.hw_lock); 3268 mutex_unlock(&dev_priv->rps.hw_lock);
3253 3269
3254 return 0; 3270 return 0;
@@ -3288,6 +3304,7 @@ i915_min_freq_set(void *data, u64 val)
3288{ 3304{
3289 struct drm_device *dev = data; 3305 struct drm_device *dev = data;
3290 struct drm_i915_private *dev_priv = dev->dev_private; 3306 struct drm_i915_private *dev_priv = dev->dev_private;
3307 u32 rp_state_cap, hw_max, hw_min;
3291 int ret; 3308 int ret;
3292 3309
3293 if (!(IS_GEN6(dev) || IS_GEN7(dev))) 3310 if (!(IS_GEN6(dev) || IS_GEN7(dev)))
@@ -3306,13 +3323,29 @@ i915_min_freq_set(void *data, u64 val)
3306 */ 3323 */
3307 if (IS_VALLEYVIEW(dev)) { 3324 if (IS_VALLEYVIEW(dev)) {
3308 val = vlv_freq_opcode(dev_priv, val); 3325 val = vlv_freq_opcode(dev_priv, val);
3309 dev_priv->rps.min_delay = val; 3326
3310 valleyview_set_rps(dev, val); 3327 hw_max = valleyview_rps_max_freq(dev_priv);
3328 hw_min = valleyview_rps_min_freq(dev_priv);
3311 } else { 3329 } else {
3312 do_div(val, GT_FREQUENCY_MULTIPLIER); 3330 do_div(val, GT_FREQUENCY_MULTIPLIER);
3313 dev_priv->rps.min_delay = val; 3331
3314 gen6_set_rps(dev, val); 3332 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
3333 hw_max = dev_priv->rps.hw_max;
3334 hw_min = (rp_state_cap >> 16) & 0xff;
3335 }
3336
3337 if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
3338 mutex_unlock(&dev_priv->rps.hw_lock);
3339 return -EINVAL;
3315 } 3340 }
3341
3342 dev_priv->rps.min_delay = val;
3343
3344 if (IS_VALLEYVIEW(dev))
3345 valleyview_set_rps(dev, val);
3346 else
3347 gen6_set_rps(dev, val);
3348
3316 mutex_unlock(&dev_priv->rps.hw_lock); 3349 mutex_unlock(&dev_priv->rps.hw_lock);
3317 3350
3318 return 0; 3351 return 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 05072cf5a008..2d05d7ce4c29 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -728,6 +728,17 @@ int i915_reset(struct drm_device *dev)
728 728
729 drm_irq_uninstall(dev); 729 drm_irq_uninstall(dev);
730 drm_irq_install(dev); 730 drm_irq_install(dev);
731
732 /* rps/rc6 re-init is necessary to restore state lost after the
733 * reset and the re-install of drm irq. Skip for ironlake per
734 * previous concerns that it doesn't respond well to some forms
735 * of re-init after reset. */
736 if (INTEL_INFO(dev)->gen > 5) {
737 mutex_lock(&dev->struct_mutex);
738 intel_enable_gt_powersave(dev);
739 mutex_unlock(&dev->struct_mutex);
740 }
741
731 intel_hpd_init(dev); 742 intel_hpd_init(dev);
732 } else { 743 } else {
733 mutex_unlock(&dev->struct_mutex); 744 mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9ab388313d3d..6af58cd6d77c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3322,7 +3322,7 @@ static void gen6_enable_rps(struct drm_device *dev)
3322{ 3322{
3323 struct drm_i915_private *dev_priv = dev->dev_private; 3323 struct drm_i915_private *dev_priv = dev->dev_private;
3324 struct intel_ring_buffer *ring; 3324 struct intel_ring_buffer *ring;
3325 u32 rp_state_cap; 3325 u32 rp_state_cap, hw_max, hw_min;
3326 u32 gt_perf_status; 3326 u32 gt_perf_status;
3327 u32 rc6vids, pcu_mbox, rc6_mask = 0; 3327 u32 rc6vids, pcu_mbox, rc6_mask = 0;
3328 u32 gtfifodbg; 3328 u32 gtfifodbg;
@@ -3351,13 +3351,20 @@ static void gen6_enable_rps(struct drm_device *dev)
3351 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); 3351 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
3352 3352
3353 /* In units of 50MHz */ 3353 /* In units of 50MHz */
3354 dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff; 3354 dev_priv->rps.hw_max = hw_max = rp_state_cap & 0xff;
3355 dev_priv->rps.min_delay = (rp_state_cap >> 16) & 0xff; 3355 hw_min = (rp_state_cap >> 16) & 0xff;
3356 dev_priv->rps.rp1_delay = (rp_state_cap >> 8) & 0xff; 3356 dev_priv->rps.rp1_delay = (rp_state_cap >> 8) & 0xff;
3357 dev_priv->rps.rp0_delay = (rp_state_cap >> 0) & 0xff; 3357 dev_priv->rps.rp0_delay = (rp_state_cap >> 0) & 0xff;
3358 dev_priv->rps.rpe_delay = dev_priv->rps.rp1_delay; 3358 dev_priv->rps.rpe_delay = dev_priv->rps.rp1_delay;
3359 dev_priv->rps.cur_delay = 0; 3359 dev_priv->rps.cur_delay = 0;
3360 3360
3361 /* Preserve min/max settings in case of re-init */
3362 if (dev_priv->rps.max_delay == 0)
3363 dev_priv->rps.max_delay = hw_max;
3364
3365 if (dev_priv->rps.min_delay == 0)
3366 dev_priv->rps.min_delay = hw_min;
3367
3361 /* disable the counters and set deterministic thresholds */ 3368 /* disable the counters and set deterministic thresholds */
3362 I915_WRITE(GEN6_RC_CONTROL, 0); 3369 I915_WRITE(GEN6_RC_CONTROL, 0);
3363 3370
@@ -3586,7 +3593,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
3586{ 3593{
3587 struct drm_i915_private *dev_priv = dev->dev_private; 3594 struct drm_i915_private *dev_priv = dev->dev_private;
3588 struct intel_ring_buffer *ring; 3595 struct intel_ring_buffer *ring;
3589 u32 gtfifodbg, val, rc6_mode = 0; 3596 u32 gtfifodbg, val, hw_max, hw_min, rc6_mode = 0;
3590 int i; 3597 int i;
3591 3598
3592 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 3599 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
@@ -3648,21 +3655,27 @@ static void valleyview_enable_rps(struct drm_device *dev)
3648 vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay), 3655 vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay),
3649 dev_priv->rps.cur_delay); 3656 dev_priv->rps.cur_delay);
3650 3657
3651 dev_priv->rps.max_delay = valleyview_rps_max_freq(dev_priv); 3658 dev_priv->rps.hw_max = hw_max = valleyview_rps_max_freq(dev_priv);
3652 dev_priv->rps.hw_max = dev_priv->rps.max_delay;
3653 DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", 3659 DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
3654 vlv_gpu_freq(dev_priv, dev_priv->rps.max_delay), 3660 vlv_gpu_freq(dev_priv, hw_max),
3655 dev_priv->rps.max_delay); 3661 hw_max);
3656 3662
3657 dev_priv->rps.rpe_delay = valleyview_rps_rpe_freq(dev_priv); 3663 dev_priv->rps.rpe_delay = valleyview_rps_rpe_freq(dev_priv);
3658 DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", 3664 DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
3659 vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay), 3665 vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
3660 dev_priv->rps.rpe_delay); 3666 dev_priv->rps.rpe_delay);
3661 3667
3662 dev_priv->rps.min_delay = valleyview_rps_min_freq(dev_priv); 3668 hw_min = valleyview_rps_min_freq(dev_priv);
3663 DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", 3669 DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
3664 vlv_gpu_freq(dev_priv, dev_priv->rps.min_delay), 3670 vlv_gpu_freq(dev_priv, hw_min),
3665 dev_priv->rps.min_delay); 3671 hw_min);
3672
3673 /* Preserve min/max settings in case of re-init */
3674 if (dev_priv->rps.max_delay == 0)
3675 dev_priv->rps.max_delay = hw_max;
3676
3677 if (dev_priv->rps.min_delay == 0)
3678 dev_priv->rps.min_delay = hw_min;
3666 3679
3667 DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n", 3680 DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
3668 vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay), 3681 vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),