From e089de33e8efd87b30d59c571b9ab9aa302b23e1 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 21 Aug 2006 21:36:00 +0200 Subject: i915 fence object driver implementing 2 fence object types: 0x00 EXE fence. Signals when command stream interpreter has reached the point where the fence was emitted. 0x01 FLUSH fence. Signals when command stream interpreter has reached the point where the fence was emitted, and all previous drawing operations have been completed and flushed. Implements busy wait (for fastest response time / high CPU) and lazy wait (User interrupt or timer driven). --- linux-core/i915_fence.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 linux-core/i915_fence.c (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c new file mode 100644 index 00000000..46a2a728 --- /dev/null +++ b/linux-core/i915_fence.c @@ -0,0 +1,121 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include "drmP.h" +#include "drm.h" +#include "i915_drm.h" +#include "i915_drv.h" + +/* + * Implements an intel sync flush operation. + */ + +static void i915_perform_flush(drm_device_t * dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + drm_fence_manager_t *fm = &dev->fm; + drm_fence_driver_t *driver = dev->driver->fence_driver; + int flush_completed = 0; + uint32_t flush_flags = 0; + uint32_t flush_sequence = 0; + uint32_t i_status; + uint32_t diff; + uint32_t sequence; + + if (fm->pending_exe_flush) { + sequence = READ_BREADCRUMB(dev_priv); + diff = sequence - fm->last_exe_flush; + if (diff < driver->wrap_diff && diff != 0) { + drm_fence_handler(dev, sequence, DRM_FENCE_EXE); + diff = sequence - fm->exe_flush_sequence; + if (diff < driver->wrap_diff) { + fm->pending_exe_flush = 0; + /* + * Turn off user IRQs + */ + } else { + /* + * Turn on user IRQs + */ + } + } + } + if (dev_priv->flush_pending) { + i_status = READ_HWSP(dev_priv, 0); + if ((i_status & (1 << 12)) != + (dev_priv->saved_flush_status & (1 << 12))) { + flush_completed = 1; + flush_flags = dev_priv->flush_flags; + flush_sequence = dev_priv->flush_sequence; + dev_priv->flush_pending = 0; + } else { + } + } + if (flush_completed) { + drm_fence_handler(dev, flush_sequence, flush_flags); + } + if (fm->pending_flush && !dev_priv->flush_pending) { + dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); + dev_priv->flush_flags = fm->pending_flush; + dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0); + I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); + dev_priv->flush_pending = 1; + fm->pending_flush = 0; + } +} + +void i915_poke_flush(drm_device_t * dev) +{ + drm_fence_manager_t *fm = &dev->fm; + unsigned long flags; + + write_lock_irqsave(&fm->lock, flags); + i915_perform_flush(dev); + write_unlock_irqrestore(&fm->lock, flags); +} + +int i915_fence_emit_sequence(drm_device_t * dev, uint32_t * sequence) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + i915_emit_irq(dev); + *sequence = (uint32_t) dev_priv->counter; + return 0; +} + +void i915_fence_handler(drm_device_t * dev) +{ + drm_fence_manager_t *fm = &dev->fm; + + write_lock(&fm->lock); + i915_perform_flush(dev); + i915_perform_flush(dev); + write_unlock(&fm->lock); +} -- cgit v1.2.3 From 23f01c9fe8e6170459fe46ad5fc9757bbe967d96 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 29 Aug 2006 18:40:08 +0200 Subject: Checkpoint commit. Buffer object flags and IOCTL argument list. --- linux-core/i915_fence.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 46a2a728..452d4ee8 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -86,6 +86,8 @@ static void i915_perform_flush(drm_device_t * dev) dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); dev_priv->flush_flags = fm->pending_flush; dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0); + DRM_ERROR("Saved flush status is 0x%08x\n", + dev_priv->saved_flush_status); I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); dev_priv->flush_pending = 1; fm->pending_flush = 0; -- cgit v1.2.3 From 44f6d08988a77a640bea40d09cb61eec7566a5ce Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 31 Aug 2006 21:42:29 +0200 Subject: Validation and fencing. --- linux-core/i915_fence.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 452d4ee8..673ebd0e 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -121,3 +121,4 @@ void i915_fence_handler(drm_device_t * dev) i915_perform_flush(dev); write_unlock(&fm->lock); } + -- cgit v1.2.3 From 034fc31292edaa25779a938ab3e92ef34697eaf9 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 5 Sep 2006 14:23:18 +0200 Subject: i915: Only turn on user IRQs when they are needed. --- linux-core/i915_fence.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 673ebd0e..80ef3ab2 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -58,13 +58,9 @@ static void i915_perform_flush(drm_device_t * dev) diff = sequence - fm->exe_flush_sequence; if (diff < driver->wrap_diff) { fm->pending_exe_flush = 0; - /* - * Turn off user IRQs - */ + i915_user_irq_off(dev_priv); } else { - /* - * Turn on user IRQs - */ + i915_user_irq_on(dev_priv); } } } -- cgit v1.2.3 From 99acb7936660843090ea8a9f22d2d50d9433e0de Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 8 Sep 2006 17:24:38 +0200 Subject: Various bugfixes. --- linux-core/i915_fence.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 80ef3ab2..20e12d6a 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -55,13 +55,18 @@ static void i915_perform_flush(drm_device_t * dev) diff = sequence - fm->last_exe_flush; if (diff < driver->wrap_diff && diff != 0) { drm_fence_handler(dev, sequence, DRM_FENCE_EXE); - diff = sequence - fm->exe_flush_sequence; - if (diff < driver->wrap_diff) { - fm->pending_exe_flush = 0; + } + + diff = sequence - fm->exe_flush_sequence; + if (diff < driver->wrap_diff) { + fm->pending_exe_flush = 0; + if (dev_priv->fence_irq_on) { i915_user_irq_off(dev_priv); - } else { - i915_user_irq_on(dev_priv); + dev_priv->fence_irq_on = 0; } + } else if (!dev_priv->fence_irq_on) { + i915_user_irq_on(dev_priv); + dev_priv->fence_irq_on = 1; } } if (dev_priv->flush_pending) { @@ -82,8 +87,6 @@ static void i915_perform_flush(drm_device_t * dev) dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); dev_priv->flush_flags = fm->pending_flush; dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0); - DRM_ERROR("Saved flush status is 0x%08x\n", - dev_priv->saved_flush_status); I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); dev_priv->flush_pending = 1; fm->pending_flush = 0; -- cgit v1.2.3 From 49fbeb339c232804866cd548d6023fe559597353 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 15 Sep 2006 11:18:35 +0200 Subject: Some bugfixes. Change the fence object interface somewhat to allow some more flexibility. Make list IOCTLS really restartable. Try to avoid busy-waits in the kernel using immediate return to user-space with an -EAGAIN. --- linux-core/i915_fence.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 20e12d6a..5a8612cb 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -43,7 +43,6 @@ static void i915_perform_flush(drm_device_t * dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_fence_manager_t *fm = &dev->fm; drm_fence_driver_t *driver = dev->driver->fence_driver; - int flush_completed = 0; uint32_t flush_flags = 0; uint32_t flush_sequence = 0; uint32_t i_status; @@ -52,9 +51,14 @@ static void i915_perform_flush(drm_device_t * dev) if (fm->pending_exe_flush) { sequence = READ_BREADCRUMB(dev_priv); + + /* + * First update fences with the current breadcrumb. + */ + diff = sequence - fm->last_exe_flush; if (diff < driver->wrap_diff && diff != 0) { - drm_fence_handler(dev, sequence, DRM_FENCE_EXE); + drm_fence_handler(dev, sequence, DRM_FENCE_TYPE_EXE); } diff = sequence - fm->exe_flush_sequence; @@ -69,20 +73,18 @@ static void i915_perform_flush(drm_device_t * dev) dev_priv->fence_irq_on = 1; } } + if (dev_priv->flush_pending) { i_status = READ_HWSP(dev_priv, 0); if ((i_status & (1 << 12)) != (dev_priv->saved_flush_status & (1 << 12))) { - flush_completed = 1; flush_flags = dev_priv->flush_flags; flush_sequence = dev_priv->flush_sequence; dev_priv->flush_pending = 0; - } else { - } - } - if (flush_completed) { - drm_fence_handler(dev, flush_sequence, flush_flags); + drm_fence_handler(dev, flush_sequence, flush_flags); + } } + if (fm->pending_flush && !dev_priv->flush_pending) { dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); dev_priv->flush_flags = fm->pending_flush; @@ -91,6 +93,18 @@ static void i915_perform_flush(drm_device_t * dev) dev_priv->flush_pending = 1; fm->pending_flush = 0; } + + if (dev_priv->flush_pending) { + i_status = READ_HWSP(dev_priv, 0); + if ((i_status & (1 << 12)) != + (dev_priv->saved_flush_status & (1 << 12))) { + flush_flags = dev_priv->flush_flags; + flush_sequence = dev_priv->flush_sequence; + dev_priv->flush_pending = 0; + drm_fence_handler(dev, flush_sequence, flush_flags); + } + } + } void i915_poke_flush(drm_device_t * dev) @@ -117,7 +131,6 @@ void i915_fence_handler(drm_device_t * dev) write_lock(&fm->lock); i915_perform_flush(dev); - i915_perform_flush(dev); write_unlock(&fm->lock); } -- cgit v1.2.3 From f613022ceef1814cb734bb3375f01962fd3bcf10 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 15 Sep 2006 16:47:09 +0200 Subject: Allow a "native type" to be associated with a fence sequence. In the intel case, we can associate a flush with a sequence. --- linux-core/i915_fence.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 5a8612cb..8a3f81fe 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -86,6 +86,7 @@ static void i915_perform_flush(drm_device_t * dev) } if (fm->pending_flush && !dev_priv->flush_pending) { + DRM_ERROR("Sync flush"); dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); dev_priv->flush_flags = fm->pending_flush; dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0); @@ -117,11 +118,16 @@ void i915_poke_flush(drm_device_t * dev) write_unlock_irqrestore(&fm->lock, flags); } -int i915_fence_emit_sequence(drm_device_t * dev, uint32_t * sequence) +int i915_fence_emit_sequence(drm_device_t * dev, uint32_t flags, + uint32_t * sequence, uint32_t *native_type) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; i915_emit_irq(dev); *sequence = (uint32_t) dev_priv->counter; + *native_type = DRM_FENCE_TYPE_EXE; + if (flags & DRM_I915_FENCE_FLAG_FLUSHED) + *native_type |= DRM_I915_FENCE_TYPE_RW; + return 0; } -- cgit v1.2.3 From ca1b15d645c74e20f638f5a09981bcf02f58caee Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 18 Sep 2006 20:43:31 +0200 Subject: Alternative implementation of page table zeroing using zap page_range. (Disabled for now) Fix bo_wait_idle bug. Remove stray debug message. --- linux-core/i915_fence.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 8a3f81fe..7491a672 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -86,7 +86,6 @@ static void i915_perform_flush(drm_device_t * dev) } if (fm->pending_flush && !dev_priv->flush_pending) { - DRM_ERROR("Sync flush"); dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); dev_priv->flush_flags = fm->pending_flush; dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0); -- cgit v1.2.3 From 273eb7833d69db2d72430d5c96c21cebd05c206e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 25 Sep 2006 11:51:08 +0200 Subject: Add /proc filesystem buffer / fence object accounting. Check for NULL pointer in the i915 flush handler. Remove i915_sync_flush declaration. --- linux-core/i915_fence.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 7491a672..49dc254f 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -49,6 +49,9 @@ static void i915_perform_flush(drm_device_t * dev) uint32_t diff; uint32_t sequence; + if (!dev_priv) + return; + if (fm->pending_exe_flush) { sequence = READ_BREADCRUMB(dev_priv); -- cgit v1.2.3 From 89b944179856fadf8667587eff142129c2c6b826 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 19:57:06 +0200 Subject: Lindent. --- linux-core/i915_fence.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index 49dc254f..fc8ab761 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -62,7 +62,7 @@ static void i915_perform_flush(drm_device_t * dev) diff = sequence - fm->last_exe_flush; if (diff < driver->wrap_diff && diff != 0) { drm_fence_handler(dev, sequence, DRM_FENCE_TYPE_EXE); - } + } diff = sequence - fm->exe_flush_sequence; if (diff < driver->wrap_diff) { @@ -85,7 +85,7 @@ static void i915_perform_flush(drm_device_t * dev) flush_sequence = dev_priv->flush_sequence; dev_priv->flush_pending = 0; drm_fence_handler(dev, flush_sequence, flush_flags); - } + } } if (fm->pending_flush && !dev_priv->flush_pending) { @@ -105,7 +105,7 @@ static void i915_perform_flush(drm_device_t * dev) flush_sequence = dev_priv->flush_sequence; dev_priv->flush_pending = 0; drm_fence_handler(dev, flush_sequence, flush_flags); - } + } } } @@ -121,15 +121,15 @@ void i915_poke_flush(drm_device_t * dev) } int i915_fence_emit_sequence(drm_device_t * dev, uint32_t flags, - uint32_t * sequence, uint32_t *native_type) + uint32_t * sequence, uint32_t * native_type) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; i915_emit_irq(dev); *sequence = (uint32_t) dev_priv->counter; - *native_type = DRM_FENCE_TYPE_EXE; - if (flags & DRM_I915_FENCE_FLAG_FLUSHED) + *native_type = DRM_FENCE_TYPE_EXE; + if (flags & DRM_I915_FENCE_FLAG_FLUSHED) *native_type |= DRM_I915_FENCE_TYPE_RW; - + return 0; } @@ -141,4 +141,3 @@ void i915_fence_handler(drm_device_t * dev) i915_perform_flush(dev); write_unlock(&fm->lock); } - -- cgit v1.2.3 From e8ba62db722eb0b915377269d7e1c3a039928669 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 19 Oct 2006 16:58:00 +0200 Subject: Make sure delayed delete list is empty on lastclose. Fix some refcounting errors. Fix some error messages. --- linux-core/i915_fence.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux-core/i915_fence.c') diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index fc8ab761..2182604c 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -124,6 +124,9 @@ int i915_fence_emit_sequence(drm_device_t * dev, uint32_t flags, uint32_t * sequence, uint32_t * native_type) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + if (!dev_priv) + return -EINVAL; + i915_emit_irq(dev); *sequence = (uint32_t) dev_priv->counter; *native_type = DRM_FENCE_TYPE_EXE; -- cgit v1.2.3