diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 55d993110d51..c5914564939c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4143,17 +4143,25 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) dev_priv->rps.last_adj = 0; I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); } + mutex_unlock(&dev_priv->rps.hw_lock); + spin_lock(&dev_priv->rps.client_lock); while (!list_empty(&dev_priv->rps.clients)) list_del_init(dev_priv->rps.clients.next); - mutex_unlock(&dev_priv->rps.hw_lock); + spin_unlock(&dev_priv->rps.client_lock); } void gen6_rps_boost(struct drm_i915_private *dev_priv, struct intel_rps_client *rps, unsigned long submitted) { - u32 val; + /* This is intentionally racy! We peek at the state here, then + * validate inside the RPS worker. + */ + if (!(dev_priv->mm.busy && + dev_priv->rps.enabled && + dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit)) + return; /* Force a RPS boost (and don't count it against the client) if * the GPU is severely congested. @@ -4161,14 +4169,14 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv, if (rps && time_after(jiffies, submitted + DRM_I915_THROTTLE_JIFFIES)) rps = NULL; - mutex_lock(&dev_priv->rps.hw_lock); - val = dev_priv->rps.max_freq_softlimit; - if (dev_priv->rps.enabled && - dev_priv->mm.busy && - dev_priv->rps.cur_freq < val && - (rps == NULL || list_empty(&rps->link))) { - intel_set_rps(dev_priv->dev, val); - dev_priv->rps.last_adj = 0; + spin_lock(&dev_priv->rps.client_lock); + if (rps == NULL || list_empty(&rps->link)) { + spin_lock_irq(&dev_priv->irq_lock); + if (dev_priv->rps.interrupts_enabled) { + dev_priv->rps.client_boost = true; + queue_work(dev_priv->wq, &dev_priv->rps.work); + } + spin_unlock_irq(&dev_priv->irq_lock); if (rps != NULL) { list_add(&rps->link, &dev_priv->rps.clients); @@ -4176,7 +4184,7 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv, } else dev_priv->rps.boosts++; } - mutex_unlock(&dev_priv->rps.hw_lock); + spin_unlock(&dev_priv->rps.client_lock); } void intel_set_rps(struct drm_device *dev, u8 val) @@ -4956,9 +4964,9 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) mutex_lock(&dev_priv->rps.hw_lock); - mutex_lock(&dev_priv->dpio_lock); + mutex_lock(&dev_priv->sb_lock); val = vlv_cck_read(dev_priv, CCK_FUSE_REG); - mutex_unlock(&dev_priv->dpio_lock); + mutex_unlock(&dev_priv->sb_lock); switch ((val >> 2) & 0x7) { case 0: @@ -5878,13 +5886,15 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void g4x_disable_trickle_feed(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; + enum pipe pipe; for_each_pipe(dev_priv, pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); - intel_flush_primary_plane(dev_priv, pipe); + + I915_WRITE(DSPSURF(pipe), I915_READ(DSPSURF(pipe))); + POSTING_READ(DSPSURF(pipe)); } } @@ -6913,6 +6923,7 @@ void intel_pm_setup(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; mutex_init(&dev_priv->rps.hw_lock); + spin_lock_init(&dev_priv->rps.client_lock); INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, intel_gen6_powersave_work); |
