[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