drm/i915/fbc: Disable FBC fully on FIFO underrun
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 24 Nov 2021 11:36:47 +0000 (13:36 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 3 Dec 2021 11:23:38 +0000 (13:23 +0200)
Currently a FIFO underrun just causes FBC to be deactivated,
and later checks then prevent it from being reactivated. We
can simpify our lives a bit by logically disabling FBC on
FIFO underruns. This avoids the funny intermediate state where
FBC is logically enabled but can't actually be activated.

v2: intel_wait_for_vblank() is no more

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211124113652.22090-16-ville.syrjala@linux.intel.com
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
drivers/gpu/drm/i915/display/intel_fbc.c

index 616ab95766b2e8e64d39a5f28a18f08b0d5adfc1..1f8ff7ab2dec26dc1f43e42f38fb03ed0a61ab55 100644 (file)
@@ -994,16 +994,6 @@ static bool intel_fbc_cfb_size_changed(struct intel_fbc *fbc)
        return fbc->state_cache.cfb_size > fbc->compressed_fb.size * fbc->limit;
 }
 
-static bool intel_fbc_can_enable(struct intel_fbc *fbc)
-{
-       if (fbc->underrun_detected) {
-               fbc->no_fbc_reason = "underrun detected";
-               return false;
-       }
-
-       return true;
-}
-
 static int intel_fbc_check_plane(struct intel_atomic_state *state,
                                 struct intel_plane *plane)
 {
@@ -1123,22 +1113,11 @@ static bool intel_fbc_can_activate(struct intel_fbc *fbc)
        struct drm_i915_private *i915 = fbc->i915;
        struct intel_fbc_state *cache = &fbc->state_cache;
 
-       if (!intel_fbc_can_enable(fbc))
-               return false;
-
        if (cache->no_fbc_reason) {
                fbc->no_fbc_reason = cache->no_fbc_reason;
                return false;
        }
 
-       /* We don't need to use a state cache here since this information is
-        * global for all CRTC.
-        */
-       if (fbc->underrun_detected) {
-               fbc->no_fbc_reason = "underrun detected";
-               return false;
-       }
-
        /* The use of a CPU fence is one of two ways to detect writes by the
         * CPU to the scanout and trigger updates to the FBC.
         *
@@ -1467,6 +1446,11 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
        if (cache->no_fbc_reason)
                return;
 
+       if (fbc->underrun_detected) {
+               fbc->no_fbc_reason = "FIFO underrun";
+               return;
+       }
+
        if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(plane_state), min_limit)) {
                fbc->no_fbc_reason = "not enough stolen memory";
                return;
@@ -1567,6 +1551,9 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
        fbc->underrun_detected = true;
 
        intel_fbc_deactivate(fbc, "FIFO underrun");
+       if (!fbc->flip_pending)
+               intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(i915, fbc->plane->pipe));
+       __intel_fbc_disable(fbc);
 out:
        mutex_unlock(&fbc->lock);
 }