> -----Original Message----- > From: Intel-xe <intel-xe-boun...@lists.freedesktop.org> On Behalf Of Ville > Syrjala > Sent: Friday, May 16, 2025 5:04 PM > To: intel-gfx@lists.freedesktop.org > Cc: intel...@lists.freedesktop.org > Subject: [PATCH 08/12] drm/i915/flipq: Implement flipq queue based commit > path
Nit: Drop the redundant q from flipq Looks Good to me. Reviewed-by: Uma Shankar <uma.shan...@intel.com> > > From: Ville Syrjälä <ville.syrj...@linux.intel.com> > > Support commits via the flip queue (as opposed to DSB or MMIO). > > As it's somewhat unknown if we can actually use it is currently gated behind > the > new use_flipq modparam, which defaults to disabled. > > The implementation has a bunch of limitations that would need real though to > solve: > - disabled when PSR is used > - disabled when VRR is used > - color management updates not performed via the flip queue > > Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> > --- > drivers/gpu/drm/i915/display/intel_display.c | 63 +++++++++++++------ > .../drm/i915/display/intel_display_params.c | 3 + > .../drm/i915/display/intel_display_params.h | 1 + > .../drm/i915/display/intel_display_types.h | 3 + > drivers/gpu/drm/i915/display/intel_dmc.c | 20 +++++- > 5 files changed, 71 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c > b/drivers/gpu/drm/i915/display/intel_display.c > index 1b09f8ae76ff..3a42536247d8 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.c > +++ b/drivers/gpu/drm/i915/display/intel_display.c > @@ -93,6 +93,7 @@ > #include "intel_fbc.h" > #include "intel_fdi.h" > #include "intel_fifo_underrun.h" > +#include "intel_flipq.h" > #include "intel_frontbuffer.h" > #include "intel_hdmi.h" > #include "intel_hotplug.h" > @@ -6610,7 +6611,7 @@ static void commit_pipe_pre_planes(struct > intel_atomic_state *state, > intel_atomic_get_new_crtc_state(state, crtc); > bool modeset = intel_crtc_needs_modeset(new_crtc_state); > > - drm_WARN_ON(display->drm, new_crtc_state->use_dsb); > + drm_WARN_ON(display->drm, new_crtc_state->use_dsb || > +new_crtc_state->use_flipq); > > /* > * During modesets pipe configuration was programmed as the @@ - > 6639,7 +6640,7 @@ static void commit_pipe_post_planes(struct > intel_atomic_state *state, > const struct intel_crtc_state *new_crtc_state = > intel_atomic_get_new_crtc_state(state, crtc); > > - drm_WARN_ON(display->drm, new_crtc_state->use_dsb); > + drm_WARN_ON(display->drm, new_crtc_state->use_dsb || > +new_crtc_state->use_flipq); > > /* > * Disable the scaler(s) after the plane(s) so that we don't @@ -6723,10 > +6724,10 @@ static void intel_pre_update_crtc(struct intel_atomic_state > *state, > > if (!modeset && > intel_crtc_needs_color_update(new_crtc_state) && > - !new_crtc_state->use_dsb) > + !new_crtc_state->use_dsb && !new_crtc_state->use_flipq) > intel_color_commit_noarm(NULL, new_crtc_state); > > - if (!new_crtc_state->use_dsb) > + if (!new_crtc_state->use_dsb && !new_crtc_state->use_flipq) > intel_crtc_planes_update_noarm(NULL, state, crtc); } > > @@ -6738,7 +6739,14 @@ static void intel_update_crtc(struct > intel_atomic_state *state, > struct intel_crtc_state *new_crtc_state = > intel_atomic_get_new_crtc_state(state, crtc); > > - if (new_crtc_state->use_dsb) { > + if (new_crtc_state->use_flipq) { > + intel_flipq_enable(new_crtc_state); > + > + intel_crtc_prepare_vblank_event(new_crtc_state, &crtc- > >flipq_event); > + > + intel_flipq_add(crtc, INTEL_FLIPQ_PLANE_1, 0, INTEL_DSB_0, > + new_crtc_state->dsb_commit); > + } else if (new_crtc_state->use_dsb) { > intel_crtc_prepare_vblank_event(new_crtc_state, &crtc- > >dsb_event); > > intel_dsb_commit(new_crtc_state->dsb_commit, false); @@ - > 7176,7 +7184,18 @@ static void intel_atomic_dsb_prepare(struct > intel_atomic_state *state, > return; > > /* FIXME deal with everything */ > + new_crtc_state->use_flipq = > + display->params.enable_flipq && > + DISPLAY_VER(display) >= 20 && > + !new_crtc_state->do_async_flip && > + !new_crtc_state->vrr.enable && > + !new_crtc_state->has_psr && > + !intel_crtc_needs_modeset(new_crtc_state) && > + !intel_crtc_needs_fastset(new_crtc_state) && > + !intel_crtc_needs_color_update(new_crtc_state); > + > new_crtc_state->use_dsb = > + !new_crtc_state->use_flipq && > !new_crtc_state->do_async_flip && > (DISPLAY_VER(display) >= 20 || !new_crtc_state->has_psr) && > !intel_crtc_needs_modeset(new_crtc_state) && @@ -7192,7 > +7211,9 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state > *state, > struct intel_crtc_state *new_crtc_state = > intel_atomic_get_new_crtc_state(state, crtc); > > - if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color_vblank) > + if (!new_crtc_state->use_flipq && > + !new_crtc_state->use_dsb && > + !new_crtc_state->dsb_color_vblank) > return; > > /* > @@ -7201,14 +7222,16 @@ static void intel_atomic_dsb_finish(struct > intel_atomic_state *state, > * Double that for pipe stuff and other overhead. > */ > new_crtc_state->dsb_commit = intel_dsb_prepare(state, crtc, > INTEL_DSB_0, > - new_crtc_state->use_dsb ? > 1024 : 16); > + new_crtc_state->use_dsb > || > + new_crtc_state->use_flipq > ? 1024 : 16); > if (!new_crtc_state->dsb_commit) { > + new_crtc_state->use_flipq = false; > new_crtc_state->use_dsb = false; > intel_color_cleanup_commit(new_crtc_state); > return; > } > > - if (new_crtc_state->use_dsb) { > + if (new_crtc_state->use_flipq || new_crtc_state->use_dsb) { > if (intel_crtc_needs_color_update(new_crtc_state)) > intel_color_commit_noarm(new_crtc_state- > >dsb_commit, > new_crtc_state); > @@ -7223,7 +7246,8 @@ static void intel_atomic_dsb_finish(struct > intel_atomic_state *state, > intel_psr_trigger_frame_change_event(new_crtc_state- > >dsb_commit, > state, crtc); > > - intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit); > + if (new_crtc_state->use_dsb) > + intel_dsb_vblank_evade(state, new_crtc_state- > >dsb_commit); > > if (intel_crtc_needs_color_update(new_crtc_state)) > intel_color_commit_arm(new_crtc_state->dsb_commit, > @@ -7238,21 +7262,21 @@ static void intel_atomic_dsb_finish(struct > intel_atomic_state *state, > if (DISPLAY_VER(display) >= 9) > skl_detach_scalers(new_crtc_state->dsb_commit, > new_crtc_state); > - > - if (!new_crtc_state->dsb_color_vblank) { > - intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, > 1); > - > - 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_check_push_sent(new_crtc_state- > >dsb_commit, new_crtc_state); > - intel_dsb_interrupt(new_crtc_state->dsb_commit); > - } > } > > if (new_crtc_state->dsb_color_vblank) > intel_dsb_chain(state, new_crtc_state->dsb_commit, > new_crtc_state->dsb_color_vblank, true); > > + if (new_crtc_state->use_dsb && !new_crtc_state->dsb_color_vblank) { > + intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1); > + > + 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_check_push_sent(new_crtc_state->dsb_commit, > new_crtc_state); > + intel_dsb_interrupt(new_crtc_state->dsb_commit); > + } > + > intel_dsb_finish(new_crtc_state->dsb_commit); > } > > @@ -7397,6 +7421,9 @@ static void intel_atomic_commit_tail(struct > intel_atomic_state *state) > > if (!state->base.legacy_cursor_update && !new_crtc_state- > >use_dsb) > intel_vrr_check_push_sent(NULL, new_crtc_state); > + > + if (new_crtc_state->use_flipq) > + intel_flipq_disable(new_crtc_state); > } > > /* > diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c > b/drivers/gpu/drm/i915/display/intel_display_params.c > index c4f1ab43fc0c..75316247ee8a 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_params.c > +++ b/drivers/gpu/drm/i915/display/intel_display_params.c > @@ -62,6 +62,9 @@ intel_display_param_named_unsafe(enable_dpt, bool, > 0400, intel_display_param_named_unsafe(enable_dsb, bool, 0400, > "Enable display state buffer (DSB) (default: true)"); > > +intel_display_param_named_unsafe(enable_flipq, bool, 0400, > + "Enable DMC flip queue (default: false)"); > + > intel_display_param_named_unsafe(enable_sagv, bool, 0400, > "Enable system agent voltage/frequency scaling (SAGV) (default: true)"); > > diff --git a/drivers/gpu/drm/i915/display/intel_display_params.h > b/drivers/gpu/drm/i915/display/intel_display_params.h > index 5317138e6044..784e6bae8615 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_params.h > +++ b/drivers/gpu/drm/i915/display/intel_display_params.h > @@ -31,6 +31,7 @@ struct drm_printer; > param(int, enable_dc, -1, 0400) \ > param(bool, enable_dpt, true, 0400) \ > param(bool, enable_dsb, true, 0600) \ > + param(bool, enable_flipq, false, 0600) \ > param(bool, enable_sagv, true, 0600) \ > param(int, disable_power_well, -1, 0400) \ > param(bool, enable_ips, true, 0600) \ > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index 2f3fdf292d88..dd87099823d2 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -1299,6 +1299,7 @@ struct intel_crtc_state { > /* For DSB based pipe updates */ > struct intel_dsb *dsb_color_vblank, *dsb_commit; > bool use_dsb; > + bool use_flipq; > > u32 psr2_man_track_ctl; > > @@ -1406,6 +1407,8 @@ struct intel_crtc { > struct drm_pending_vblank_event *flip_done_event; > /* armed event for DSB based updates */ > struct drm_pending_vblank_event *dsb_event; > + /* armed event for flip queue based updates */ > + struct drm_pending_vblank_event *flipq_event; > > /* Access to these should be protected by display->irq.lock. */ > bool cpu_fifo_underrun_disabled; > diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c > b/drivers/gpu/drm/i915/display/intel_dmc.c > index 7b28da58faec..10d1be68df79 100644 > --- a/drivers/gpu/drm/i915/display/intel_dmc.c > +++ b/drivers/gpu/drm/i915/display/intel_dmc.c > @@ -502,7 +502,8 @@ static u32 pipedmc_interrupt_mask(struct intel_display > *display) > * triggering it during the first DC state transition. Figure > * out what is going on... > */ > - return PIPEDMC_GTT_FAULT | > + return PIPEDMC_FLIPQ_PROG_DONE | > + PIPEDMC_GTT_FAULT | > PIPEDMC_ATS_FAULT; > } > > @@ -1486,6 +1487,23 @@ void intel_pipedmc_irq_handler(struct intel_display > *display, enum pipe pipe) > tmp = intel_de_read(display, PIPEDMC_INTERRUPT(pipe)); > intel_de_write(display, PIPEDMC_INTERRUPT(pipe), tmp); > > + if (tmp & PIPEDMC_FLIPQ_PROG_DONE) { > + spin_lock(&display->drm->event_lock); > + > + if (crtc->flipq_event) { > + /* > + * Update vblank counter/timestamp in case it > + * hasn't been done yet for this frame. > + */ > + drm_crtc_accurate_vblank_count(&crtc->base); > + > + drm_crtc_send_vblank_event(&crtc->base, > crtc->flipq_event); > + crtc->flipq_event = NULL; > + } > + > + spin_unlock(&display->drm->event_lock); > + } > + > if (tmp & PIPEDMC_ATS_FAULT) > drm_err_ratelimited(display->drm, "[CRTC:%d:%s] > PIPEDMC ATS fault\n", > crtc->base.base.id, crtc- > >base.name); > -- > 2.49.0