drm/i915: Move vblank evasion to commit (v4)
Move the vblank evasion up from the low-level, hw-specific
update_plane() handlers to the general plane commit operation.
Everything inside commit should now be non-sleeping, so this brings us
closer to how vblank evasion will behave once we move over to atomic.
v2:
- Restore lost intel_crtc->active check on vblank evasion
v3:
- Replace assert_pipe_enabled() in intel_disable_primary_hw_plane()
with an intel_crtc->active test; it turns out assert_pipe_enabled()
grabs some mutexes and can sleep, which we can't do with interrupts
disabled.
v4:
- Equivalent to v2; v3 change is now squashed into an earlier patch
of the series. (Ander).
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 260b91c..b7c59d5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11864,6 +11864,12 @@
intel_update_watermarks(crtc);
intel_runtime_pm_get(dev_priv);
+
+ /* Perform vblank evasion around commit operation */
+ if (intel_crtc->active)
+ intel_crtc->atomic.evade =
+ intel_pipe_update_start(intel_crtc,
+ &intel_crtc->atomic.start_vbl_count);
}
static void intel_finish_crtc_commit(struct drm_crtc *crtc)
@@ -11873,6 +11879,10 @@
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_plane *p;
+ if (intel_crtc->atomic.evade)
+ intel_pipe_update_end(intel_crtc,
+ intel_crtc->atomic.start_vbl_count);
+
intel_runtime_pm_put(dev_priv);
if (intel_crtc->atomic.wait_vblank)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d70bcc4..8051468 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -428,6 +428,10 @@
* and thus can't be run with interrupts disabled.
*/
struct intel_crtc_atomic_commit {
+ /* vblank evasion */
+ bool evade;
+ unsigned start_vbl_count;
+
/* Sleepable operations to perform before commit */
bool wait_for_flips;
bool disable_fbc;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 3e6e95f..1dfdccb 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -412,8 +412,6 @@
u32 sprctl;
unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
- u32 start_vbl_count;
- bool atomic_update;
sprctl = I915_READ(SPCNTR(pipe, plane));
@@ -502,8 +500,6 @@
linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
}
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
intel_update_primary_plane(intel_crtc);
if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
@@ -525,9 +521,6 @@
sprsurf_offset);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void
@@ -539,10 +532,6 @@
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_plane->pipe;
int plane = intel_plane->plane;
- u32 start_vbl_count;
- bool atomic_update;
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -553,9 +542,6 @@
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
-
intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
}
@@ -626,8 +612,6 @@
u32 sprctl, sprscale = 0;
unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
- u32 start_vbl_count;
- bool atomic_update;
sprctl = I915_READ(SPRCTL(pipe));
@@ -711,8 +695,6 @@
}
}
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
intel_update_primary_plane(intel_crtc);
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
@@ -735,9 +717,6 @@
i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void
@@ -748,10 +727,6 @@
struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_plane->pipe;
- u32 start_vbl_count;
- bool atomic_update;
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -764,9 +739,6 @@
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
-
/*
* Avoid underruns when disabling the sprite.
* FIXME remove once watermark updates are done properly.
@@ -845,8 +817,6 @@
unsigned long dvssurf_offset, linear_offset;
u32 dvscntr, dvsscale;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
- u32 start_vbl_count;
- bool atomic_update;
dvscntr = I915_READ(DVSCNTR(pipe));
@@ -921,8 +891,6 @@
linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
}
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
intel_update_primary_plane(intel_crtc);
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
@@ -940,9 +908,6 @@
i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void
@@ -953,10 +918,6 @@
struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_plane->pipe;
- u32 start_vbl_count;
- bool atomic_update;
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -968,9 +929,6 @@
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
-
/*
* Avoid underruns when disabling the sprite.
* FIXME remove once watermark updates are done properly.