aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_overlay.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2009-09-15 16:57:36 -0400
committerEric Anholt <eric@anholt.net>2009-11-05 17:47:09 -0500
commit5a5a0c64a99d7542c48c99d1a8bbb49e665842be (patch)
treef915bb581b83247df2bc508d899dd379455119e1 /drivers/gpu/drm/i915/intel_overlay.c
parent240a2d12dfff98f8fa1332dc8424284d96f0801e (diff)
drm/i915: implement fastpath for overlay flip waiting
As long as the gpu can keep up, neither the cpu (waiting for gpu) nore the gpu (waiting for vblank to do an overlay flip) stalls. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_overlay.c')
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 4e88abb423b0..85e07e4459ce 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -251,7 +251,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
251 drm_i915_private_t *dev_priv = dev->dev_private; 251 drm_i915_private_t *dev_priv = dev->dev_private;
252 u32 flip_addr = overlay->flip_addr; 252 u32 flip_addr = overlay->flip_addr;
253 u32 tmp; 253 u32 tmp;
254 int ret;
255 RING_LOCALS; 254 RING_LOCALS;
256 255
257 BUG_ON(!overlay->active); 256 BUG_ON(!overlay->active);
@@ -264,11 +263,40 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
264 if (tmp & (1 << 17)) 263 if (tmp & (1 << 17))
265 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); 264 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
266 265
267 BEGIN_LP_RING(6); 266 BEGIN_LP_RING(4);
268 OUT_RING(MI_FLUSH); 267 OUT_RING(MI_FLUSH);
269 OUT_RING(MI_NOOP); 268 OUT_RING(MI_NOOP);
270 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 269 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
271 OUT_RING(flip_addr); 270 OUT_RING(flip_addr);
271 ADVANCE_LP_RING();
272
273 overlay->last_flip_req = i915_add_request(dev, NULL, 0);
274}
275
276static int intel_overlay_wait_flip(struct intel_overlay *overlay)
277{
278 struct drm_device *dev = overlay->dev;
279 drm_i915_private_t *dev_priv = dev->dev_private;
280 int ret;
281 u32 tmp;
282 RING_LOCALS;
283
284 if (overlay->last_flip_req != 0) {
285 ret = i915_do_wait_request(dev, overlay->last_flip_req, 0);
286
287 if (ret != 0)
288 return ret;
289
290 overlay->last_flip_req = 0;
291
292 tmp = I915_READ(ISR);
293
294 if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT))
295 return 0;
296 }
297
298 /* synchronous slowpath */
299 BEGIN_LP_RING(2);
272 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 300 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
273 OUT_RING(MI_NOOP); 301 OUT_RING(MI_NOOP);
274 ADVANCE_LP_RING(); 302 ADVANCE_LP_RING();
@@ -279,13 +307,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
279 DRM_ERROR("intel overlay: ring sync failed, hw likely wedged\n"); 307 DRM_ERROR("intel overlay: ring sync failed, hw likely wedged\n");
280 overlay->hw_wedged = 1; 308 overlay->hw_wedged = 1;
281 } 309 }
282}
283 310
284static int intel_overlay_wait_flip(struct intel_overlay *overlay) 311 return ret;
285{
286 /* don't overcomplicate things for now with asynchronous operations
287 * see comment above */
288 return 0;
289} 312}
290 313
291/* overlay needs to be disabled in OCMD reg */ 314/* overlay needs to be disabled in OCMD reg */
@@ -344,7 +367,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
344 return ret; 367 return ret;
345} 368}
346 369
347/* wait for pending overlay flip and release old frame */ 370/* Wait for pending overlay flip and release old frame.
371 * Needs to be called before the overlay register are changed
372 * via intel_overlay_(un)map_regs_atomic */
348static int intel_overlay_release_old_vid(struct intel_overlay *overlay) 373static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
349{ 374{
350 int ret; 375 int ret;