drm/i915: Initialize DRRS delayed work
authorVandana Kannan <vandana.kannan@intel.com>
Thu, 22 Jan 2015 09:44:45 +0000 (15:14 +0530)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 27 Jan 2015 08:51:14 +0000 (09:51 +0100)
Add DRRS work function to trigger a switch to low refresh rate,
when no activity is detected on screen till 1 sec duration.

v2: [By Ram]: drrs.dp also protected with drrs.mutex and worker function
is renamed to intel_edp_drrs_downclock_work [Chris]

Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_dp.c

index 081eb36871907110f33eacb023e8e9990ae31960..a3ce984c084def2f42a3d526f009e6436d07a82e 100644 (file)
@@ -4817,20 +4817,40 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
                I915_WRITE(reg, val);
        }
 
+       dev_priv->drrs.refresh_rate_type = index;
+
+       DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+}
+
+static void intel_edp_drrs_downclock_work(struct work_struct *work)
+{
+       struct drm_i915_private *dev_priv =
+               container_of(work, typeof(*dev_priv), drrs.work.work);
+       struct intel_dp *intel_dp;
+
+       mutex_lock(&dev_priv->drrs.mutex);
+
+       intel_dp = dev_priv->drrs.dp;
+
+       if (!intel_dp)
+               goto unlock;
+
        /*
-        * mutex taken to ensure that there is no race between differnt
-        * drrs calls trying to update refresh rate. This scenario may occur
-        * in future when idleness detection based DRRS in kernel and
-        * possible calls from user space to set differnt RR are made.
+        * The delayed work can race with an invalidate hence we need to
+        * recheck.
         */
 
-       mutex_lock(&dev_priv->drrs.mutex);
+       if (dev_priv->drrs.busy_frontbuffer_bits)
+               goto unlock;
 
-       dev_priv->drrs.refresh_rate_type = index;
+       if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR)
+               intel_dp_set_drrs_state(dev_priv->dev,
+                       intel_dp->attached_connector->panel.
+                       downclock_mode->vrefresh);
 
-       mutex_unlock(&dev_priv->drrs.mutex);
+unlock:
 
-       DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+       mutex_unlock(&dev_priv->drrs.mutex);
 }
 
 static struct drm_display_mode *
@@ -4860,6 +4880,8 @@ intel_dp_drrs_init(struct intel_connector *intel_connector,
                return NULL;
        }
 
+       INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
+
        mutex_init(&dev_priv->drrs.mutex);
 
        dev_priv->drrs.type = dev_priv->vbt.drrs_type;