From b259f6730c09bc356df932ba9188f291de816808 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 29 Mar 2011 13:19:09 +0100 Subject: drm/i915: Move the irq wait queue initialisation into the ring init Required so that we don't obliterate the queue if initialising the rings after the global IRQ handler is installed. [Jesse, you recently looked at refactoring the IRQ installation routines, does moving the initialisation of ring buffer data structures away from that routine make sense in your grand scheme?] Signed-off-by: Chris Wilson Cc: Jesse Barnes Reviewed-by: Ben Widawsky Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e9e6f71418a4..884556d9814e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -800,6 +800,7 @@ int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(&ring->request_list); INIT_LIST_HEAD(&ring->gpu_write_list); + init_waitqueue_head(&ring->irq_queue); spin_lock_init(&ring->irq_lock); ring->irq_mask = ~0; -- cgit v1.2.3 From 96f298aa9c9fc9b7c8a2ebaf8c195d178f570e09 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Sat, 19 Mar 2011 18:14:27 -0700 Subject: drm/1915: ringbuffer wait for idle function Added a new function which waits for the ringbuffer space to be equal to (total - 8). This is the empty condition of the ringbuffer, and equivalent to head==tail. Also modified two users of this functionality elsewhere in the code. Signed-off-by: Ben Widawsky Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 884556d9814e..07e59072e129 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -873,7 +873,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) /* Disable the ring buffer. The ring must be idle at this point */ dev_priv = ring->dev->dev_private; - ret = intel_wait_ring_buffer(ring, ring->size - 8); + ret = intel_wait_ring_idle(ring); if (ret) DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", ring->name, ret); -- cgit v1.2.3 From 93dfb40cd887c4f39e38f047c4d9ea0b7188a58a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 29 Mar 2011 16:59:50 -0700 Subject: drm/i915: Rename agp_type to cache_level ... to clarify just how we use it inside the driver and remove the confusion of the poorly matching agp_type names. We still need to translate through agp_type for interface into the fake AGP driver. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Reviewed-by: Daniel Vetter Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 07e59072e129..bf63869f6a07 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -236,7 +236,7 @@ init_pipe_control(struct intel_ring_buffer *ring) ret = -ENOMEM; goto err; } - obj->agp_type = AGP_USER_CACHED_MEMORY; + obj->cache_level = I915_CACHE_LLC; ret = i915_gem_object_pin(obj, 4096, true); if (ret) @@ -759,7 +759,7 @@ static int init_status_page(struct intel_ring_buffer *ring) ret = -ENOMEM; goto err; } - obj->agp_type = AGP_USER_CACHED_MEMORY; + obj->cache_level = I915_CACHE_LLC; ret = i915_gem_object_pin(obj, 4096, true); if (ret != 0) { -- cgit v1.2.3 From 65d3eb1e065c5e558a584fabe583daa5fdd63b75 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 6 Apr 2011 14:54:44 -0700 Subject: drm/i915: ring support for Ivy Bridge Use Sandy Bridge paths in a few places. Signed-off-by: Jesse Barnes Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index bf63869f6a07..12c168f0cb77 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -286,7 +286,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen > 3) { int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; - if (IS_GEN6(dev)) + if (IS_GEN6(dev) || IS_GEN7(dev)) mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; I915_WRITE(MI_MODE, mode); } @@ -552,7 +552,7 @@ render_ring_put_irq(struct intel_ring_buffer *ring) void intel_ring_setup_status_page(struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = ring->dev->dev_private; - u32 mmio = IS_GEN6(ring->dev) ? + u32 mmio = (IS_GEN6(ring->dev) || IS_GEN7(ring->dev)) ? RING_HWS_PGA_GEN6(ring->mmio_base) : RING_HWS_PGA(ring->mmio_base); I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); @@ -1334,7 +1334,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; - if (IS_GEN6(dev)) + if (IS_GEN6(dev) || IS_GEN7(dev)) *ring = gen6_bsd_ring; else *ring = bsd_ring; -- cgit v1.2.3 From 4593010b68247e6bed746da4e15f66f06e239e28 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 6 May 2011 17:12:35 -0700 Subject: drm/i915: Update the location of the ringbuffers' HWS_PGA registers for IVB. They have been moved from the ringbuffer groups to their own group it looks like. Fixes GPU hangs on gnome startup. Signed-off-by: Eric Anholt Reviewed-by: Jesse Barnes Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 12c168f0cb77..3971b5e6ad60 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -551,10 +551,31 @@ render_ring_put_irq(struct intel_ring_buffer *ring) void intel_ring_setup_status_page(struct intel_ring_buffer *ring) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = ring->dev->dev_private; - u32 mmio = (IS_GEN6(ring->dev) || IS_GEN7(ring->dev)) ? - RING_HWS_PGA_GEN6(ring->mmio_base) : - RING_HWS_PGA(ring->mmio_base); + u32 mmio = 0; + + /* The ring status page addresses are no longer next to the rest of + * the ring registers as of gen7. + */ + if (IS_GEN7(dev)) { + switch (ring->id) { + case RING_RENDER: + mmio = RENDER_HWS_PGA_GEN7; + break; + case RING_BLT: + mmio = BLT_HWS_PGA_GEN7; + break; + case RING_BSD: + mmio = BSD_HWS_PGA_GEN7; + break; + } + } else if (IS_GEN6(ring->dev)) { + mmio = RING_HWS_PGA_GEN6(ring->mmio_base); + } else { + mmio = RING_HWS_PGA(ring->mmio_base); + } + I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); POSTING_READ(mmio); } -- cgit v1.2.3 From 5bfa1063a775836a84f97e4df863fc36e1f856ad Mon Sep 17 00:00:00 2001 From: "Feng, Boqun" Date: Mon, 16 May 2011 16:02:39 +0800 Subject: drm/i915: fix user irq miss in BSD ring on g4x On g4x, user interrupt in BSD ring is missed. This is because though g4x and ironlake share the same bsd_ring, their interrupt control interfaces have _two_ differences. 1.different irq enable/disable functions: On g4x are i915_enable_irq and i915_disable_irq. On ironlake are ironlake_enable_irq and ironlake_disable_irq. 2.different irq flag: On g4x user interrupt flag in BSD ring on is I915_BSD_USER_INTERRUPT. On ironlake is GT_BSD_USER_INTERRUPT Old bsd_ring_get/put_irq call ring_get_irq and ring_get_irq. ring_get_irq and ring_put_irq only call ironlake_enable/disable_irq. So comes the irq miss on g4x. To fix this, as other rings' code do, conditionally call different functions(i915_enable/disable_irq and ironlake_enable/disable_irq) and use different interrupt flags in bsd_ring_get/put_irq. Signed-off-by: Feng, Boqun Reviewed-by: Xiang, Haihao Cc: stable@kernel.org Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3971b5e6ad60..69cdbcd6e5b7 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -687,12 +687,37 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) static bool bsd_ring_get_irq(struct intel_ring_buffer *ring) { - return ring_get_irq(ring, GT_BSD_USER_INTERRUPT); + struct drm_device *dev = ring->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (!dev->irq_enabled) + return false; + + spin_lock(&ring->irq_lock); + if (ring->irq_refcount++ == 0) { + if (IS_G4X(dev)) + i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT); + else + ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT); + } + spin_unlock(&ring->irq_lock); + + return true; } static void bsd_ring_put_irq(struct intel_ring_buffer *ring) { - ring_put_irq(ring, GT_BSD_USER_INTERRUPT); + struct drm_device *dev = ring->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + spin_lock(&ring->irq_lock); + if (--ring->irq_refcount == 0) { + if (IS_G4X(dev)) + i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT); + else + ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT); + } + spin_unlock(&ring->irq_lock); } static int -- cgit v1.2.3 From 8547920fc6f0d288fcc57ca705ccb2d00920fc72 Mon Sep 17 00:00:00 2001 From: "Feng, Boqun" Date: Thu, 28 Apr 2011 17:15:33 +0800 Subject: drm/i915: clean up unused ring_get_irq/ring_put_irq functions This patch depends on patch "drm/i915: fix user irq miss in BSD ring on g4x". Once the previous patch apply, ring_get_irq/ring_put_irq become unused. So simply remove them. Signed-off-by: Feng, Boqun Reviewed-by: Xiang, Haihao Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_ringbuffer.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 69cdbcd6e5b7..95c4b1429935 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -620,35 +620,6 @@ ring_add_request(struct intel_ring_buffer *ring, return 0; } -static bool -ring_get_irq(struct intel_ring_buffer *ring, u32 flag) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev->irq_enabled) - return false; - - spin_lock(&ring->irq_lock); - if (ring->irq_refcount++ == 0) - ironlake_enable_irq(dev_priv, flag); - spin_unlock(&ring->irq_lock); - - return true; -} - -static void -ring_put_irq(struct intel_ring_buffer *ring, u32 flag) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - spin_lock(&ring->irq_lock); - if (--ring->irq_refcount == 0) - ironlake_disable_irq(dev_priv, flag); - spin_unlock(&ring->irq_lock); -} - static bool gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) { -- cgit v1.2.3