From f5f7381e9bea1a40df48673c385f7bb008602b34 Mon Sep 17 00:00:00 2001 From: jsg Date: Mon, 29 Apr 2024 06:19:53 +0000 Subject: [PATCH] drm/i915: Enable VRR later during fastsets From Ville Syrjala deaeb5b64c5b8a7b681acaf721d040b1fe9dcc53 in linux-6.6.y/6.6.29 691dec86acc3afb469f09e9a4a00508b458bdb0c in mainline linux --- sys/dev/pci/drm/i915/display/intel_crtc.c | 35 ++++++++++++-------- sys/dev/pci/drm/i915/display/intel_display.c | 21 ++++++++---- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/sys/dev/pci/drm/i915/display/intel_crtc.c b/sys/dev/pci/drm/i915/display/intel_crtc.c index 9693747a18c..5c89eba8148 100644 --- a/sys/dev/pci/drm/i915/display/intel_crtc.c +++ b/sys/dev/pci/drm/i915/display/intel_crtc.c @@ -472,15 +472,31 @@ static void intel_crtc_vblank_evade_scanlines(struct intel_atomic_state *state, struct intel_crtc *crtc, int *min, int *max, int *vblank_start) { + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode; + const struct intel_crtc_state *crtc_state; + const struct drm_display_mode *adjusted_mode; - 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); + /* + * During fastsets/etc. the transcoder is still + * running with the old timings at this point. + * + * TODO: maybe just use the active timings here? + */ + if (intel_crtc_needs_modeset(new_crtc_state)) + crtc_state = new_crtc_state; + else + crtc_state = old_crtc_state; + + adjusted_mode = &crtc_state->hw.adjusted_mode; + + if (crtc->mode_flags & I915_MODE_FLAG_VRR) { + if (intel_vrr_is_push_sent(crtc_state)) + *vblank_start = intel_vrr_vmin_vblank_start(crtc_state); else - *vblank_start = intel_vrr_vmax_vblank_start(new_crtc_state); + *vblank_start = intel_vrr_vmax_vblank_start(crtc_state); } else { *vblank_start = intel_mode_vblank_start(adjusted_mode); } @@ -712,15 +728,6 @@ void intel_pipe_update_end(struct intel_atomic_state *state, */ intel_vrr_send_push(new_crtc_state); - /* - * Seamless M/N update may need to update frame timings. - * - * FIXME Should be synchronized with the start of vblank somehow... - */ - if (new_crtc_state->seamless_m_n && intel_crtc_needs_fastset(new_crtc_state)) - intel_crtc_update_active_timings(new_crtc_state, - new_crtc_state->vrr.enable); - local_irq_enable(); if (intel_vgpu_active(dev_priv)) diff --git a/sys/dev/pci/drm/i915/display/intel_display.c b/sys/dev/pci/drm/i915/display/intel_display.c index f1b01d42fea..1adc281085c 100644 --- a/sys/dev/pci/drm/i915/display/intel_display.c +++ b/sys/dev/pci/drm/i915/display/intel_display.c @@ -6533,6 +6533,8 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -6544,6 +6546,9 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) >= 9 && !intel_crtc_needs_modeset(new_crtc_state)) skl_detach_scalers(new_crtc_state); + + if (vrr_enabling(old_crtc_state, new_crtc_state)) + intel_vrr_enable(new_crtc_state); } static void intel_enable_crtc(struct intel_atomic_state *state, @@ -6584,12 +6589,6 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_dpt_configure(crtc); } - if (vrr_enabling(old_crtc_state, new_crtc_state)) { - intel_vrr_enable(new_crtc_state); - intel_crtc_update_active_timings(new_crtc_state, - new_crtc_state->vrr.enable); - } - if (!modeset) { if (new_crtc_state->preload_luts && intel_crtc_needs_color_update(new_crtc_state)) @@ -6626,6 +6625,16 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_pipe_update_end(state, crtc); + /* + * VRR/Seamless M/N update may need to update frame timings. + * + * FIXME Should be synchronized with the start of vblank somehow... + */ + if (vrr_enabling(old_crtc_state, new_crtc_state) || + (new_crtc_state->seamless_m_n && intel_crtc_needs_fastset(new_crtc_state))) + intel_crtc_update_active_timings(new_crtc_state, + new_crtc_state->vrr.enable); + /* * We usually enable FIFO underrun interrupts as part of the * CRTC enable sequence during modesets. But when we inherit a -- 2.20.1