@@ -1990,6 +1990,7 @@ void intel_color_prepare_commit(struct intel_atomic_state *state,
intel_vrr_send_push(crtc_state->dsb_color_vblank, crtc_state);
intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank);
+ intel_vrr_dsb_wait_push_sent(crtc_state->dsb_color_vblank, crtc_state);
intel_dsb_interrupt(crtc_state->dsb_color_vblank);
intel_dsb_finish(crtc_state->dsb_color_vblank);
@@ -7732,6 +7732,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state,
intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state);
intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit);
+ intel_vrr_dsb_wait_push_sent(new_crtc_state->dsb_commit, new_crtc_state);
intel_dsb_interrupt(new_crtc_state->dsb_commit);
}
}
@@ -5,6 +5,7 @@
*/
#include "i915_reg.h"
+#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dp.h"
@@ -416,6 +417,36 @@ void intel_vrr_send_push(struct intel_dsb *dsb,
intel_dsb_nonpost_end(dsb);
}
+void intel_vrr_dsb_wait_push_sent(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+ int wait, count;
+
+ /* not to be used in mmio codepaths */
+ if (drm_WARN_ON(display->drm, !dsb))
+ return;
+
+ /*
+ * We always do the send after the "wait for safe window", thus
+ * the push should happen within ~1 scanline. Poll for ~2 scanlines
+ * to make sure it does. If the bit does not clear DSB will raise
+ * the poll error interrupt as an indication that we failed to
+ * sequence things correctly.
+ *
+ * Note that vblank delay does postpone the bit clearing, but
+ * we can ignore that by assuming that our caller has already
+ * dealt with it via intel_dsb_wait_vblank_delay() after
+ * triggering the push.
+ */
+ wait = 2; /* usecs */
+ count = DIV_ROUND_UP(intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode, 2), wait);
+
+ intel_dsb_poll(dsb, TRANS_PUSH(display, cpu_transcoder),
+ TRANS_PUSH_SEND, 0, wait, count);
+}
+
bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
@@ -25,6 +25,8 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
void intel_vrr_enable(const struct intel_crtc_state *crtc_state);
void intel_vrr_send_push(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state);
+void intel_vrr_dsb_wait_push_sent(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state);
bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state);
void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state);
void intel_vrr_get_config(struct intel_crtc_state *crtc_state);