|
@@ -986,6 +986,43 @@ static void notify_ring(struct drm_device *dev,
|
|
|
i915_queue_hangcheck(dev);
|
|
|
}
|
|
|
|
|
|
+static void gen6_set_pm_mask(struct drm_i915_private *dev_priv,
|
|
|
+ u32 pm_iir, int new_delay)
|
|
|
+{
|
|
|
+ if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
|
|
|
+ if (new_delay >= dev_priv->rps.max_delay) {
|
|
|
+ /* Mask UP THRESHOLD Interrupts */
|
|
|
+ I915_WRITE(GEN6_PMINTRMSK,
|
|
|
+ I915_READ(GEN6_PMINTRMSK) |
|
|
|
+ GEN6_PM_RP_UP_THRESHOLD);
|
|
|
+ dev_priv->rps.rp_up_masked = true;
|
|
|
+ }
|
|
|
+ if (dev_priv->rps.rp_down_masked) {
|
|
|
+ /* UnMask DOWN THRESHOLD Interrupts */
|
|
|
+ I915_WRITE(GEN6_PMINTRMSK,
|
|
|
+ I915_READ(GEN6_PMINTRMSK) &
|
|
|
+ ~GEN6_PM_RP_DOWN_THRESHOLD);
|
|
|
+ dev_priv->rps.rp_down_masked = false;
|
|
|
+ }
|
|
|
+ } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
|
|
|
+ if (new_delay <= dev_priv->rps.min_delay) {
|
|
|
+ /* Mask DOWN THRESHOLD Interrupts */
|
|
|
+ I915_WRITE(GEN6_PMINTRMSK,
|
|
|
+ I915_READ(GEN6_PMINTRMSK) |
|
|
|
+ GEN6_PM_RP_DOWN_THRESHOLD);
|
|
|
+ dev_priv->rps.rp_down_masked = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dev_priv->rps.rp_up_masked) {
|
|
|
+ /* UnMask UP THRESHOLD Interrupts */
|
|
|
+ I915_WRITE(GEN6_PMINTRMSK,
|
|
|
+ I915_READ(GEN6_PMINTRMSK) &
|
|
|
+ ~GEN6_PM_RP_UP_THRESHOLD);
|
|
|
+ dev_priv->rps.rp_up_masked = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void gen6_pm_rps_work(struct work_struct *work)
|
|
|
{
|
|
|
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
|
|
@@ -1043,6 +1080,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
|
|
|
*/
|
|
|
new_delay = clamp_t(int, new_delay,
|
|
|
dev_priv->rps.min_delay, dev_priv->rps.max_delay);
|
|
|
+
|
|
|
+ gen6_set_pm_mask(dev_priv, pm_iir, new_delay);
|
|
|
dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_delay;
|
|
|
|
|
|
if (IS_VALLEYVIEW(dev_priv->dev))
|