drm/i915: Remove crtc->config dereference from drrs_ctl
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Thu, 11 Oct 2018 10:04:48 +0000 (12:04 +0200)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Wed, 17 Oct 2018 12:58:54 +0000 (14:58 +0200)
Wait for idle, and iterate over connectors instead of encoders.
With this information we know crtc->state is the actual state,
and we can enable/disable drrs safely.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181011100457.8776-2-maarten.lankhorst@linux.intel.com
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
drivers/gpu/drm/i915/i915_debugfs.c

index 5f3c639..2e01159 100644 (file)
@@ -4660,20 +4660,45 @@ static int i915_drrs_ctl_set(void *data, u64 val)
 {
        struct drm_i915_private *dev_priv = data;
        struct drm_device *dev = &dev_priv->drm;
-       struct intel_crtc *intel_crtc;
-       struct intel_encoder *encoder;
-       struct intel_dp *intel_dp;
+       struct intel_crtc *crtc;
 
        if (INTEL_GEN(dev_priv) < 7)
                return -ENODEV;
 
-       drm_modeset_lock_all(dev);
-       for_each_intel_crtc(dev, intel_crtc) {
-               if (!intel_crtc->base.state->active ||
-                                       !intel_crtc->config->has_drrs)
-                       continue;
+       for_each_intel_crtc(dev, crtc) {
+               struct drm_connector_list_iter conn_iter;
+               struct intel_crtc_state *crtc_state;
+               struct drm_connector *connector;
+               struct drm_crtc_commit *commit;
+               int ret;
+
+               ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
+               if (ret)
+                       return ret;
+
+               crtc_state = to_intel_crtc_state(crtc->base.state);
+
+               if (!crtc_state->base.active ||
+                   !crtc_state->has_drrs)
+                       goto out;
 
-               for_each_encoder_on_crtc(dev, &intel_crtc->base, encoder) {
+               commit = crtc_state->base.commit;
+               if (commit) {
+                       ret = wait_for_completion_interruptible(&commit->hw_done);
+                       if (ret)
+                               goto out;
+               }
+
+               drm_connector_list_iter_begin(dev, &conn_iter);
+               drm_for_each_connector_iter(connector, &conn_iter) {
+                       struct intel_encoder *encoder;
+                       struct intel_dp *intel_dp;
+
+                       if (!(crtc_state->base.connector_mask &
+                             drm_connector_mask(connector)))
+                               continue;
+
+                       encoder = intel_attached_encoder(connector);
                        if (encoder->type != INTEL_OUTPUT_EDP)
                                continue;
 
@@ -4683,13 +4708,18 @@ static int i915_drrs_ctl_set(void *data, u64 val)
                        intel_dp = enc_to_intel_dp(&encoder->base);
                        if (val)
                                intel_edp_drrs_enable(intel_dp,
-                                                       intel_crtc->config);
+                                                     crtc_state);
                        else
                                intel_edp_drrs_disable(intel_dp,
-                                                       intel_crtc->config);
+                                                      crtc_state);
                }
+               drm_connector_list_iter_end(&conn_iter);
+
+out:
+               drm_modeset_unlock(&crtc->base.mutex);
+               if (ret)
+                       return ret;
        }
-       drm_modeset_unlock_all(dev);
 
        return 0;
 }