From a6910434e1b5f2a9fe7cab39b01bae9a7a7bbe70 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 2 Feb 2010 17:08:37 +0100 Subject: drm/i915: only one interrupt per batchbuffer is not enough! Previously I thought that one interrupt per batchbuffer should be enough. Now tedious benchmarking showed this to be wrong. Therefore track whether any commands have been isssued with a future seqno (like pipelined fencing changes or flushes). If this is the case emit a request before issueing the batchbuffer. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 525e7d3edda..d3e5f40a804 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -83,6 +83,11 @@ struct intel_ring_buffer { */ struct list_head request_list; + /** + * Do we have some not yet emitted requests outstanding? + */ + bool outstanding_lazy_request; + wait_queue_head_t irq_queue; drm_local_map_t map; }; -- cgit v1.2.3-70-g09d2 From 2b6efaa47615b29e572d7fc444565db62ca9bcf7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Sep 2010 17:04:02 +0100 Subject: drm/i915: Remove unused intel_ringbuffer->ring_flag This can always be re-added should somebody find a use... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 5 ++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 -- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 02719df418e..a83574df096 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1580,9 +1580,8 @@ i915_gem_process_flushing_list(struct drm_device *dev, gpu_write_list) { struct drm_gem_object *obj = &obj_priv->base; - if ((obj->write_domain & flush_domains) == - obj->write_domain && - obj_priv->ring->ring_flag == ring->ring_flag) { + if (obj->write_domain & flush_domains && + obj_priv->ring == ring) { uint32_t old_write_domain = obj->write_domain; obj->write_domain = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1ae2b25bf7e..11bcfc871a0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -805,7 +805,6 @@ struct intel_ring_buffer render_ring = { .tail = PRB0_TAIL, .start = PRB0_START }, - .ring_flag = I915_EXEC_RENDER, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, .virtual_start = NULL, @@ -843,7 +842,6 @@ struct intel_ring_buffer bsd_ring = { .tail = BSD_RING_TAIL, .start = BSD_RING_START }, - .ring_flag = I915_EXEC_BSD, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, .virtual_start = NULL, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d3e5f40a804..fa5d84f85c2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -16,7 +16,6 @@ struct intel_ring_buffer { u32 tail; u32 start; } regs; - unsigned int ring_flag; unsigned long size; unsigned int alignment; void *virtual_start; -- cgit v1.2.3-70-g09d2 From 9220434a8768902cd9cf248709972678b74aa8c1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 18 Sep 2010 11:02:01 +0100 Subject: drm/i915: Only emit a flush request on the active ring. When flushing the GPU domains,we emit a flush on *both* rings, even though they share a unified cache. Only emit the flush on the currently active ring. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 5 ++- drivers/gpu/drm/i915/i915_gem.c | 58 ++++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +++ 4 files changed, 51 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4b6aeb5e66b..ed09846fac7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -623,6 +623,8 @@ typedef struct drm_i915_private { /* storage for physical objects */ struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; + + uint32_t flush_rings; } mm; struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ @@ -1014,9 +1016,6 @@ int i915_do_wait_request(struct drm_device *dev, bool interruptible, struct intel_ring_buffer *ring); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); -void i915_gem_process_flushing_list(struct drm_device *dev, - uint32_t flush_domains, - struct intel_ring_buffer *ring); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write); int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1c02798bb7e..cf2765529cf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1567,7 +1567,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) i915_verify_inactive(dev, __FILE__, __LINE__); } -void +static void i915_gem_process_flushing_list(struct drm_device *dev, uint32_t flush_domains, struct intel_ring_buffer *ring) @@ -1879,24 +1879,37 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno, return i915_do_wait_request(dev, seqno, 1, ring); } +static void +i915_gem_flush_ring(struct drm_device *dev, + struct intel_ring_buffer *ring, + uint32_t invalidate_domains, + uint32_t flush_domains) +{ + ring->flush(dev, ring, invalidate_domains, flush_domains); + i915_gem_process_flushing_list(dev, flush_domains, ring); +} + static void i915_gem_flush(struct drm_device *dev, uint32_t invalidate_domains, - uint32_t flush_domains) + uint32_t flush_domains, + uint32_t flush_rings) { drm_i915_private_t *dev_priv = dev->dev_private; if (flush_domains & I915_GEM_DOMAIN_CPU) drm_agp_chipset_flush(dev); - dev_priv->render_ring.flush(dev, &dev_priv->render_ring, - invalidate_domains, - flush_domains); - - if (HAS_BSD(dev)) - dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring, - invalidate_domains, - flush_domains); + if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { + if (flush_rings & RING_RENDER) + i915_gem_flush_ring(dev, + &dev_priv->render_ring, + invalidate_domains, flush_domains); + if (flush_rings & RING_BSD) + i915_gem_flush_ring(dev, + &dev_priv->bsd_ring, + invalidate_domains, flush_domains); + } } /** @@ -2022,7 +2035,9 @@ i915_gpu_idle(struct drm_device *dev) return 0; /* Flush everything onto the inactive list. */ - i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + i915_gem_flush_ring(dev, + &dev_priv->render_ring, + I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); ret = i915_wait_request(dev, i915_gem_next_request_seqno(dev, &dev_priv->render_ring), @@ -2031,6 +2046,10 @@ i915_gpu_idle(struct drm_device *dev) return ret; if (HAS_BSD(dev)) { + i915_gem_flush_ring(dev, + &dev_priv->bsd_ring, + I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + ret = i915_wait_request(dev, i915_gem_next_request_seqno(dev, &dev_priv->bsd_ring), &dev_priv->bsd_ring); @@ -2598,7 +2617,9 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, /* Queue the GPU write cache flushing we need. */ old_write_domain = obj->write_domain; - i915_gem_flush(dev, 0, obj->write_domain); + i915_gem_flush_ring(dev, + to_intel_bo(obj)->ring, + 0, obj->write_domain); BUG_ON(obj->write_domain); trace_i915_gem_object_change_domain(obj, @@ -2908,6 +2929,7 @@ static void i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; @@ -2972,6 +2994,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) dev->invalidate_domains |= invalidate_domains; dev->flush_domains |= flush_domains; + if (obj_priv->ring) + dev_priv->mm.flush_rings |= obj_priv->ring->id; #if WATCH_BUF DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n", __func__, @@ -3684,6 +3708,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, */ dev->invalidate_domains = 0; dev->flush_domains = 0; + dev_priv->mm.flush_rings = 0; for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; @@ -3703,7 +3728,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, #endif i915_gem_flush(dev, dev->invalidate_domains, - dev->flush_domains); + dev->flush_domains, + dev_priv->mm.flush_rings); } if (dev_priv->render_ring.outstanding_lazy_request) { @@ -4170,8 +4196,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * use this buffer rather sooner than later, so issuing the required * flush earlier is beneficial. */ - if (obj->write_domain) { - i915_gem_flush(dev, 0, obj->write_domain); + if (obj->write_domain & I915_GEM_GPU_DOMAINS) { + i915_gem_flush_ring(dev, + obj_priv->ring, + 0, obj->write_domain); (void)i915_add_request(dev, file_priv, NULL, obj_priv->ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 670f94af6b0..45f66e289af 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -116,8 +116,6 @@ render_ring_flush(struct drm_device *dev, intel_ring_emit(dev, ring, MI_NOOP); intel_ring_advance(dev, ring); } - - i915_gem_process_flushing_list(dev, flush_domains, ring); } static unsigned int render_ring_get_head(struct drm_device *dev, @@ -386,8 +384,6 @@ bsd_ring_flush(struct drm_device *dev, intel_ring_emit(dev, ring, MI_FLUSH); intel_ring_emit(dev, ring, MI_NOOP); intel_ring_advance(dev, ring); - - i915_gem_process_flushing_list(dev, flush_domains, ring); } static inline unsigned int bsd_ring_get_head(struct drm_device *dev, @@ -799,6 +795,7 @@ void intel_fill_struct(struct drm_device *dev, struct intel_ring_buffer render_ring = { .name = "render ring", + .id = RING_RENDER, .regs = { .ctl = PRB0_CTL, .head = PRB0_HEAD, @@ -836,6 +833,7 @@ struct intel_ring_buffer render_ring = { struct intel_ring_buffer bsd_ring = { .name = "bsd ring", + .id = RING_BSD, .regs = { .ctl = BSD_RING_CTL, .head = BSD_RING_HEAD, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index fa5d84f85c2..8dc0e62b7d2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -10,6 +10,10 @@ struct intel_hw_status_page { struct drm_i915_gem_execbuffer2; struct intel_ring_buffer { const char *name; + enum intel_ring_id { + RING_RENDER = 0x1, + RING_BSD = 0x2, + } id; struct ring_regs { u32 ctl; u32 head; -- cgit v1.2.3-70-g09d2 From 5c1143bbecf50184ff7cad6287b4e0993bacbd9f Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 16 Sep 2010 10:43:11 +0800 Subject: drm/i915: do not export the instances of struct intel_ring_buffer Introduce intel_init_render_ring_buffer(), intel_init_bsd_ring_buffer for ring initialization. Signed-off-by: Xiang, Haihao Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 14 ++------------ drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- 3 files changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 325f52bc140..7b33b4d5ebf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4496,28 +4496,18 @@ i915_gem_init_ringbuffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; int ret; - dev_priv->render_ring = render_ring; - - if (!I915_NEED_GFX_HWS(dev)) { - dev_priv->render_ring.status_page.page_addr - = dev_priv->status_page_dmah->vaddr; - memset(dev_priv->render_ring.status_page.page_addr, - 0, PAGE_SIZE); - } - if (HAS_PIPE_CONTROL(dev)) { ret = i915_gem_init_pipe_control(dev); if (ret) return ret; } - ret = intel_init_ring_buffer(dev, &dev_priv->render_ring); + ret = intel_init_render_ring_buffer(dev); if (ret) goto cleanup_pipe_control; if (HAS_BSD(dev)) { - dev_priv->bsd_ring = bsd_ring; - ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring); + ret = intel_init_bsd_ring_buffer(dev); if (ret) goto cleanup_render_ring; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 45f66e289af..178e2cea983 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -793,7 +793,7 @@ void intel_fill_struct(struct drm_device *dev, intel_ring_advance(dev, ring); } -struct intel_ring_buffer render_ring = { +static struct intel_ring_buffer render_ring = { .name = "render ring", .id = RING_RENDER, .regs = { @@ -831,7 +831,7 @@ struct intel_ring_buffer render_ring = { /* ring buffer for bit-stream decoder */ -struct intel_ring_buffer bsd_ring = { +static struct intel_ring_buffer bsd_ring = { .name = "bsd ring", .id = RING_BSD, .regs = { @@ -866,3 +866,28 @@ struct intel_ring_buffer bsd_ring = { .status_page = {NULL, 0, NULL}, .map = {0,} }; + +int intel_init_render_ring_buffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + dev_priv->render_ring = render_ring; + + if (!I915_NEED_GFX_HWS(dev)) { + dev_priv->render_ring.status_page.page_addr + = dev_priv->status_page_dmah->vaddr; + memset(dev_priv->render_ring.status_page.page_addr, + 0, PAGE_SIZE); + } + + return intel_init_ring_buffer(dev, &dev_priv->render_ring); +} + +int intel_init_bsd_ring_buffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + dev_priv->bsd_ring = bsd_ring; + + return intel_init_ring_buffer(dev, &dev_priv->bsd_ring); +} diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 8dc0e62b7d2..5603d6e945e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -133,7 +133,7 @@ void intel_ring_advance(struct drm_device *dev, u32 intel_ring_get_seqno(struct drm_device *dev, struct intel_ring_buffer *ring); -extern struct intel_ring_buffer render_ring; -extern struct intel_ring_buffer bsd_ring; +int intel_init_render_ring_buffer(struct drm_device *dev); +int intel_init_bsd_ring_buffer(struct drm_device *dev); #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3-70-g09d2 From d46eefa29724b1be0e8e90a3a51a190b912ebfab Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 16 Sep 2010 10:43:12 +0800 Subject: drm/i915: add set_tail hook in struct intel_ring_buffer This is prepared for video codec ring buffer on Sandybridge. It is needed to read/write more than one register to move the tail pointer of the video codec ring on Sandybridge. Signed-off-by: Xiang, Haihao Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 22 +++++++++++++++++----- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++ 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 178e2cea983..7debb1972eb 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -132,6 +132,12 @@ static unsigned int render_ring_get_tail(struct drm_device *dev, return I915_READ(PRB0_TAIL) & TAIL_ADDR; } +static inline void render_ring_set_tail(struct drm_device *dev, u32 value) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + I915_WRITE(PRB0_TAIL, value); +} + static unsigned int render_ring_get_active_head(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -144,8 +150,7 @@ static unsigned int render_ring_get_active_head(struct drm_device *dev, static void render_ring_advance_ring(struct drm_device *dev, struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(PRB0_TAIL, ring->tail); + render_ring_set_tail(dev, ring->tail); } static int init_ring_common(struct drm_device *dev, @@ -159,7 +164,7 @@ static int init_ring_common(struct drm_device *dev, /* Stop the ring if it's running. */ I915_WRITE(ring->regs.ctl, 0); I915_WRITE(ring->regs.head, 0); - I915_WRITE(ring->regs.tail, 0); + ring->set_tail(dev, 0); /* Initialize the ring. */ I915_WRITE(ring->regs.start, obj_priv->gtt_offset); @@ -400,6 +405,12 @@ static inline unsigned int bsd_ring_get_tail(struct drm_device *dev, return I915_READ(BSD_RING_TAIL) & TAIL_ADDR; } +static inline void bsd_ring_set_tail(struct drm_device *dev, u32 value) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + I915_WRITE(BSD_RING_TAIL, value); +} + static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -410,8 +421,7 @@ static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, static inline void bsd_ring_advance_ring(struct drm_device *dev, struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(BSD_RING_TAIL, ring->tail); + bsd_ring_set_tail(dev, ring->tail); } static int init_bsd_ring(struct drm_device *dev, @@ -817,6 +827,7 @@ static struct intel_ring_buffer render_ring = { .init = init_render_ring, .get_head = render_ring_get_head, .get_tail = render_ring_get_tail, + .set_tail = render_ring_set_tail, .get_active_head = render_ring_get_active_head, .advance_ring = render_ring_advance_ring, .flush = render_ring_flush, @@ -855,6 +866,7 @@ static struct intel_ring_buffer bsd_ring = { .init = init_bsd_ring, .get_head = bsd_ring_get_head, .get_tail = bsd_ring_get_tail, + .set_tail = bsd_ring_set_tail, .get_active_head = bsd_ring_get_active_head, .advance_ring = bsd_ring_advance_ring, .flush = bsd_ring_flush, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 5603d6e945e..7bd571c796a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -48,6 +48,8 @@ struct intel_ring_buffer { struct intel_ring_buffer *ring); unsigned int (*get_tail)(struct drm_device *dev, struct intel_ring_buffer *ring); + void (*set_tail)(struct drm_device *dev, + u32 value); unsigned int (*get_active_head)(struct drm_device *dev, struct intel_ring_buffer *ring); void (*advance_ring)(struct drm_device *dev, -- cgit v1.2.3-70-g09d2 From a3f07cd53e31c1c27364e56266a541b9467c1895 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 19 Sep 2010 14:36:46 +0100 Subject: drm/i915/ringbuffer: Implement advance using set_tail As noted by Zhenyu, we can now simply replace the existing advance hook by calling the new set_tail function pointer directly. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 16 +--------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 -- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7debb1972eb..3f80f18e284 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -147,12 +147,6 @@ static unsigned int render_ring_get_active_head(struct drm_device *dev, return I915_READ(acthd_reg); } -static void render_ring_advance_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - render_ring_set_tail(dev, ring->tail); -} - static int init_ring_common(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -418,12 +412,6 @@ static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, return I915_READ(BSD_RING_ACTHD); } -static inline void bsd_ring_advance_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - bsd_ring_set_tail(dev, ring->tail); -} - static int init_bsd_ring(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -785,7 +773,7 @@ void intel_ring_advance(struct drm_device *dev, struct intel_ring_buffer *ring) { ring->tail &= ring->size - 1; - ring->advance_ring(dev, ring); + ring->set_tail(dev, ring->tail); } void intel_fill_struct(struct drm_device *dev, @@ -829,7 +817,6 @@ static struct intel_ring_buffer render_ring = { .get_tail = render_ring_get_tail, .set_tail = render_ring_set_tail, .get_active_head = render_ring_get_active_head, - .advance_ring = render_ring_advance_ring, .flush = render_ring_flush, .add_request = render_ring_add_request, .get_gem_seqno = render_ring_get_gem_seqno, @@ -868,7 +855,6 @@ static struct intel_ring_buffer bsd_ring = { .get_tail = bsd_ring_get_tail, .set_tail = bsd_ring_set_tail, .get_active_head = bsd_ring_get_active_head, - .advance_ring = bsd_ring_advance_ring, .flush = bsd_ring_flush, .add_request = bsd_ring_add_request, .get_gem_seqno = bsd_ring_get_gem_seqno, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 7bd571c796a..be1fd9b3708 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -52,8 +52,6 @@ struct intel_ring_buffer { u32 value); unsigned int (*get_active_head)(struct drm_device *dev, struct intel_ring_buffer *ring); - void (*advance_ring)(struct drm_device *dev, - struct intel_ring_buffer *ring); void (*flush)(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, -- cgit v1.2.3-70-g09d2 From 333e9fe94d00ce8c334d91099449b9948bf76b92 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Aug 2010 16:24:01 +0200 Subject: drm/i915: add relative ring register macros Documentation explicitly mentions that the ring registers are designed to have the same offsets relative to a base registers. Use this to fight the code beaurocratic in intel_ringbuffer.c. No code changes in this patch, just the new definitions. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 3 files changed, 12 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8b8ac60cc83..77c9191f3fd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -288,6 +288,14 @@ #define PRB0_HEAD 0x02034 #define PRB0_START 0x02038 #define PRB0_CTL 0x0203c +#define RENDER_RING_BASE 0x02000 +#define BSD_RING_BASE 0x04000 +#define GEN6_BSD_RING_BASE 0x12000 +#define RING_TAIL(base) (base)+0x30 +#define RING_HEAD(base) (base)+0x34 +#define RING_START(base) (base)+0x38 +#define RING_CTL(base) (base)+0x3c +#define RING_HWS_PGA(base) (base)+0x80 #define TAIL_ADDR 0x001FFFF8 #define HEAD_WRAP_COUNT 0xFFE00000 #define HEAD_WRAP_ONE 0x00200000 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f0b44d3ba95..c1517b2d2f0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -801,6 +801,7 @@ static const struct intel_ring_buffer render_ring = { .tail = PRB0_TAIL, .start = PRB0_START }, + .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, .virtual_start = NULL, @@ -839,6 +840,7 @@ static const struct intel_ring_buffer bsd_ring = { .tail = BSD_RING_TAIL, .start = BSD_RING_START }, + .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, .virtual_start = NULL, @@ -957,6 +959,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .tail = GEN6_BSD_RING_TAIL, .start = GEN6_BSD_RING_START }, + .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, .virtual_start = NULL, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index be1fd9b3708..3917d8b1c1a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -20,6 +20,7 @@ struct intel_ring_buffer { u32 tail; u32 start; } regs; + u32 mmio_base; unsigned long size; unsigned int alignment; void *virtual_start; -- cgit v1.2.3-70-g09d2 From 870e86ddc2d110124812b277643ed0f2767148ee Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Aug 2010 16:29:44 +0200 Subject: drm/i915: use new macros to access the ring tail register Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 63 +++++++++------------------------ drivers/gpu/drm/i915/intel_ringbuffer.h | 9 ++--- 2 files changed, 22 insertions(+), 50 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c1517b2d2f0..4b797e7dc95 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -126,17 +126,12 @@ static unsigned int render_ring_get_head(struct drm_device *dev, return I915_READ(PRB0_HEAD) & HEAD_ADDR; } -static unsigned int render_ring_get_tail(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(PRB0_TAIL) & TAIL_ADDR; -} - -static inline void render_ring_set_tail(struct drm_device *dev, u32 value) +static void ring_set_tail(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 value) { drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(PRB0_TAIL, value); + I915_WRITE_TAIL(ring, ring->tail); } static unsigned int render_ring_get_active_head(struct drm_device *dev, @@ -159,7 +154,7 @@ static int init_ring_common(struct drm_device *dev, /* Stop the ring if it's running. */ I915_WRITE(ring->regs.ctl, 0); I915_WRITE(ring->regs.head, 0); - ring->set_tail(dev, 0); + ring->set_tail(dev, ring, 0); /* Initialize the ring. */ I915_WRITE(ring->regs.start, obj_priv->gtt_offset); @@ -172,7 +167,7 @@ static int init_ring_common(struct drm_device *dev, ring->name, I915_READ(ring->regs.ctl), I915_READ(ring->regs.head), - I915_READ(ring->regs.tail), + I915_READ_TAIL(ring), I915_READ(ring->regs.start)); I915_WRITE(ring->regs.head, 0); @@ -182,7 +177,7 @@ static int init_ring_common(struct drm_device *dev, ring->name, I915_READ(ring->regs.ctl), I915_READ(ring->regs.head), - I915_READ(ring->regs.tail), + I915_READ_TAIL(ring), I915_READ(ring->regs.start)); } @@ -198,7 +193,7 @@ static int init_ring_common(struct drm_device *dev, ring->name, I915_READ(ring->regs.ctl), I915_READ(ring->regs.head), - I915_READ(ring->regs.tail), + I915_READ_TAIL(ring), I915_READ(ring->regs.start)); return -EIO; } @@ -207,7 +202,7 @@ static int init_ring_common(struct drm_device *dev, i915_kernel_lost_context(dev); else { ring->head = ring->get_head(dev, ring); - ring->tail = ring->get_tail(dev, ring); + ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; @@ -393,19 +388,6 @@ static inline unsigned int bsd_ring_get_head(struct drm_device *dev, return I915_READ(BSD_RING_HEAD) & HEAD_ADDR; } -static inline unsigned int bsd_ring_get_tail(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(BSD_RING_TAIL) & TAIL_ADDR; -} - -static inline void bsd_ring_set_tail(struct drm_device *dev, u32 value) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(BSD_RING_TAIL, value); -} - static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -620,6 +602,7 @@ err: int intel_init_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv; struct drm_gem_object *obj; int ret; @@ -668,7 +651,7 @@ int intel_init_ring_buffer(struct drm_device *dev, i915_kernel_lost_context(dev); else { ring->head = ring->get_head(dev, ring); - ring->tail = ring->get_tail(dev, ring); + ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; @@ -774,7 +757,7 @@ void intel_ring_advance(struct drm_device *dev, struct intel_ring_buffer *ring) { ring->tail &= ring->size - 1; - ring->set_tail(dev, ring->tail); + ring->set_tail(dev, ring, ring->tail); } void intel_fill_struct(struct drm_device *dev, @@ -798,7 +781,6 @@ static const struct intel_ring_buffer render_ring = { .regs = { .ctl = PRB0_CTL, .head = PRB0_HEAD, - .tail = PRB0_TAIL, .start = PRB0_START }, .mmio_base = RENDER_RING_BASE, @@ -816,8 +798,7 @@ static const struct intel_ring_buffer render_ring = { .setup_status_page = render_setup_status_page, .init = init_render_ring, .get_head = render_ring_get_head, - .get_tail = render_ring_get_tail, - .set_tail = render_ring_set_tail, + .set_tail = ring_set_tail, .get_active_head = render_ring_get_active_head, .flush = render_ring_flush, .add_request = render_ring_add_request, @@ -837,7 +818,6 @@ static const struct intel_ring_buffer bsd_ring = { .regs = { .ctl = BSD_RING_CTL, .head = BSD_RING_HEAD, - .tail = BSD_RING_TAIL, .start = BSD_RING_START }, .mmio_base = BSD_RING_BASE, @@ -855,8 +835,7 @@ static const struct intel_ring_buffer bsd_ring = { .setup_status_page = bsd_setup_status_page, .init = init_bsd_ring, .get_head = bsd_ring_get_head, - .get_tail = bsd_ring_get_tail, - .set_tail = bsd_ring_set_tail, + .set_tail = ring_set_tail, .get_active_head = bsd_ring_get_active_head, .flush = bsd_ring_flush, .add_request = bsd_ring_add_request, @@ -884,15 +863,9 @@ static inline unsigned int gen6_bsd_ring_get_head(struct drm_device *dev, return I915_READ(GEN6_BSD_RING_HEAD) & HEAD_ADDR; } -static inline unsigned int gen6_bsd_ring_get_tail(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(GEN6_BSD_RING_TAIL) & TAIL_ADDR; -} - static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, - u32 value) + struct intel_ring_buffer *ring, + u32 value) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -907,7 +880,7 @@ static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, 50)) DRM_ERROR("timed out waiting for IDLE Indicator\n"); - I915_WRITE(GEN6_BSD_RING_TAIL, value); + I915_WRITE_TAIL(ring, value); I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); @@ -956,7 +929,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .regs = { .ctl = GEN6_BSD_RING_CTL, .head = GEN6_BSD_RING_HEAD, - .tail = GEN6_BSD_RING_TAIL, .start = GEN6_BSD_RING_START }, .mmio_base = GEN6_BSD_RING_BASE, @@ -974,7 +946,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .setup_status_page = gen6_bsd_setup_status_page, .init = init_bsd_ring, .get_head = gen6_bsd_ring_get_head, - .get_tail = gen6_bsd_ring_get_tail, .set_tail = gen6_bsd_ring_set_tail, .get_active_head = gen6_bsd_ring_get_active_head, .flush = gen6_bsd_ring_flush, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3917d8b1c1a..2dfcd9bad3c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -7,6 +7,9 @@ struct intel_hw_status_page { struct drm_gem_object *obj; }; +#define I915_READ_TAIL(ring) I915_READ(RING_TAIL(ring->mmio_base)) +#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) + struct drm_i915_gem_execbuffer2; struct intel_ring_buffer { const char *name; @@ -17,7 +20,6 @@ struct intel_ring_buffer { struct ring_regs { u32 ctl; u32 head; - u32 tail; u32 start; } regs; u32 mmio_base; @@ -47,10 +49,9 @@ struct intel_ring_buffer { unsigned int (*get_head)(struct drm_device *dev, struct intel_ring_buffer *ring); - unsigned int (*get_tail)(struct drm_device *dev, - struct intel_ring_buffer *ring); void (*set_tail)(struct drm_device *dev, - u32 value); + struct intel_ring_buffer *ring, + u32 value); unsigned int (*get_active_head)(struct drm_device *dev, struct intel_ring_buffer *ring); void (*flush)(struct drm_device *dev, -- cgit v1.2.3-70-g09d2 From 6c0e1c556ee659cd8c976cd175c0b70e209acb92 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Aug 2010 16:33:33 +0200 Subject: drm/i915: use new macros to access the ring start register Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 ++- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4b797e7dc95..395c4d34b1e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -157,7 +157,7 @@ static int init_ring_common(struct drm_device *dev, ring->set_tail(dev, ring, 0); /* Initialize the ring. */ - I915_WRITE(ring->regs.start, obj_priv->gtt_offset); + I915_WRITE_START(ring, obj_priv->gtt_offset); head = ring->get_head(dev, ring); /* G45 ring initialization fails to reset head to zero */ @@ -168,7 +168,7 @@ static int init_ring_common(struct drm_device *dev, I915_READ(ring->regs.ctl), I915_READ(ring->regs.head), I915_READ_TAIL(ring), - I915_READ(ring->regs.start)); + I915_READ_START(ring)); I915_WRITE(ring->regs.head, 0); @@ -178,7 +178,7 @@ static int init_ring_common(struct drm_device *dev, I915_READ(ring->regs.ctl), I915_READ(ring->regs.head), I915_READ_TAIL(ring), - I915_READ(ring->regs.start)); + I915_READ_START(ring)); } I915_WRITE(ring->regs.ctl, @@ -194,7 +194,7 @@ static int init_ring_common(struct drm_device *dev, I915_READ(ring->regs.ctl), I915_READ(ring->regs.head), I915_READ_TAIL(ring), - I915_READ(ring->regs.start)); + I915_READ_START(ring)); return -EIO; } @@ -781,7 +781,6 @@ static const struct intel_ring_buffer render_ring = { .regs = { .ctl = PRB0_CTL, .head = PRB0_HEAD, - .start = PRB0_START }, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, @@ -818,7 +817,6 @@ static const struct intel_ring_buffer bsd_ring = { .regs = { .ctl = BSD_RING_CTL, .head = BSD_RING_HEAD, - .start = BSD_RING_START }, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, @@ -929,7 +927,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .regs = { .ctl = GEN6_BSD_RING_CTL, .head = GEN6_BSD_RING_HEAD, - .start = GEN6_BSD_RING_START }, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 2dfcd9bad3c..9d0ae5ad7e5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -9,6 +9,8 @@ struct intel_hw_status_page { #define I915_READ_TAIL(ring) I915_READ(RING_TAIL(ring->mmio_base)) #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) +#define I915_READ_START(ring) I915_READ(RING_START(ring->mmio_base)) +#define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) struct drm_i915_gem_execbuffer2; struct intel_ring_buffer { @@ -20,7 +22,6 @@ struct intel_ring_buffer { struct ring_regs { u32 ctl; u32 head; - u32 start; } regs; u32 mmio_base; unsigned long size; -- cgit v1.2.3-70-g09d2 From 570ef608591aa1c7f7cb615c2d33b30246179da1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Aug 2010 17:06:23 +0200 Subject: drm/i915: use new macros to access the ring head register Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 48 ++++++++------------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ++-- 2 files changed, 13 insertions(+), 40 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 395c4d34b1e..7eb936a315b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -119,13 +119,6 @@ render_ring_flush(struct drm_device *dev, } } -static unsigned int render_ring_get_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(PRB0_HEAD) & HEAD_ADDR; -} - static void ring_set_tail(struct drm_device *dev, struct intel_ring_buffer *ring, u32 value) @@ -153,12 +146,12 @@ static int init_ring_common(struct drm_device *dev, /* Stop the ring if it's running. */ I915_WRITE(ring->regs.ctl, 0); - I915_WRITE(ring->regs.head, 0); + I915_WRITE_HEAD(ring, 0); ring->set_tail(dev, ring, 0); /* Initialize the ring. */ I915_WRITE_START(ring, obj_priv->gtt_offset); - head = ring->get_head(dev, ring); + head = I915_READ_HEAD(ring) & HEAD_ADDR; /* G45 ring initialization fails to reset head to zero */ if (head != 0) { @@ -166,17 +159,17 @@ static int init_ring_common(struct drm_device *dev, "ctl %08x head %08x tail %08x start %08x\n", ring->name, I915_READ(ring->regs.ctl), - I915_READ(ring->regs.head), + I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); - I915_WRITE(ring->regs.head, 0); + I915_WRITE_HEAD(ring, 0); DRM_ERROR("%s head forced to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, I915_READ(ring->regs.ctl), - I915_READ(ring->regs.head), + I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); } @@ -185,14 +178,14 @@ static int init_ring_common(struct drm_device *dev, ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | RING_NO_REPORT | RING_VALID); - head = I915_READ(ring->regs.head) & HEAD_ADDR; + head = I915_READ_HEAD(ring) & HEAD_ADDR; /* If the head is still not zero, the ring is dead */ if (head != 0) { DRM_ERROR("%s initialization failed " "ctl %08x head %08x tail %08x start %08x\n", ring->name, I915_READ(ring->regs.ctl), - I915_READ(ring->regs.head), + I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); return -EIO; @@ -201,7 +194,7 @@ static int init_ring_common(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_kernel_lost_context(dev); else { - ring->head = ring->get_head(dev, ring); + ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) @@ -381,13 +374,6 @@ bsd_ring_flush(struct drm_device *dev, intel_ring_advance(dev, ring); } -static inline unsigned int bsd_ring_get_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(BSD_RING_HEAD) & HEAD_ADDR; -} - static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -650,7 +636,7 @@ int intel_init_ring_buffer(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_kernel_lost_context(dev); else { - ring->head = ring->get_head(dev, ring); + ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) @@ -716,11 +702,12 @@ int intel_wait_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring, int n) { unsigned long end; + drm_i915_private_t *dev_priv = dev->dev_private; trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; do { - ring->head = ring->get_head(dev, ring); + ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; @@ -780,7 +767,6 @@ static const struct intel_ring_buffer render_ring = { .id = RING_RENDER, .regs = { .ctl = PRB0_CTL, - .head = PRB0_HEAD, }, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, @@ -796,7 +782,6 @@ static const struct intel_ring_buffer render_ring = { .waiting_gem_seqno = 0, .setup_status_page = render_setup_status_page, .init = init_render_ring, - .get_head = render_ring_get_head, .set_tail = ring_set_tail, .get_active_head = render_ring_get_active_head, .flush = render_ring_flush, @@ -816,7 +801,6 @@ static const struct intel_ring_buffer bsd_ring = { .id = RING_BSD, .regs = { .ctl = BSD_RING_CTL, - .head = BSD_RING_HEAD, }, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, @@ -832,7 +816,6 @@ static const struct intel_ring_buffer bsd_ring = { .waiting_gem_seqno = 0, .setup_status_page = bsd_setup_status_page, .init = init_bsd_ring, - .get_head = bsd_ring_get_head, .set_tail = ring_set_tail, .get_active_head = bsd_ring_get_active_head, .flush = bsd_ring_flush, @@ -854,13 +837,6 @@ static void gen6_bsd_setup_status_page(struct drm_device *dev, I915_READ(GEN6_BSD_HWS_PGA); } -static inline unsigned int gen6_bsd_ring_get_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(GEN6_BSD_RING_HEAD) & HEAD_ADDR; -} - static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, struct intel_ring_buffer *ring, u32 value) @@ -926,7 +902,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .id = RING_BSD, .regs = { .ctl = GEN6_BSD_RING_CTL, - .head = GEN6_BSD_RING_HEAD, }, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, @@ -942,7 +917,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .waiting_gem_seqno = 0, .setup_status_page = gen6_bsd_setup_status_page, .init = init_bsd_ring, - .get_head = gen6_bsd_ring_get_head, .set_tail = gen6_bsd_ring_set_tail, .get_active_head = gen6_bsd_ring_get_active_head, .flush = gen6_bsd_ring_flush, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 9d0ae5ad7e5..af09eaa84be 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -11,6 +11,8 @@ struct intel_hw_status_page { #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) #define I915_READ_START(ring) I915_READ(RING_START(ring->mmio_base)) #define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) +#define I915_READ_HEAD(ring) I915_READ(RING_HEAD(ring->mmio_base)) +#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD(ring->mmio_base), val) struct drm_i915_gem_execbuffer2; struct intel_ring_buffer { @@ -21,7 +23,6 @@ struct intel_ring_buffer { } id; struct ring_regs { u32 ctl; - u32 head; } regs; u32 mmio_base; unsigned long size; @@ -48,8 +49,6 @@ struct intel_ring_buffer { int (*init)(struct drm_device *dev, struct intel_ring_buffer *ring); - unsigned int (*get_head)(struct drm_device *dev, - struct intel_ring_buffer *ring); void (*set_tail)(struct drm_device *dev, struct intel_ring_buffer *ring, u32 value); -- cgit v1.2.3-70-g09d2 From 7f2ab69913135f0377a1dfc1da5695b64107d3ca Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Aug 2010 17:06:59 +0200 Subject: drm/i915: use new macros to access the ring ctl register Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 19 +++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ++--- 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7eb936a315b..1198b6097be 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -145,7 +145,7 @@ static int init_ring_common(struct drm_device *dev, obj_priv = to_intel_bo(ring->gem_object); /* Stop the ring if it's running. */ - I915_WRITE(ring->regs.ctl, 0); + I915_WRITE_CTL(ring, 0); I915_WRITE_HEAD(ring, 0); ring->set_tail(dev, ring, 0); @@ -158,7 +158,7 @@ static int init_ring_common(struct drm_device *dev, DRM_ERROR("%s head not reset to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, - I915_READ(ring->regs.ctl), + I915_READ_CTL(ring), I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); @@ -168,13 +168,13 @@ static int init_ring_common(struct drm_device *dev, DRM_ERROR("%s head forced to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, - I915_READ(ring->regs.ctl), + I915_READ_CTL(ring), I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); } - I915_WRITE(ring->regs.ctl, + I915_WRITE_CTL(ring, ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | RING_NO_REPORT | RING_VALID); @@ -184,7 +184,7 @@ static int init_ring_common(struct drm_device *dev, DRM_ERROR("%s initialization failed " "ctl %08x head %08x tail %08x start %08x\n", ring->name, - I915_READ(ring->regs.ctl), + I915_READ_CTL(ring), I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); @@ -765,9 +765,6 @@ void intel_fill_struct(struct drm_device *dev, static const struct intel_ring_buffer render_ring = { .name = "render ring", .id = RING_RENDER, - .regs = { - .ctl = PRB0_CTL, - }, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, @@ -799,9 +796,6 @@ static const struct intel_ring_buffer render_ring = { static const struct intel_ring_buffer bsd_ring = { .name = "bsd ring", .id = RING_BSD, - .regs = { - .ctl = BSD_RING_CTL, - }, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, @@ -900,9 +894,6 @@ gen6_bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, static const struct intel_ring_buffer gen6_bsd_ring = { .name = "gen6 bsd ring", .id = RING_BSD, - .regs = { - .ctl = GEN6_BSD_RING_CTL, - }, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, .alignment = PAGE_SIZE, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index af09eaa84be..1668cd9ac87 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -13,6 +13,8 @@ struct intel_hw_status_page { #define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) #define I915_READ_HEAD(ring) I915_READ(RING_HEAD(ring->mmio_base)) #define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD(ring->mmio_base), val) +#define I915_READ_CTL(ring) I915_READ(RING_CTL(ring->mmio_base)) +#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL(ring->mmio_base), val) struct drm_i915_gem_execbuffer2; struct intel_ring_buffer { @@ -21,9 +23,6 @@ struct intel_ring_buffer { RING_RENDER = 0x1, RING_BSD = 0x2, } id; - struct ring_regs { - u32 ctl; - } regs; u32 mmio_base; unsigned long size; unsigned int alignment; -- cgit v1.2.3-70-g09d2 From a9db5c8fdd8c6e6e966897e05e2c2acd99bcdb6e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Aug 2010 17:22:48 +0200 Subject: drm/i915: drop alignment ringbuffer parameter Always PAGE_SIZE and only complicates the code. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +---- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d395d055328..c9894c2bcd6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -610,7 +610,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->gem_object = obj; - ret = i915_gem_object_pin(obj, ring->alignment); + ret = i915_gem_object_pin(obj, PAGE_SIZE); if (ret) goto err_unref; @@ -767,7 +767,6 @@ static const struct intel_ring_buffer render_ring = { .id = RING_RENDER, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, - .alignment = PAGE_SIZE, .setup_status_page = render_setup_status_page, .init = init_render_ring, .set_tail = ring_set_tail, @@ -787,7 +786,6 @@ static const struct intel_ring_buffer bsd_ring = { .id = RING_BSD, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .alignment = PAGE_SIZE, .setup_status_page = bsd_setup_status_page, .init = init_bsd_ring, .set_tail = ring_set_tail, @@ -874,7 +872,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .id = RING_BSD, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .alignment = PAGE_SIZE, .setup_status_page = gen6_bsd_setup_status_page, .init = init_bsd_ring, .set_tail = gen6_bsd_ring_set_tail, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 1668cd9ac87..abf8a4e25a2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -25,7 +25,6 @@ struct intel_ring_buffer { } id; u32 mmio_base; unsigned long size; - unsigned int alignment; void *virtual_start; struct drm_device *dev; struct drm_gem_object *gem_object; -- cgit v1.2.3-70-g09d2 From ab6f8e325083f138ce5da8417baf48887d62da3c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 19 Sep 2010 17:53:44 +0100 Subject: drm/i915/ringbuffer: whitespace cleanup Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 123 +++++++++++++++++--------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 10 ++- 2 files changed, 68 insertions(+), 65 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c9894c2bcd6..1bcea7c8523 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -50,9 +50,9 @@ static u32 i915_gem_get_seqno(struct drm_device *dev) static void render_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { drm_i915_private_t *dev_priv = dev->dev_private; u32 cmd; @@ -128,7 +128,7 @@ static void ring_set_tail(struct drm_device *dev, } static unsigned int render_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; u32 acthd_reg = INTEL_INFO(dev)->gen ? ACTHD_I965 : ACTHD; @@ -137,7 +137,7 @@ static unsigned int render_ring_get_active_head(struct drm_device *dev, } static int init_ring_common(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { u32 head; drm_i915_private_t *dev_priv = dev->dev_private; @@ -204,7 +204,7 @@ static int init_ring_common(struct drm_device *dev, } static int init_render_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; int ret = init_ring_common(dev, ring); @@ -238,9 +238,9 @@ do { \ */ static u32 render_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_file *file_priv, - u32 flush_domains) + struct intel_ring_buffer *ring, + struct drm_file *file_priv, + u32 flush_domains) { drm_i915_private_t *dev_priv = dev->dev_private; u32 seqno; @@ -304,7 +304,7 @@ render_ring_add_request(struct drm_device *dev, static u32 render_ring_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; if (HAS_PIPE_CONTROL(dev)) @@ -315,7 +315,7 @@ render_ring_get_gem_seqno(struct drm_device *dev, static void render_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; @@ -332,7 +332,7 @@ render_ring_get_user_irq(struct drm_device *dev, static void render_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; @@ -349,7 +349,7 @@ render_ring_put_user_irq(struct drm_device *dev, } static void render_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; if (IS_GEN6(dev)) { @@ -362,7 +362,7 @@ static void render_setup_status_page(struct drm_device *dev, } -void +static void bsd_ring_flush(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, @@ -374,24 +374,24 @@ bsd_ring_flush(struct drm_device *dev, intel_ring_advance(dev, ring); } -static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) +static unsigned int bsd_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; return I915_READ(BSD_RING_ACTHD); } static int init_bsd_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { return init_ring_common(dev, ring); } static u32 bsd_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_file *file_priv, - u32 flush_domains) + struct intel_ring_buffer *ring, + struct drm_file *file_priv, + u32 flush_domains) { u32 seqno; @@ -411,7 +411,7 @@ bsd_ring_add_request(struct drm_device *dev, } static void bsd_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr); @@ -420,30 +420,30 @@ static void bsd_setup_status_page(struct drm_device *dev, static void bsd_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { /* do nothing */ } static void bsd_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { /* do nothing */ } static u32 bsd_ring_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } static int bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { uint32_t exec_start; exec_start = (uint32_t) exec_offset + exec->batch_start_offset; @@ -458,10 +458,10 @@ bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, static int render_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { drm_i915_private_t *dev_priv = dev->dev_private; int nbox = exec->num_cliprects; @@ -520,7 +520,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, } static void cleanup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; @@ -540,7 +540,7 @@ static void cleanup_status_page(struct drm_device *dev, } static int init_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; @@ -584,9 +584,8 @@ err: return ret; } - int intel_init_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv; @@ -659,7 +658,7 @@ err_hws: } void intel_cleanup_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { if (ring->gem_object == NULL) return; @@ -672,8 +671,8 @@ void intel_cleanup_ring_buffer(struct drm_device *dev, cleanup_status_page(dev, ring); } -int intel_wrap_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int intel_wrap_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring) { unsigned int *virt; int rem; @@ -699,7 +698,7 @@ int intel_wrap_ring_buffer(struct drm_device *dev, } int intel_wait_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring, int n) + struct intel_ring_buffer *ring, int n) { unsigned long end; drm_i915_private_t *dev_priv = dev->dev_private; @@ -729,7 +728,8 @@ int intel_wait_ring_buffer(struct drm_device *dev, } void intel_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, int num_dwords) + struct intel_ring_buffer *ring, + int num_dwords) { int n = 4*num_dwords; if (unlikely(ring->tail + n > ring->size)) @@ -741,16 +741,16 @@ void intel_ring_begin(struct drm_device *dev, } void intel_ring_advance(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { ring->tail &= ring->size - 1; ring->set_tail(dev, ring, ring->tail); } void intel_fill_struct(struct drm_device *dev, - struct intel_ring_buffer *ring, - void *data, - unsigned int len) + struct intel_ring_buffer *ring, + void *data, + unsigned int len) { unsigned int *virt = ring->virtual_start + ring->tail; BUG_ON((len&~(4-1)) != 0); @@ -800,16 +800,16 @@ static const struct intel_ring_buffer bsd_ring = { static void gen6_bsd_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; I915_WRITE(GEN6_BSD_HWS_PGA, ring->status_page.gfx_addr); I915_READ(GEN6_BSD_HWS_PGA); } -static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 value) +static void gen6_bsd_ring_set_tail(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 value) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -830,17 +830,17 @@ static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); } -static inline unsigned int gen6_bsd_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) +static unsigned int gen6_bsd_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; return I915_READ(GEN6_BSD_RING_ACTHD); } static void gen6_bsd_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { intel_ring_begin(dev, ring, 4); intel_ring_emit(dev, ring, MI_FLUSH_DW); @@ -852,17 +852,22 @@ static void gen6_bsd_ring_flush(struct drm_device *dev, static int gen6_bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { uint32_t exec_start; + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; + intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); /* bit0-7 is the length on GEN6+ */ + intel_ring_emit(dev, ring, + MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); + /* bit0-7 is the length on GEN6+ */ intel_ring_emit(dev, ring, exec_start); intel_ring_advance(dev, ring); + return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index abf8a4e25a2..2d3165fc147 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -104,15 +104,13 @@ intel_read_status_page(struct intel_ring_buffer *ring, } int intel_init_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring); + struct intel_ring_buffer *ring); void intel_cleanup_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring); + struct intel_ring_buffer *ring); int intel_wait_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring, int n); -int intel_wrap_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring); + struct intel_ring_buffer *ring, int n); void intel_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, int n); + struct intel_ring_buffer *ring, int n); static inline void intel_ring_emit(struct drm_device *dev, struct intel_ring_buffer *ring, -- cgit v1.2.3-70-g09d2 From 5c12a07e8073295ce8b57a822f811ac34e4f8420 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 22 Sep 2010 11:22:30 +0100 Subject: drm/i915: Drop ring->lazy_request We are not currently using it as intended, so remove the complication. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 37 ++++++--------------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ----- 2 files changed, 6 insertions(+), 36 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0ce28c71fac..3fd69ad19aa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1470,24 +1470,12 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) obj_priv->pages = NULL; } -static uint32_t -i915_gem_next_request_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - ring->outstanding_lazy_request = true; - - return dev_priv->next_seqno; -} - static void i915_gem_object_move_to_active(struct drm_gem_object *obj, struct intel_ring_buffer *ring) { - struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = obj->dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - uint32_t seqno = i915_gem_next_request_seqno(dev, ring); BUG_ON(ring == NULL); obj_priv->ring = ring; @@ -1500,7 +1488,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, /* Move from whatever list we were on to the tail of execution. */ list_move_tail(&obj_priv->list, &ring->active_list); - obj_priv->last_rendering_seqno = seqno; + obj_priv->last_rendering_seqno = dev_priv->next_seqno; } static void @@ -1945,11 +1933,6 @@ i915_gem_flush_ring(struct drm_device *dev, { ring->flush(dev, ring, invalidate_domains, flush_domains); i915_gem_process_flushing_list(dev, flush_domains, ring); - - if (ring->outstanding_lazy_request) { - (void)i915_add_request(dev, file_priv, NULL, ring); - ring->outstanding_lazy_request = false; - } } static void @@ -2098,7 +2081,7 @@ i915_gpu_idle(struct drm_device *dev) return 0; /* Flush everything onto the inactive list. */ - seqno = i915_gem_next_request_seqno(dev, &dev_priv->render_ring); + seqno = dev_priv->next_seqno; i915_gem_flush_ring(dev, NULL, &dev_priv->render_ring, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); ret = i915_wait_request(dev, seqno, &dev_priv->render_ring); @@ -2106,7 +2089,7 @@ i915_gpu_idle(struct drm_device *dev) return ret; if (HAS_BSD(dev)) { - seqno = i915_gem_next_request_seqno(dev, &dev_priv->render_ring); + seqno = dev_priv->next_seqno; i915_gem_flush_ring(dev, NULL, &dev_priv->bsd_ring, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); ret = i915_wait_request(dev, seqno, &dev_priv->bsd_ring); @@ -3573,7 +3556,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_request *request = NULL; int ret = 0, ret2, i, pinned = 0; uint64_t exec_offset; - uint32_t seqno, reloc_index; + uint32_t reloc_index; int pin_tries, flips; struct intel_ring_buffer *ring = NULL; @@ -3854,15 +3837,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_INFO("%s: move to exec list %p\n", __func__, obj); #endif } - - /* - * Get a seqno representing the execution of the current buffer, - * which we can wait on. We would like to mitigate these interrupts, - * likely by only creating seqnos occasionally (so that we have - * *some* interrupts representing completion of buffers that we can - * wait on when trying to clear up gtt space). - */ - seqno = i915_add_request(dev, file_priv, request, ring); + i915_add_request(dev, file_priv, request, ring); request = NULL; #if WATCH_LRU diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 2d3165fc147..bfbc4889909 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -86,11 +86,6 @@ struct intel_ring_buffer { */ struct list_head request_list; - /** - * Do we have some not yet emitted requests outstanding? - */ - bool outstanding_lazy_request; - wait_queue_head_t irq_queue; drm_local_map_t map; }; -- cgit v1.2.3-70-g09d2 From 780f0ca3e0cd3f0677d9149b7e14bf0878d1dbdc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 23 Sep 2010 17:45:39 +0100 Subject: drm/i915/ringbuffer: Fix sign of ring space. As we presume space is signed when computing and looking for wrap along, make it so. Reported-by: Owain G. Ainsworth Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index bfbc4889909..ce521010ce9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -31,7 +31,7 @@ struct intel_ring_buffer { unsigned int head; unsigned int tail; - unsigned int space; + int space; struct intel_hw_status_page status_page; u32 irq_gem_seqno; /* last seq seem at irq time */ -- cgit v1.2.3-70-g09d2 From f787a5f59e1b0e320a6b0a37e9a2e306551d1e40 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Sep 2010 16:02:42 +0100 Subject: drm/i915: Only hold a process-local lock whilst throttling. Avoid cause latencies in other clients by not taking the global struct mutex and moving the per-client request manipulation a local per-client mutex. For example, this allows a compositor to schedule a page-flip (through X) whilst an OpenGL application is monopolising the GPU. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +- drivers/gpu/drm/i915/i915_dma.c | 22 +++--- drivers/gpu/drm/i915/i915_drv.h | 15 +++- drivers/gpu/drm/i915/i915_gem.c | 120 +++++++++++++++++++------------- drivers/gpu/drm/i915/i915_irq.c | 29 ++++---- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 16 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +- 8 files changed, 123 insertions(+), 92 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 36f0e3630f7..eb5dd52847a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -261,7 +261,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) if (dev_priv->render_ring.status_page.page_addr != NULL) { seq_printf(m, "Current sequence: %d\n", - i915_get_gem_seqno(dev, &dev_priv->render_ring)); + dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring)); } else { seq_printf(m, "Current sequence: hws uninitialized\n"); } @@ -321,7 +321,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) atomic_read(&dev_priv->irq_received)); if (dev_priv->render_ring.status_page.page_addr != NULL) { seq_printf(m, "Current sequence: %d\n", - i915_get_gem_seqno(dev, &dev_priv->render_ring)); + dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring)); } else { seq_printf(m, "Current sequence: hws uninitialized\n"); } @@ -932,7 +932,7 @@ i915_wedged_write(struct file *filp, atomic_set(&dev_priv->mm.wedged, val); if (val) { - DRM_WAKEUP(&dev_priv->irq_queue); + wake_up_all(&dev_priv->irq_queue); queue_work(dev_priv->wq, &dev_priv->error_work); } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 048c54bdfd4..a3aea17c964 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2162,20 +2162,19 @@ int i915_driver_unload(struct drm_device *dev) return 0; } -int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) +int i915_driver_open(struct drm_device *dev, struct drm_file *file) { - struct drm_i915_file_private *i915_file_priv; + struct drm_i915_file_private *file_priv; DRM_DEBUG_DRIVER("\n"); - i915_file_priv = (struct drm_i915_file_private *) - kmalloc(sizeof(*i915_file_priv), GFP_KERNEL); - - if (!i915_file_priv) + file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); + if (!file_priv) return -ENOMEM; - file_priv->driver_priv = i915_file_priv; + file->driver_priv = file_priv; - INIT_LIST_HEAD(&i915_file_priv->mm.request_list); + INIT_LIST_HEAD(&file_priv->mm.request_list); + mutex_init(&file_priv->mutex); return 0; } @@ -2218,11 +2217,12 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) i915_mem_release(dev, file_priv, dev_priv->agp_heap); } -void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) +void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) { - struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; + struct drm_i915_file_private *file_priv = file->driver_priv; - kfree(i915_file_priv); + mutex_destroy(&file_priv->mutex); + kfree(file_priv); } struct drm_ioctl_desc i915_ioctls[] = { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cbfb99dce6a..2611e85bdd3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -844,11 +844,13 @@ struct drm_i915_gem_request { /** global list entry for this request */ struct list_head list; + struct drm_i915_file_private *file_priv; /** file_priv list entry for this request */ struct list_head client_list; }; struct drm_i915_file_private { + struct mutex mutex; struct { struct list_head request_list; } mm; @@ -1005,9 +1007,16 @@ void i915_gem_object_unpin(struct drm_gem_object *obj); int i915_gem_object_unbind(struct drm_gem_object *obj); void i915_gem_release_mmap(struct drm_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); -uint32_t i915_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring); -bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); + +/** + * Returns true if seq1 is later than seq2. + */ +static inline bool +i915_seqno_passed(uint32_t seq1, uint32_t seq2) +{ + return (int32_t)(seq1 - seq2) >= 0; +} + int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool interruptible); int i915_gem_object_put_fence_reg(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index dec7bbc81cb..9185f098822 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1592,17 +1592,17 @@ i915_gem_process_flushing_list(struct drm_device *dev, uint32_t i915_add_request(struct drm_device *dev, - struct drm_file *file_priv, + struct drm_file *file, struct drm_i915_gem_request *request, struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_file_private *i915_file_priv = NULL; + struct drm_i915_file_private *file_priv = NULL; uint32_t seqno; int was_empty; - if (file_priv != NULL) - i915_file_priv = file_priv->driver_priv; + if (file != NULL) + file_priv = file->driver_priv; if (request == NULL) { request = kzalloc(sizeof(*request), GFP_KERNEL); @@ -1610,7 +1610,7 @@ i915_add_request(struct drm_device *dev, return 0; } - seqno = ring->add_request(dev, ring, file_priv, 0); + seqno = ring->add_request(dev, ring, 0); request->seqno = seqno; request->ring = ring; @@ -1618,11 +1618,12 @@ i915_add_request(struct drm_device *dev, was_empty = list_empty(&ring->request_list); list_add_tail(&request->list, &ring->request_list); - if (i915_file_priv) { + if (file_priv) { + mutex_lock(&file_priv->mutex); + request->file_priv = file_priv; list_add_tail(&request->client_list, - &i915_file_priv->mm.request_list); - } else { - INIT_LIST_HEAD(&request->client_list); + &file_priv->mm.request_list); + mutex_unlock(&file_priv->mutex); } if (!dev_priv->mm.suspended) { @@ -1654,20 +1655,14 @@ i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) I915_GEM_DOMAIN_COMMAND, flush_domains); } -/** - * Returns true if seq1 is later than seq2. - */ -bool -i915_seqno_passed(uint32_t seq1, uint32_t seq2) -{ - return (int32_t)(seq1 - seq2) >= 0; -} - -uint32_t -i915_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +static inline void +i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) { - return ring->get_gem_seqno(dev, ring); + if (request->file_priv) { + mutex_lock(&request->file_priv->mutex); + list_del(&request->client_list); + mutex_unlock(&request->file_priv->mutex); + } } static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, @@ -1681,7 +1676,7 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, list); list_del(&request->list); - list_del(&request->client_list); + i915_gem_request_remove_from_client(request); kfree(request); } @@ -1746,7 +1741,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, list_empty(&ring->request_list)) return; - seqno = i915_get_gem_seqno(dev, ring); + seqno = ring->get_seqno(dev, ring); while (!list_empty(&ring->request_list)) { struct drm_i915_gem_request *request; @@ -1760,7 +1755,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, trace_i915_gem_request_retire(dev, request->seqno); list_del(&request->list); - list_del(&request->client_list); + i915_gem_request_remove_from_client(request); kfree(request); } @@ -1862,7 +1857,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, if (atomic_read(&dev_priv->mm.wedged)) return -EIO; - if (!i915_seqno_passed(ring->get_gem_seqno(dev, ring), seqno)) { + if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { if (HAS_PCH_SPLIT(dev)) ier = I915_READ(DEIER) | I915_READ(GTIER); else @@ -1881,12 +1876,12 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, if (interruptible) ret = wait_event_interruptible(ring->irq_queue, i915_seqno_passed( - ring->get_gem_seqno(dev, ring), seqno) + ring->get_seqno(dev, ring), seqno) || atomic_read(&dev_priv->mm.wedged)); else wait_event(ring->irq_queue, i915_seqno_passed( - ring->get_gem_seqno(dev, ring), seqno) + ring->get_seqno(dev, ring), seqno) || atomic_read(&dev_priv->mm.wedged)); ring->user_irq_put(dev, ring); @@ -1899,7 +1894,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, if (ret && ret != -ERESTARTSYS) DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n", - __func__, ret, seqno, ring->get_gem_seqno(dev, ring), + __func__, ret, seqno, ring->get_seqno(dev, ring), dev_priv->next_seqno); /* Directly dispatch request retiring. While we have the work queue @@ -3384,28 +3379,48 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, * relatively low latency when blocking on a particular request to finish. */ static int -i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) +i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) { - struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; - int ret = 0; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_file_private *file_priv = file->driver_priv; unsigned long recent_enough = jiffies - msecs_to_jiffies(20); + struct drm_i915_gem_request *request; + struct intel_ring_buffer *ring = NULL; + u32 seqno = 0; + int ret; - mutex_lock(&dev->struct_mutex); - while (!list_empty(&i915_file_priv->mm.request_list)) { - struct drm_i915_gem_request *request; - - request = list_first_entry(&i915_file_priv->mm.request_list, - struct drm_i915_gem_request, - client_list); - + mutex_lock(&file_priv->mutex); + list_for_each_entry(request, &file_priv->mm.request_list, client_list) { if (time_after_eq(request->emitted_jiffies, recent_enough)) break; - ret = i915_wait_request(dev, request->seqno, request->ring); - if (ret != 0) - break; + ring = request->ring; + seqno = request->seqno; } - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&file_priv->mutex); + + if (seqno == 0) + return 0; + + ret = 0; + if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { + /* And wait for the seqno passing without holding any locks and + * causing extra latency for others. This is safe as the irq + * generation is designed to be run atomically and so is + * lockless. + */ + ring->user_irq_get(dev, ring); + ret = wait_event_interruptible(ring->irq_queue, + i915_seqno_passed(ring->get_seqno(dev, ring), seqno) + || atomic_read(&dev_priv->mm.wedged)); + ring->user_irq_put(dev, ring); + + if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) + ret = -EIO; + } + + if (ret == 0) + queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); return ret; } @@ -4857,17 +4872,26 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, return 0; } -void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv) +void i915_gem_release(struct drm_device *dev, struct drm_file *file) { - struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; + struct drm_i915_file_private *file_priv = file->driver_priv; /* Clean up our request list when the client is going away, so that * later retire_requests won't dereference our soon-to-be-gone * file_priv. */ mutex_lock(&dev->struct_mutex); - while (!list_empty(&i915_file_priv->mm.request_list)) - list_del_init(i915_file_priv->mm.request_list.next); + mutex_lock(&file_priv->mutex); + while (!list_empty(&file_priv->mm.request_list)) { + struct drm_i915_gem_request *request; + + request = list_first_entry(&file_priv->mm.request_list, + struct drm_i915_gem_request, + client_list); + list_del(&request->client_list); + request->file_priv = NULL; + } + mutex_unlock(&file_priv->mutex); mutex_unlock(&dev->struct_mutex); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d4c053e1c37..245a07e6f1a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -327,16 +327,16 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) } if (gt_iir & GT_PIPE_NOTIFY) { - u32 seqno = render_ring->get_gem_seqno(dev, render_ring); + u32 seqno = render_ring->get_seqno(dev, render_ring); render_ring->irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); - DRM_WAKEUP(&dev_priv->render_ring.irq_queue); + wake_up_all(&dev_priv->render_ring.irq_queue); dev_priv->hangcheck_count = 0; mod_timer(&dev_priv->hangcheck_timer, jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); } if (gt_iir & bsd_usr_interrupt) - DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); + wake_up_all(&dev_priv->bsd_ring.irq_queue); if (de_iir & DE_GSE) intel_opregion_gse_intr(dev); @@ -573,7 +573,8 @@ static void i915_capture_error_state(struct drm_device *dev) return; } - error->seqno = i915_get_gem_seqno(dev, &dev_priv->render_ring); + error->seqno = + dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); error->pipeastat = I915_READ(PIPEASTAT); @@ -873,7 +874,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) /* * Wakeup waiting processes so they don't hang */ - DRM_WAKEUP(&dev_priv->render_ring.irq_queue); + wake_up_all(&dev_priv->render_ring.irq_queue); + if (HAS_BSD(dev)) + wake_up_all(&dev_priv->bsd_ring.irq_queue); } queue_work(dev_priv->wq, &dev_priv->error_work); @@ -1012,18 +1015,17 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } if (iir & I915_USER_INTERRUPT) { - u32 seqno = - render_ring->get_gem_seqno(dev, render_ring); + u32 seqno = render_ring->get_seqno(dev, render_ring); render_ring->irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); - DRM_WAKEUP(&dev_priv->render_ring.irq_queue); + wake_up_all(&dev_priv->render_ring.irq_queue); dev_priv->hangcheck_count = 0; mod_timer(&dev_priv->hangcheck_timer, jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); } if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) - DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); + wake_up_all(&dev_priv->bsd_ring.irq_queue); if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { intel_prepare_page_flip(dev, 0); @@ -1333,9 +1335,8 @@ void i915_hangcheck_elapsed(unsigned long data) /* If all work is done then ACTHD clearly hasn't advanced. */ if (list_empty(&dev_priv->render_ring.request_list) || - i915_seqno_passed(i915_get_gem_seqno(dev, - &dev_priv->render_ring), - i915_get_tail_request(dev)->seqno)) { + i915_seqno_passed(dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring), + i915_get_tail_request(dev)->seqno)) { bool missed_wakeup = false; dev_priv->hangcheck_count = 0; @@ -1343,13 +1344,13 @@ void i915_hangcheck_elapsed(unsigned long data) /* Issue a wake-up to catch stuck h/w. */ if (dev_priv->render_ring.waiting_gem_seqno && waitqueue_active(&dev_priv->render_ring.irq_queue)) { - DRM_WAKEUP(&dev_priv->render_ring.irq_queue); + wake_up_all(&dev_priv->render_ring.irq_queue); missed_wakeup = true; } if (dev_priv->bsd_ring.waiting_gem_seqno && waitqueue_active(&dev_priv->bsd_ring.irq_queue)) { - DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); + wake_up_all(&dev_priv->bsd_ring.irq_queue); missed_wakeup = true; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4843d027aaa..00214c123ec 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4983,7 +4983,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, /* Initial scanout buffer will have a 0 pending flip count */ if ((atomic_read(&obj_priv->pending_flip) == 0) || atomic_dec_and_test(&obj_priv->pending_flip)) - DRM_WAKEUP(&dev_priv->pending_flip_queue); + wake_up(&dev_priv->pending_flip_queue); schedule_work(&work->work); trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1bcea7c8523..9b848be4057 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -239,7 +239,6 @@ do { \ static u32 render_ring_add_request(struct drm_device *dev, struct intel_ring_buffer *ring, - struct drm_file *file_priv, u32 flush_domains) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -303,8 +302,8 @@ render_ring_add_request(struct drm_device *dev, } static u32 -render_ring_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +render_ring_get_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; if (HAS_PIPE_CONTROL(dev)) @@ -390,7 +389,6 @@ static int init_bsd_ring(struct drm_device *dev, static u32 bsd_ring_add_request(struct drm_device *dev, struct intel_ring_buffer *ring, - struct drm_file *file_priv, u32 flush_domains) { u32 seqno; @@ -432,8 +430,8 @@ bsd_ring_put_user_irq(struct drm_device *dev, } static u32 -bsd_ring_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +bsd_ring_get_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } @@ -773,7 +771,7 @@ static const struct intel_ring_buffer render_ring = { .get_active_head = render_ring_get_active_head, .flush = render_ring_flush, .add_request = render_ring_add_request, - .get_gem_seqno = render_ring_get_gem_seqno, + .get_seqno = render_ring_get_seqno, .user_irq_get = render_ring_get_user_irq, .user_irq_put = render_ring_put_user_irq, .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer, @@ -792,7 +790,7 @@ static const struct intel_ring_buffer bsd_ring = { .get_active_head = bsd_ring_get_active_head, .flush = bsd_ring_flush, .add_request = bsd_ring_add_request, - .get_gem_seqno = bsd_ring_get_gem_seqno, + .get_seqno = bsd_ring_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer, @@ -883,7 +881,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .get_active_head = gen6_bsd_ring_get_active_head, .flush = gen6_bsd_ring_flush, .add_request = bsd_ring_add_request, - .get_gem_seqno = bsd_ring_get_gem_seqno, + .get_seqno = bsd_ring_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, .dispatch_gem_execbuffer = gen6_bsd_ring_dispatch_gem_execbuffer, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ce521010ce9..d506da1605b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -58,10 +58,9 @@ struct intel_ring_buffer { u32 flush_domains); u32 (*add_request)(struct drm_device *dev, struct intel_ring_buffer *ring, - struct drm_file *file_priv, u32 flush_domains); - u32 (*get_gem_seqno)(struct drm_device *dev, - struct intel_ring_buffer *ring); + u32 (*get_seqno)(struct drm_device *dev, + struct intel_ring_buffer *ring); int (*dispatch_gem_execbuffer)(struct drm_device *dev, struct intel_ring_buffer *ring, struct drm_i915_gem_execbuffer2 *exec, -- cgit v1.2.3-70-g09d2 From 79f321b7e676bd54f563c5ce513588aa90b2cc21 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 24 Sep 2010 21:20:10 +0200 Subject: drm/i915: kill ring->get_active_head All functions are extremely similar, so fold them into one generic implementation. This function isn't used anyway, because there's not yet a bsd ring error state dumper. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 21 ++------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +++-- 2 files changed, 5 insertions(+), 21 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 487575f2340..a3e73d4cd39 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -127,8 +127,8 @@ static void ring_set_tail(struct drm_device *dev, I915_WRITE_TAIL(ring, ring->tail); } -static unsigned int render_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) +u32 intel_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; u32 acthd_reg = INTEL_INFO(dev)->gen >= 4 ? @@ -376,13 +376,6 @@ bsd_ring_flush(struct drm_device *dev, intel_ring_advance(dev, ring); } -static unsigned int bsd_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(RING_ACTHD(ring->mmio_base)); -} - static int init_bsd_ring(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -771,7 +764,6 @@ static const struct intel_ring_buffer render_ring = { .setup_status_page = render_setup_status_page, .init = init_render_ring, .set_tail = ring_set_tail, - .get_active_head = render_ring_get_active_head, .flush = render_ring_flush, .add_request = render_ring_add_request, .get_seqno = render_ring_get_seqno, @@ -790,7 +782,6 @@ static const struct intel_ring_buffer bsd_ring = { .setup_status_page = bsd_setup_status_page, .init = init_bsd_ring, .set_tail = ring_set_tail, - .get_active_head = bsd_ring_get_active_head, .flush = bsd_ring_flush, .add_request = bsd_ring_add_request, .get_seqno = bsd_ring_get_seqno, @@ -831,13 +822,6 @@ static void gen6_bsd_ring_set_tail(struct drm_device *dev, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); } -static unsigned int gen6_bsd_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(RING_ACTHD(ring->mmio_base)); -} - static void gen6_bsd_ring_flush(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, @@ -881,7 +865,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .setup_status_page = gen6_bsd_setup_status_page, .init = init_bsd_ring, .set_tail = gen6_bsd_ring_set_tail, - .get_active_head = gen6_bsd_ring_get_active_head, .flush = gen6_bsd_ring_flush, .add_request = bsd_ring_add_request, .get_seqno = bsd_ring_get_seqno, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d506da1605b..43c5f7a476f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -50,8 +50,6 @@ struct intel_ring_buffer { void (*set_tail)(struct drm_device *dev, struct intel_ring_buffer *ring, u32 value); - unsigned int (*get_active_head)(struct drm_device *dev, - struct intel_ring_buffer *ring); void (*flush)(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, @@ -128,4 +126,7 @@ u32 intel_ring_get_seqno(struct drm_device *dev, int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); +u32 intel_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring); + #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3-70-g09d2 From 447da18742b170b8e09ac71edf63c5798d2dbb0b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 24 Sep 2010 21:49:27 +0200 Subject: drm/i915: kill ring->setup_status_page It's the same code, essentially, so kill all copies safe one unified version. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 25 +++---------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- 3 files changed, 6 insertions(+), 25 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a3aea17c964..ba050ed8df5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -221,7 +221,7 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG_DRIVER("hw status page @ %p\n", ring->status_page.page_addr); if (ring->status_page.gfx_addr != 0) - ring->setup_status_page(dev, ring); + intel_ring_setup_status_page(dev, ring); else I915_WRITE(HWS_PGA, dev_priv->dma_status_page); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a3e73d4cd39..5103b95cea9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -348,8 +348,8 @@ render_ring_put_user_irq(struct drm_device *dev, spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } -static void render_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) +void intel_ring_setup_status_page(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; if (IS_GEN6(dev)) { @@ -404,14 +404,6 @@ bsd_ring_add_request(struct drm_device *dev, return seqno; } -static void bsd_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(RING_HWS_PGA(ring->mmio_base), ring->status_page.gfx_addr); - I915_READ(RING_HWS_PGA(ring->mmio_base)); -} - static void bsd_ring_get_user_irq(struct drm_device *dev, struct intel_ring_buffer *ring) @@ -564,7 +556,7 @@ static int init_status_page(struct drm_device *dev, ring->status_page.obj = obj; memset(ring->status_page.page_addr, 0, PAGE_SIZE); - ring->setup_status_page(dev, ring); + intel_ring_setup_status_page(dev, ring); DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", ring->name, ring->status_page.gfx_addr); @@ -761,7 +753,6 @@ static const struct intel_ring_buffer render_ring = { .id = RING_RENDER, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, - .setup_status_page = render_setup_status_page, .init = init_render_ring, .set_tail = ring_set_tail, .flush = render_ring_flush, @@ -779,7 +770,6 @@ static const struct intel_ring_buffer bsd_ring = { .id = RING_BSD, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .setup_status_page = bsd_setup_status_page, .init = init_bsd_ring, .set_tail = ring_set_tail, .flush = bsd_ring_flush, @@ -791,14 +781,6 @@ static const struct intel_ring_buffer bsd_ring = { }; -static void gen6_bsd_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(RING_HWS_PGA_GEN6(ring->mmio_base), ring->status_page.gfx_addr); - I915_READ(RING_HWS_PGA_GEN6(ring->mmio_base)); -} - static void gen6_bsd_ring_set_tail(struct drm_device *dev, struct intel_ring_buffer *ring, u32 value) @@ -862,7 +844,6 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .id = RING_BSD, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .setup_status_page = gen6_bsd_setup_status_page, .init = init_bsd_ring, .set_tail = gen6_bsd_ring_set_tail, .flush = gen6_bsd_ring_flush, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 43c5f7a476f..c50919275c6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -41,8 +41,6 @@ struct intel_ring_buffer { struct intel_ring_buffer *ring); void (*user_irq_put)(struct drm_device *dev, struct intel_ring_buffer *ring); - void (*setup_status_page)(struct drm_device *dev, - struct intel_ring_buffer *ring); int (*init)(struct drm_device *dev, struct intel_ring_buffer *ring); @@ -128,5 +126,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev); u32 intel_ring_get_active_head(struct drm_device *dev, struct intel_ring_buffer *ring); +void intel_ring_setup_status_page(struct drm_device *dev, + struct intel_ring_buffer *ring); #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3-70-g09d2 From a56ba56c275b1c2b982c8901ab92bf5a0fd0b757 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 28 Sep 2010 10:07:56 +0100 Subject: Revert "drm/i915: Drop ring->lazy_request" With multiple rings generating requests independently, the outstanding requests must also be track independently. Reported-by: Wang Jinjin Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=30380 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 43 +++++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ++++ 2 files changed, 35 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1025508e591..63b38608c80 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1545,12 +1545,23 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) obj_priv->pages = NULL; } +static uint32_t +i915_gem_next_request_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + ring->outstanding_lazy_request = true; + return dev_priv->next_seqno; +} + static void i915_gem_object_move_to_active(struct drm_gem_object *obj, struct intel_ring_buffer *ring) { - struct drm_i915_private *dev_priv = obj->dev->dev_private; + struct drm_device *dev = obj->dev; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + uint32_t seqno = i915_gem_next_request_seqno(dev, ring); BUG_ON(ring == NULL); obj_priv->ring = ring; @@ -1563,7 +1574,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, /* Move from whatever list we were on to the tail of execution. */ list_move_tail(&obj_priv->list, &ring->active_list); - obj_priv->last_rendering_seqno = dev_priv->next_seqno; + obj_priv->last_rendering_seqno = seqno; } static void @@ -1686,6 +1697,7 @@ i915_add_request(struct drm_device *dev, } seqno = ring->add_request(dev, ring, 0); + ring->outstanding_lazy_request = false; request->seqno = seqno; request->ring = ring; @@ -1930,11 +1942,12 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, if (atomic_read(&dev_priv->mm.wedged)) return -EAGAIN; - if (seqno == dev_priv->next_seqno) { + if (ring->outstanding_lazy_request) { seqno = i915_add_request(dev, NULL, NULL, ring); if (seqno == 0) return -ENOMEM; } + BUG_ON(seqno == dev_priv->next_seqno); if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { if (HAS_PCH_SPLIT(dev)) @@ -1993,7 +2006,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, */ static int i915_wait_request(struct drm_device *dev, uint32_t seqno, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { return i915_do_wait_request(dev, seqno, 1, ring); } @@ -2139,12 +2152,21 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return ret; } +static int i915_ring_idle(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + i915_gem_flush_ring(dev, NULL, ring, + I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + return i915_wait_request(dev, + i915_gem_next_request_seqno(dev, ring), + ring); +} + int i915_gpu_idle(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; bool lists_empty; - u32 seqno; int ret; lists_empty = (list_empty(&dev_priv->mm.flushing_list) && @@ -2155,18 +2177,12 @@ i915_gpu_idle(struct drm_device *dev) return 0; /* Flush everything onto the inactive list. */ - seqno = dev_priv->next_seqno; - i915_gem_flush_ring(dev, NULL, &dev_priv->render_ring, - I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); - ret = i915_wait_request(dev, seqno, &dev_priv->render_ring); + ret = i915_ring_idle(dev, &dev_priv->render_ring); if (ret) return ret; if (HAS_BSD(dev)) { - seqno = dev_priv->next_seqno; - i915_gem_flush_ring(dev, NULL, &dev_priv->bsd_ring, - I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); - ret = i915_wait_request(dev, seqno, &dev_priv->bsd_ring); + ret = i915_ring_idle(dev, &dev_priv->bsd_ring); if (ret) return ret; } @@ -3938,6 +3954,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_INFO("%s: move to exec list %p\n", __func__, obj); #endif } + i915_add_request(dev, file_priv, request, ring); request = NULL; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index c50919275c6..9725f783db2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -81,6 +81,11 @@ struct intel_ring_buffer { */ struct list_head request_list; + /** + * Do we have some not yet emitted requests outstanding? + */ + bool outstanding_lazy_request; + wait_queue_head_t irq_queue; drm_local_map_t map; }; -- cgit v1.2.3-70-g09d2 From e36c1cd7292efcb8daca26cd6331481736544742 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Oct 2010 19:00:02 +0100 Subject: drm/i915/ringbuffer: Remove broken intel_fill_struct() ... before someone tries to use it. The code both calls intel_ring_begin/advance() and open-codes the bookkeeping performed by those two functions. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 15 --------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ---- 2 files changed, 19 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f1e0538b21f..8da5ff790da 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -733,21 +733,6 @@ void intel_ring_advance(struct drm_device *dev, ring->set_tail(dev, ring, ring->tail); } -void intel_fill_struct(struct drm_device *dev, - struct intel_ring_buffer *ring, - void *data, - unsigned int len) -{ - unsigned int *virt = ring->virtual_start + ring->tail; - BUG_ON((len&~(4-1)) != 0); - intel_ring_begin(dev, ring, len/4); - memcpy(virt, data, len); - ring->tail += len; - ring->tail &= ring->size - 1; - ring->space -= len; - intel_ring_advance(dev, ring); -} - static const struct intel_ring_buffer render_ring = { .name = "render ring", .id = RING_RENDER, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 9725f783db2..5b37ff3a694 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -116,10 +116,6 @@ static inline void intel_ring_emit(struct drm_device *dev, ring->tail += 4; } -void intel_fill_struct(struct drm_device *dev, - struct intel_ring_buffer *ring, - void *data, - unsigned int len); void intel_ring_advance(struct drm_device *dev, struct intel_ring_buffer *ring); -- cgit v1.2.3-70-g09d2 From 549f7365820a212a1cfd0871d377b1ad0d1e5723 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 19 Oct 2010 11:19:32 +0100 Subject: drm/i915: Enable SandyBridge blitter ring Based on an original patch by Zhenyu Wang, this initializes the BLT ring for SandyBridge and enables support for user execbuffers. Cc: Zhenyu Wang Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 2 + drivers/gpu/drm/i915/i915_dma.c | 4 ++ drivers/gpu/drm/i915/i915_drv.c | 2 + drivers/gpu/drm/i915/i915_drv.h | 3 ++ drivers/gpu/drm/i915/i915_gem.c | 55 +++++++++++++++++--- drivers/gpu/drm/i915/i915_gem_evict.c | 6 ++- drivers/gpu/drm/i915/i915_irq.c | 64 +++++++++++++---------- drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_ringbuffer.c | 92 +++++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 + include/drm/i915_drm.h | 6 ++- 11 files changed, 175 insertions(+), 63 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f9e3295f045..d521de3e068 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -80,6 +80,8 @@ static int i915_capabilities(struct seq_file *m, void *data) B(has_overlay); B(overlay_needs_physical); B(supports_tv); + B(has_bsd_ring); + B(has_blt_ring); #undef B return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1ffeb1c5e7c..1851ca4087f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -133,6 +133,7 @@ static int i915_dma_cleanup(struct drm_device * dev) mutex_lock(&dev->struct_mutex); intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); + intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); mutex_unlock(&dev->struct_mutex); /* Clear the HWS virtual address at teardown */ @@ -763,6 +764,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_BSD: value = HAS_BSD(dev); break; + case I915_PARAM_HAS_BLT: + value = HAS_BLT(dev); + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c3decb2fef4..90f9c3e3fee 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -158,12 +158,14 @@ static const struct intel_device_info intel_sandybridge_d_info = { .gen = 6, .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, + .has_blt_ring = 1, }; static const struct intel_device_info intel_sandybridge_m_info = { .gen = 6, .is_mobile = 1, .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, + .has_blt_ring = 1, }; static const struct pci_device_id pciidlist[] = { /* aka */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 817d8be6ff4..a9a0e220176 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -216,6 +216,7 @@ struct intel_device_info { u8 overlay_needs_physical : 1; u8 supports_tv : 1; u8 has_bsd_ring : 1; + u8 has_blt_ring : 1; }; enum no_fbc_reason { @@ -255,6 +256,7 @@ typedef struct drm_i915_private { struct pci_dev *bridge_dev; struct intel_ring_buffer render_ring; struct intel_ring_buffer bsd_ring; + struct intel_ring_buffer blt_ring; uint32_t next_seqno; drm_dma_handle_t *status_page_dmah; @@ -1300,6 +1302,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) +#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5041ebe3fdf..c3398d39641 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1800,6 +1800,7 @@ void i915_gem_reset(struct drm_device *dev) i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring); i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring); + i915_gem_reset_ring_lists(dev_priv, &dev_priv->blt_ring); /* Remove anything from the flushing lists. The GPU cache is likely * to be lost on reset along with the data, so simply move the @@ -1922,6 +1923,7 @@ i915_gem_retire_requests(struct drm_device *dev) i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); + i915_gem_retire_requests_ring(dev, &dev_priv->blt_ring); } static void @@ -1944,7 +1946,8 @@ i915_gem_retire_work_handler(struct work_struct *work) if (!dev_priv->mm.suspended && (!list_empty(&dev_priv->render_ring.request_list) || - !list_empty(&dev_priv->bsd_ring.request_list))) + !list_empty(&dev_priv->bsd_ring.request_list) || + !list_empty(&dev_priv->blt_ring.request_list))) queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); mutex_unlock(&dev->struct_mutex); } @@ -2063,6 +2066,10 @@ i915_gem_flush(struct drm_device *dev, i915_gem_flush_ring(dev, file_priv, &dev_priv->bsd_ring, invalidate_domains, flush_domains); + if (flush_rings & RING_BLT) + i915_gem_flush_ring(dev, file_priv, + &dev_priv->blt_ring, + invalidate_domains, flush_domains); } } @@ -2182,7 +2189,8 @@ i915_gpu_idle(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.flushing_list) && list_empty(&dev_priv->render_ring.active_list) && - list_empty(&dev_priv->bsd_ring.active_list)); + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); if (lists_empty) return 0; @@ -2195,6 +2203,10 @@ i915_gpu_idle(struct drm_device *dev) if (ret) return ret; + ret = i915_ring_idle(dev, &dev_priv->blt_ring); + if (ret) + return ret; + return 0; } @@ -3609,14 +3621,29 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", (int) args->buffers_ptr, args->buffer_count, args->batch_len); #endif - if (args->flags & I915_EXEC_BSD) { + switch (args->flags & I915_EXEC_RING_MASK) { + case I915_EXEC_DEFAULT: + case I915_EXEC_RENDER: + ring = &dev_priv->render_ring; + break; + case I915_EXEC_BSD: if (!HAS_BSD(dev)) { - DRM_ERROR("execbuf with wrong flag\n"); + DRM_ERROR("execbuf with invalid ring (BSD)\n"); return -EINVAL; } ring = &dev_priv->bsd_ring; - } else { - ring = &dev_priv->render_ring; + break; + case I915_EXEC_BLT: + if (!HAS_BLT(dev)) { + DRM_ERROR("execbuf with invalid ring (BLT)\n"); + return -EINVAL; + } + ring = &dev_priv->blt_ring; + break; + default: + DRM_ERROR("execbuf with unknown ring: %d\n", + (int)(args->flags & I915_EXEC_RING_MASK)); + return -EINVAL; } if (args->buffer_count < 1) { @@ -4482,10 +4509,18 @@ i915_gem_init_ringbuffer(struct drm_device *dev) goto cleanup_render_ring; } + if (HAS_BLT(dev)) { + ret = intel_init_blt_ring_buffer(dev); + if (ret) + goto cleanup_bsd_ring; + } + dev_priv->next_seqno = 1; return 0; +cleanup_bsd_ring: + intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); cleanup_render_ring: intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); cleanup_pipe_control: @@ -4501,6 +4536,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); + intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); if (HAS_PIPE_CONTROL(dev)) i915_gem_cleanup_pipe_control(dev); } @@ -4532,10 +4568,12 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, BUG_ON(!list_empty(&dev_priv->mm.active_list)); BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); BUG_ON(!list_empty(&dev_priv->bsd_ring.active_list)); + BUG_ON(!list_empty(&dev_priv->blt_ring.active_list)); BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); BUG_ON(!list_empty(&dev_priv->bsd_ring.request_list)); + BUG_ON(!list_empty(&dev_priv->blt_ring.request_list)); mutex_unlock(&dev->struct_mutex); ret = drm_irq_install(dev); @@ -4594,6 +4632,8 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->render_ring.request_list); INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list); INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list); + INIT_LIST_HEAD(&dev_priv->blt_ring.active_list); + INIT_LIST_HEAD(&dev_priv->blt_ring.request_list); for (i = 0; i < 16; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, @@ -4857,7 +4897,8 @@ i915_gpu_is_active(struct drm_device *dev) lists_empty = list_empty(&dev_priv->mm.flushing_list) && list_empty(&dev_priv->render_ring.active_list) && - list_empty(&dev_priv->bsd_ring.active_list); + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list); return !lists_empty; } diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 70db2f1ee36..43a4013f53f 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -166,7 +166,8 @@ i915_gem_evict_everything(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && list_empty(&dev_priv->render_ring.active_list) && - list_empty(&dev_priv->bsd_ring.active_list)); + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); if (lists_empty) return -ENOSPC; @@ -184,7 +185,8 @@ i915_gem_evict_everything(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && list_empty(&dev_priv->render_ring.active_list) && - list_empty(&dev_priv->bsd_ring.active_list)); + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); BUG_ON(!lists_empty); return 0; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f94cd7ffd74..237b8bdb599 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -293,6 +293,19 @@ static void i915_handle_rps_change(struct drm_device *dev) return; } +static void notify_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 seqno = ring->get_seqno(dev, ring); + ring->irq_gem_seqno = seqno; + trace_i915_gem_request_complete(dev, seqno); + wake_up_all(&ring->irq_queue); + dev_priv->hangcheck_count = 0; + mod_timer(&dev_priv->hangcheck_timer, + jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); +} + static irqreturn_t ironlake_irq_handler(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -300,7 +313,6 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) u32 de_iir, gt_iir, de_ier, pch_iir; u32 hotplug_mask; struct drm_i915_master_private *master_priv; - struct intel_ring_buffer *render_ring = &dev_priv->render_ring; u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; if (IS_GEN6(dev)) @@ -332,17 +344,12 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) READ_BREADCRUMB(dev_priv); } - if (gt_iir & GT_PIPE_NOTIFY) { - u32 seqno = render_ring->get_seqno(dev, render_ring); - render_ring->irq_gem_seqno = seqno; - trace_i915_gem_request_complete(dev, seqno); - wake_up_all(&dev_priv->render_ring.irq_queue); - dev_priv->hangcheck_count = 0; - mod_timer(&dev_priv->hangcheck_timer, - jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); - } + if (gt_iir & GT_PIPE_NOTIFY) + notify_ring(dev, &dev_priv->render_ring); if (gt_iir & bsd_usr_interrupt) - wake_up_all(&dev_priv->bsd_ring.irq_queue); + notify_ring(dev, &dev_priv->bsd_ring); + if (HAS_BLT(dev) && gt_iir & GT_BLT_USER_INTERRUPT) + notify_ring(dev, &dev_priv->blt_ring); if (de_iir & DE_GSE) intel_opregion_gse_intr(dev); @@ -881,6 +888,8 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) wake_up_all(&dev_priv->render_ring.irq_queue); if (HAS_BSD(dev)) wake_up_all(&dev_priv->bsd_ring.irq_queue); + if (HAS_BLT(dev)) + wake_up_all(&dev_priv->blt_ring.irq_queue); } queue_work(dev_priv->wq, &dev_priv->error_work); @@ -941,7 +950,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) unsigned long irqflags; int irq_received; int ret = IRQ_NONE; - struct intel_ring_buffer *render_ring = &dev_priv->render_ring; atomic_inc(&dev_priv->irq_received); @@ -1018,18 +1026,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) READ_BREADCRUMB(dev_priv); } - if (iir & I915_USER_INTERRUPT) { - u32 seqno = render_ring->get_seqno(dev, render_ring); - render_ring->irq_gem_seqno = seqno; - trace_i915_gem_request_complete(dev, seqno); - wake_up_all(&dev_priv->render_ring.irq_queue); - dev_priv->hangcheck_count = 0; - mod_timer(&dev_priv->hangcheck_timer, - jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); - } - + if (iir & I915_USER_INTERRUPT) + notify_ring(dev, &dev_priv->render_ring); if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) - wake_up_all(&dev_priv->bsd_ring.irq_queue); + notify_ring(dev, &dev_priv->bsd_ring); if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { intel_prepare_page_flip(dev, 0); @@ -1358,6 +1358,12 @@ void i915_hangcheck_elapsed(unsigned long data) missed_wakeup = true; } + if (dev_priv->blt_ring.waiting_gem_seqno && + waitqueue_active(&dev_priv->blt_ring.irq_queue)) { + wake_up_all(&dev_priv->blt_ring.irq_queue); + missed_wakeup = true; + } + if (missed_wakeup) DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); return; @@ -1443,8 +1449,12 @@ static int ironlake_irq_postinstall(struct drm_device *dev) I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); (void) I915_READ(DEIER); - if (IS_GEN6(dev)) - render_mask = GT_PIPE_NOTIFY | GT_GEN6_BSD_USER_INTERRUPT; + if (IS_GEN6(dev)) { + render_mask = + GT_PIPE_NOTIFY | + GT_GEN6_BSD_USER_INTERRUPT | + GT_BLT_USER_INTERRUPT; + } dev_priv->gt_irq_mask_reg = ~render_mask; dev_priv->gt_irq_enable_reg = render_mask; @@ -1454,6 +1464,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) if (IS_GEN6(dev)) { I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_IMR_USER_INTERRUPT); + I915_WRITE(GEN6_BLITTER_IMR, ~GEN6_BLITTER_USER_INTERRUPT); } I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); @@ -1523,9 +1534,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev) u32 error_mask; DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); - if (HAS_BSD(dev)) DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue); + if (HAS_BLT(dev)) + DRM_INIT_WAITQUEUE(&dev_priv->blt_ring.irq_queue); dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 557f27134d0..c52e209321c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -263,6 +263,7 @@ #define RENDER_RING_BASE 0x02000 #define BSD_RING_BASE 0x04000 #define GEN6_BSD_RING_BASE 0x12000 +#define BLT_RING_BASE 0x22000 #define RING_TAIL(base) ((base)+0x30) #define RING_HEAD(base) ((base)+0x34) #define RING_START(base) ((base)+0x38) @@ -2561,6 +2562,7 @@ #define GT_USER_INTERRUPT (1 << 0) #define GT_BSD_USER_INTERRUPT (1 << 5) #define GT_GEN6_BSD_USER_INTERRUPT (1 << 12) +#define GT_BLT_USER_INTERRUPT (1 << 22) #define GTISR 0x44010 #define GTIMR 0x44014 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8da5ff790da..a8f408fe4e7 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -383,9 +383,9 @@ static int init_bsd_ring(struct drm_device *dev, } static u32 -bsd_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 flush_domains) +ring_add_request(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 flush_domains) { u32 seqno; @@ -418,18 +418,18 @@ bsd_ring_put_user_irq(struct drm_device *dev, } static u32 -bsd_ring_get_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +ring_status_page_get_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } static int -bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +ring_dispatch_gem_execbuffer(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { uint32_t exec_start; exec_start = (uint32_t) exec_offset + exec->batch_start_offset; @@ -441,7 +441,6 @@ bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, return 0; } - static int render_ring_dispatch_gem_execbuffer(struct drm_device *dev, struct intel_ring_buffer *ring, @@ -758,11 +757,11 @@ static const struct intel_ring_buffer bsd_ring = { .init = init_bsd_ring, .set_tail = ring_set_tail, .flush = bsd_ring_flush, - .add_request = bsd_ring_add_request, - .get_seqno = bsd_ring_get_seqno, + .add_request = ring_add_request, + .get_seqno = ring_status_page_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, - .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer, + .dispatch_gem_execbuffer = ring_dispatch_gem_execbuffer, }; @@ -789,10 +788,10 @@ static void gen6_bsd_ring_set_tail(struct drm_device *dev, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); } -static void gen6_bsd_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) +static void gen6_ring_flush(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { intel_ring_begin(dev, ring, 4); intel_ring_emit(dev, ring, MI_FLUSH_DW); @@ -803,11 +802,11 @@ static void gen6_bsd_ring_flush(struct drm_device *dev, } static int -gen6_bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +gen6_ring_dispatch_gem_execbuffer(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { uint32_t exec_start; @@ -831,12 +830,42 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .size = 32 * PAGE_SIZE, .init = init_bsd_ring, .set_tail = gen6_bsd_ring_set_tail, - .flush = gen6_bsd_ring_flush, - .add_request = bsd_ring_add_request, - .get_seqno = bsd_ring_get_seqno, + .flush = gen6_ring_flush, + .add_request = ring_add_request, + .get_seqno = ring_status_page_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, - .dispatch_gem_execbuffer = gen6_bsd_ring_dispatch_gem_execbuffer, + .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, +}; + +/* Blitter support (SandyBridge+) */ + +static void +blt_ring_get_user_irq(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + /* do nothing */ +} +static void +blt_ring_put_user_irq(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + /* do nothing */ +} + +static const struct intel_ring_buffer gen6_blt_ring = { + .name = "blt ring", + .id = RING_BLT, + .mmio_base = BLT_RING_BASE, + .size = 32 * PAGE_SIZE, + .init = init_ring_common, + .set_tail = ring_set_tail, + .flush = gen6_ring_flush, + .add_request = ring_add_request, + .get_seqno = ring_status_page_get_seqno, + .user_irq_get = blt_ring_get_user_irq, + .user_irq_put = blt_ring_put_user_irq, + .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, }; int intel_init_render_ring_buffer(struct drm_device *dev) @@ -866,3 +895,12 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) return intel_init_ring_buffer(dev, &dev_priv->bsd_ring); } + +int intel_init_blt_ring_buffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + dev_priv->blt_ring = gen6_blt_ring; + + return intel_init_ring_buffer(dev, &dev_priv->blt_ring); +} diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 5b37ff3a694..9e81ff3b39c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -22,6 +22,7 @@ struct intel_ring_buffer { enum intel_ring_id { RING_RENDER = 0x1, RING_BSD = 0x2, + RING_BLT = 0x4, } id; u32 mmio_base; unsigned long size; @@ -124,6 +125,7 @@ u32 intel_ring_get_seqno(struct drm_device *dev, int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); +int intel_init_blt_ring_buffer(struct drm_device *dev); u32 intel_ring_get_active_head(struct drm_device *dev, struct intel_ring_buffer *ring); diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index e41c74facb6..8c641bed9bb 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -286,6 +286,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_PAGEFLIPPING 8 #define I915_PARAM_HAS_EXECBUF2 9 #define I915_PARAM_HAS_BSD 10 +#define I915_PARAM_HAS_BLT 11 typedef struct drm_i915_getparam { int param; @@ -627,8 +628,11 @@ struct drm_i915_gem_execbuffer2 { __u32 num_cliprects; /** This is a struct drm_clip_rect *cliprects */ __u64 cliprects_ptr; +#define I915_EXEC_RING_MASK (7<<0) +#define I915_EXEC_DEFAULT (0<<0) #define I915_EXEC_RENDER (1<<0) -#define I915_EXEC_BSD (1<<1) +#define I915_EXEC_BSD (2<<0) +#define I915_EXEC_BLT (3<<0) __u64 flags; __u64 rsvd1; __u64 rsvd2; -- cgit v1.2.3-70-g09d2 From 297b0c5be3b6e08890cbd7149313408847e81715 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 22 Oct 2010 17:02:41 +0100 Subject: drm/i915/ringbuffer: Write the value passed in to the tail register This should fix the error along the reset path were we tried to clear the tail register by setting it to 0, but were in fact setting it to the current value and complaining when it did not reset to 0. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 26 +++++++++++++------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0c6eb97d60f..4b53ca81ea4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -119,12 +119,12 @@ render_ring_flush(struct drm_device *dev, } } -static void ring_set_tail(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 value) +static void ring_write_tail(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 value) { drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE_TAIL(ring, ring->tail); + I915_WRITE_TAIL(ring, value); } u32 intel_ring_get_active_head(struct drm_device *dev, @@ -148,7 +148,7 @@ static int init_ring_common(struct drm_device *dev, /* Stop the ring if it's running. */ I915_WRITE_CTL(ring, 0); I915_WRITE_HEAD(ring, 0); - ring->set_tail(dev, ring, 0); + ring->write_tail(dev, ring, 0); /* Initialize the ring. */ I915_WRITE_START(ring, obj_priv->gtt_offset); @@ -729,7 +729,7 @@ void intel_ring_advance(struct drm_device *dev, struct intel_ring_buffer *ring) { ring->tail &= ring->size - 1; - ring->set_tail(dev, ring, ring->tail); + ring->write_tail(dev, ring, ring->tail); } static const struct intel_ring_buffer render_ring = { @@ -738,7 +738,7 @@ static const struct intel_ring_buffer render_ring = { .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_render_ring, - .set_tail = ring_set_tail, + .write_tail = ring_write_tail, .flush = render_ring_flush, .add_request = render_ring_add_request, .get_seqno = render_ring_get_seqno, @@ -755,7 +755,7 @@ static const struct intel_ring_buffer bsd_ring = { .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_bsd_ring, - .set_tail = ring_set_tail, + .write_tail = ring_write_tail, .flush = bsd_ring_flush, .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, @@ -765,9 +765,9 @@ static const struct intel_ring_buffer bsd_ring = { }; -static void gen6_bsd_ring_set_tail(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 value) +static void gen6_bsd_ring_write_tail(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 value) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -829,7 +829,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_bsd_ring, - .set_tail = gen6_bsd_ring_set_tail, + .write_tail = gen6_bsd_ring_write_tail, .flush = gen6_ring_flush, .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, @@ -859,7 +859,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_ring_common, - .set_tail = ring_set_tail, + .write_tail = ring_write_tail, .flush = gen6_ring_flush, .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 9e81ff3b39c..6ab40c6058f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -46,9 +46,9 @@ struct intel_ring_buffer { int (*init)(struct drm_device *dev, struct intel_ring_buffer *ring); - void (*set_tail)(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 value); + void (*write_tail)(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 value); void (*flush)(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, -- cgit v1.2.3-70-g09d2 From 641934069d29211baf82afb93622a426172b67b6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 24 Oct 2010 12:38:05 +0100 Subject: drm/i915: Move gpu_write_list to per-ring ... to prevent flush processing of an idle (or even absent) ring. This fixes a regression during suspend from 87acb0a5. Reported-and-tested-by: Alexey Fisher Tested-by: Peter Clifton Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 9 --------- drivers/gpu/drm/i915/i915_gem.c | 36 +++++++++++++++++---------------- drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + drivers/gpu/drm/i915/intel_ringbuffer.h | 9 +++++++++ 4 files changed, 29 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cc9cb0dda6f..2c2c19b6285 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -570,15 +570,6 @@ typedef struct drm_i915_private { */ struct list_head flushing_list; - /** - * List of objects currently pending a GPU write flush. - * - * All elements on this list will belong to either the - * active_list or flushing_list, last_rendering_seqno can - * be used to differentiate between the two elements. - */ - struct list_head gpu_write_list; - /** * LRU list of objects which are not in the ringbuffer and * are ready to unbind, but are still in the GTT. diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e7f27a5b89d..6c2618d884e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1657,12 +1657,11 @@ i915_gem_process_flushing_list(struct drm_device *dev, struct drm_i915_gem_object *obj_priv, *next; list_for_each_entry_safe(obj_priv, next, - &dev_priv->mm.gpu_write_list, + &ring->gpu_write_list, gpu_write_list) { struct drm_gem_object *obj = &obj_priv->base; - if (obj->write_domain & flush_domains && - obj_priv->ring == ring) { + if (obj->write_domain & flush_domains) { uint32_t old_write_domain = obj->write_domain; obj->write_domain = 0; @@ -2173,6 +2172,9 @@ i915_gem_object_unbind(struct drm_gem_object *obj) static int i915_ring_idle(struct drm_device *dev, struct intel_ring_buffer *ring) { + if (list_empty(&ring->gpu_write_list)) + return 0; + i915_gem_flush_ring(dev, NULL, ring, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); return i915_wait_request(dev, @@ -3786,14 +3788,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain = obj->write_domain; - obj->write_domain = obj->pending_write_domain; - if (obj->write_domain) - list_move_tail(&obj_priv->gpu_write_list, - &dev_priv->mm.gpu_write_list); - trace_i915_gem_object_change_domain(obj, obj->read_domains, old_write_domain); @@ -3858,9 +3854,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; - obj_priv = to_intel_bo(obj); i915_gem_object_move_to_active(obj, ring); + if (obj->write_domain) + list_move_tail(&to_intel_bo(obj)->gpu_write_list, + &ring->gpu_write_list); } i915_add_request(dev, file, request, ring); @@ -4618,6 +4616,14 @@ i915_gem_lastclose(struct drm_device *dev) DRM_ERROR("failed to idle hardware: %d\n", ret); } +static void +init_ring_lists(struct intel_ring_buffer *ring) +{ + INIT_LIST_HEAD(&ring->active_list); + INIT_LIST_HEAD(&ring->request_list); + INIT_LIST_HEAD(&ring->gpu_write_list); +} + void i915_gem_load(struct drm_device *dev) { @@ -4626,17 +4632,13 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.active_list); INIT_LIST_HEAD(&dev_priv->mm.flushing_list); - INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); INIT_LIST_HEAD(&dev_priv->mm.inactive_list); INIT_LIST_HEAD(&dev_priv->mm.pinned_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); - INIT_LIST_HEAD(&dev_priv->render_ring.active_list); - INIT_LIST_HEAD(&dev_priv->render_ring.request_list); - INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list); - INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list); - INIT_LIST_HEAD(&dev_priv->blt_ring.active_list); - INIT_LIST_HEAD(&dev_priv->blt_ring.request_list); + init_ring_lists(&dev_priv->render_ring); + init_ring_lists(&dev_priv->bsd_ring); + init_ring_lists(&dev_priv->blt_ring); for (i = 0; i < 16; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4b53ca81ea4..09f2dc353ae 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -580,6 +580,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->dev = dev; INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); + INIT_LIST_HEAD(&ring->gpu_write_list); if (I915_NEED_GFX_HWS(dev)) { ret = init_status_page(dev, ring); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 6ab40c6058f..a05aff0e576 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -82,6 +82,15 @@ struct intel_ring_buffer { */ struct list_head request_list; + /** + * List of objects currently pending a GPU write flush. + * + * All elements on this list will belong to either the + * active_list or flushing_list, last_rendering_seqno can + * be used to differentiate between the two elements. + */ + struct list_head gpu_write_list; + /** * Do we have some not yet emitted requests outstanding? */ -- cgit v1.2.3-70-g09d2