summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_crtc.h
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2021-10-21 01:33:38 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2021-11-10 00:27:08 +0200
commit2bbc6fcaf8c58a7a59900512be11b1775a611381 (patch)
tree54cd4eeee78b013a0e211a0805e052fa0d8cf8c7 /drivers/gpu/drm/i915/display/intel_crtc.h
parent6f9976bd1310d123921ba2c20e8c101057087285 (diff)
drm/i915: Use vblank workers for gamma updates
The pipe gamma registers are single buffered so they should only be updated during the vblank to avoid screen tearing. In fact they really should only be updated between start of vblank and frame start because that is the only time the pipe is guaranteed to be empty. Already at frame start the pipe begins to fill up with data for the next frame. Unfortunately frame start happens ~1 scanline after the start of vblank which in practice doesn't always leave us enough time to finish the gamma update in time (gamma LUTs can be several KiB of data we have to bash into the registers). However we must try our best and so we'll add a vblank work for each pipe from where we can do the gamma update. Additionally we could consider pushing frame start forward to the max of ~4 scanlines after start of vblank. But not sure that's exactly a validated configuration. As it stands the ~100 first pixels tend to make it through with the old gamma values. Even though the vblank worker is running on a high prority thread we still have to contend with C-states. If the CPU happens be in a deep C-state when the vblank interrupt arrives even the irq handler gets delayed massively (I've observed dozens of scanlines worth of latency). To avoid that problem we'll use the qos mechanism to keep the CPU awake while the vblank work is scheduled. With all this hooked up we can finally enjoy near atomic gamma updates. It even works across several pipes from the same atomic commit which previously was a total fail because we did the gamma updates for each pipe serially after waiting for all pipes to have latched the double buffered registers. In the future the DSB should take over this responsibility which will hopefully avoid some of these issues. Kudos to Lyude for finishing the actual vblank workers. Works like the proverbial train toilet. v2: Add missing intel_atomic_state fwd declaration v3: Clean up properly when not scheduling the worker v4: Clean up the rest and add tracepoints v5: s/intel_wait_for_vblank_works/intel_wait_for_vblank_workers/ (Jani,Uma) CC: Lyude Paul <lyude@redhat.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211020223339.669-4-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_crtc.h')
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.h4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
index 22363fbbc925..a0039fdb1eb0 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.h
+++ b/drivers/gpu/drm/i915/display/intel_crtc.h
@@ -11,6 +11,7 @@
enum pipe;
struct drm_display_mode;
struct drm_i915_private;
+struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
@@ -24,7 +25,8 @@ void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);
void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state);
void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state);
-void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state);
+void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state);
void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state);
+void intel_wait_for_vblank_workers(struct intel_atomic_state *state);
#endif