[PATCH 28/51] drm/i915: Update queue_flip() to do explicit request management

John.C.Harrison
2015-02-13T11:49:32Z

From: John Harrison <John.C.Harrison@Intel.com>

Updated the display page flip code to do explicit request creation and
submission rather than relying on the OLR and just hoping that the request
actually gets submitted at some random point.

The sequence is now to create a request, queue the work to the ring, assign the
known request to the flip queue work item then actually submit the work and post
the request.

For: VIZ-5115
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/intel_display.c | 47 ++++++++++++++++++++-----------
drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +-
drivers/gpu/drm/i915/intel_ringbuffer.h | 1 -
4 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e5132d3..4b82b2e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -559,7 +559,7 @@ struct drm_i915_display_funcs {
int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags);
void (*update_primary_plane)(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ebf973c..f23f28e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9201,9 +9201,10 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
+ struct intel_engine_cs *ring = req->ring;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 flip_mask;
int ret;
@@ -9228,7 +9229,6 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, 0); /* aux display base address, unused */

intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
return 0;
}

@@ -9236,9 +9236,10 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
+ struct intel_engine_cs *ring = req->ring;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 flip_mask;
int ret;
@@ -9260,7 +9261,6 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, MI_NOOP);

intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
return 0;
}

@@ -9268,9 +9268,10 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
+ struct intel_engine_cs *ring = req->ring;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pf, pipesrc;
@@ -9299,7 +9300,6 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, pf | pipesrc);

intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
return 0;
}

@@ -9307,9 +9307,10 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
+ struct intel_engine_cs *ring = req->ring;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pf, pipesrc;
@@ -9335,7 +9336,6 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, pf | pipesrc);

intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
return 0;
}

@@ -9343,9 +9343,10 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
+ struct intel_engine_cs *ring = req->ring;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t plane_bit = 0;
int len, ret;
@@ -9430,7 +9431,6 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, (MI_NOOP));

intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
return 0;
}

@@ -9586,9 +9586,10 @@ static int intel_gen9_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
+ struct intel_engine_cs *ring = req->ring;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t plane = 0, stride;
int ret;
@@ -9640,7 +9641,6 @@ static int intel_gen9_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);

intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);

return 0;
}
@@ -9649,7 +9649,7 @@ static int intel_default_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req,
uint32_t flags)
{
return -ENODEV;
@@ -9728,6 +9728,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
enum pipe pipe = intel_crtc->pipe;
struct intel_unpin_work *work;
struct intel_engine_cs *ring;
+ struct drm_i915_gem_request *request;
int ret;

/*
@@ -9847,13 +9848,20 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
i915_gem_request_assign(&work->flip_queued_req,
obj->last_write_req);
} else {
- ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring,
- page_flip_flags);
+ ret = dev_priv->gt.alloc_request(ring, ring->default_context, &request);
if (ret)
goto cleanup_unpin;

- i915_gem_request_assign(&work->flip_queued_req,
- intel_ring_get_request(ring));
+ ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
+ page_flip_flags);
+ if (ret)
+ goto cleanup_request;
+
+ i915_gem_request_assign(&work->flip_queued_req, request);
+
+ ret = i915_add_request_no_flush(request->ring);
+ if (ret)
+ goto cleanup_request_assign;
}

work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe);
@@ -9870,6 +9878,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,

return 0;

+cleanup_request_assign:
+ i915_gem_request_assign(&work->flip_queued_req, NULL);
+cleanup_request:
+ i915_gem_request_unreference(request);
+
cleanup_unpin:
intel_unpin_fb_obj(obj);
cleanup_pending:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index c7a9192..9a0e944 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -81,7 +81,7 @@ bool intel_ring_stopped(struct intel_engine_cs *ring)
return dev_priv->gpu_error.stop_rings & intel_ring_flag(ring);
}

-void __intel_ring_advance(struct intel_engine_cs *ring)
+static void __intel_ring_advance(struct intel_engine_cs *ring)
{
struct intel_ringbuffer *ringbuf = ring->buffer;
ringbuf->tail &= ringbuf->size - 1;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 36631e2..582b0ec 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -410,7 +410,6 @@ int __intel_ring_space(int head, int tail, int size);
void intel_ring_update_space(struct intel_ringbuffer *ringbuf);
int intel_ring_space(struct intel_ringbuffer *ringbuf);
bool intel_ring_stopped(struct intel_engine_cs *ring);
-void __intel_ring_advance(struct intel_engine_cs *ring);

int __must_check intel_ring_idle(struct intel_engine_cs *ring);
void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno);
--
1.7.9.5