[PATCH] drm/i915/display: Add an extra vblank wait before fbc activation

Uma Shankar uma.shankar at intel.com
Mon Aug 24 21:42:46 UTC 2020


Add an extra vblank before fbc is activated.

v2: Add vblank worker to add the extra wait instead of blocking
vblank wait, as suggested by Maarten.

Signed-off-by: Uma Shankar <uma.shankar at intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  |  1 +
 .../drm/i915/display/intel_display_types.h    |  3 ++
 drivers/gpu/drm/i915/display/intel_fbc.c      | 28 +++++++++++++++++--
 drivers/gpu/drm/i915/display/intel_fbc.h      |  2 +-
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 2ddabf92adde..4ff2c15ae550 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -16719,6 +16719,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
 	intel_color_init(crtc);
 
 	intel_crtc_crc_init(crtc);
+	intel_crtc_fbc_work_init(crtc);
 
 	drm_WARN_ON(&dev_priv->drm, drm_crtc_index(&crtc->base) != crtc->pipe);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 9349b15afff6..e0506c888f99 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -41,6 +41,7 @@
 #include <drm/drm_vblank.h>
 #include <drm/i915_mei_hdcp_interface.h>
 #include <media/cec-notifier.h>
+#include <drm/drm_vblank_work.h>
 
 #include "i915_drv.h"
 #include "intel_de.h"
@@ -1152,6 +1153,8 @@ struct intel_crtc {
 #ifdef CONFIG_DEBUG_FS
 	struct intel_pipe_crc pipe_crc;
 #endif
+
+	struct drm_vblank_work fbc_work;
 };
 
 struct intel_plane {
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 3a4f980788a6..91a68aa0ced2 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -1075,10 +1075,13 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc)
 	if (!intel_fbc_can_activate(crtc))
 		return;
 
-	if (!fbc->busy_bits)
-		intel_fbc_hw_activate(dev_priv);
-	else
+	if (!fbc->busy_bits) {
+		drm_vblank_work_schedule(&crtc->fbc_work,
+					 drm_crtc_vblank_count(&crtc->base) + 1,
+					 true);
+	} else {
 		intel_fbc_deactivate(dev_priv, "frontbuffer write");
+	}
 }
 
 void intel_fbc_post_update(struct intel_atomic_state *state,
@@ -1281,6 +1284,9 @@ void intel_fbc_enable(struct intel_atomic_state *state,
 	fbc->no_fbc_reason = "FBC enabled but not active yet\n";
 
 	fbc->crtc = crtc;
+
+	drm_vblank_work_cancel_sync(&crtc->fbc_work);
+
 out:
 	mutex_unlock(&fbc->lock);
 }
@@ -1445,6 +1451,22 @@ static bool need_fbc_vtd_wa(struct drm_i915_private *dev_priv)
 	return false;
 }
 
+static void intel_fbc_vblank_work(struct kthread_work *base)
+{
+	struct drm_vblank_work *work = to_drm_vblank_work(base);
+	struct intel_crtc *crtc = container_of(work, struct intel_crtc,
+					       fbc_work);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	intel_fbc_hw_activate(dev_priv);
+}
+
+void intel_crtc_fbc_work_init(struct intel_crtc *crtc)
+{
+	drm_vblank_work_init(&crtc->fbc_work, &crtc->base,
+			     intel_fbc_vblank_work);
+}
+
 /**
  * intel_fbc_init - Initialize FBC
  * @dev_priv: the i915 device
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h
index 6dc1edefe81b..d1befa585f21 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc.h
@@ -36,5 +36,5 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
 void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
 void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv);
 int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv);
-
+void intel_crtc_fbc_work_init(struct intel_crtc *crtc);
 #endif /* __INTEL_FBC_H__ */
-- 
2.26.2



More information about the Intel-gfx-trybot mailing list