mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
drm/i915: Do vblank evasion correctly if vrr push has already been sent
Let's adjust the vblank evasion to account for the case where a push has already been sent. In that case the vblank exit will start at vmin vblank start (as opposed to vmax vblank start when no push has been sent). This should minimize the effects of the tiny race between sampling the frame counter vs. intel_vrr_send_push() during the previous frame. This will also be required if we want to do mailbox style updates with vrr since then we'd definitely do multiple commits per frame. Currently mailbox updates are only used by the legacy cursor, but we don't do vrr push for those. Cc: Manasi Navare <manasi.d.navare@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211117183103.27418-2-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
This commit is contained in:
parent
4765d061d5
commit
0088d39b6a
|
|
@ -470,10 +470,14 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state)
|
|||
if (intel_crtc_needs_vblank_work(new_crtc_state))
|
||||
intel_crtc_vblank_work_init(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->vrr.enable)
|
||||
vblank_start = intel_vrr_vmax_vblank_start(new_crtc_state);
|
||||
else
|
||||
if (new_crtc_state->vrr.enable) {
|
||||
if (intel_vrr_is_push_sent(new_crtc_state))
|
||||
vblank_start = intel_vrr_vmin_vblank_start(new_crtc_state);
|
||||
else
|
||||
vblank_start = intel_vrr_vmax_vblank_start(new_crtc_state);
|
||||
} else {
|
||||
vblank_start = intel_mode_vblank_start(adjusted_mode);
|
||||
}
|
||||
|
||||
/* FIXME needs to be calibrated sensibly */
|
||||
min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
|
||||
|
|
|
|||
|
|
@ -193,6 +193,18 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
|
|||
TRANS_PUSH_EN | TRANS_PUSH_SEND);
|
||||
}
|
||||
|
||||
bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
|
||||
if (!crtc_state->vrr.enable)
|
||||
return false;
|
||||
|
||||
return intel_de_read(dev_priv, TRANS_PUSH(cpu_transcoder)) & TRANS_PUSH_SEND;
|
||||
}
|
||||
|
||||
void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ void intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
|
|||
void intel_vrr_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_vrr_send_push(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 *crtc,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user