From: <al...@ke...> - 2007-10-23 14:34:33
|
bsd-core/drm_drv.c | 15 +++++---- shared-core/i915_dma.c | 70 ++++++++++++++++++++++++++++++---------------- shared-core/nouveau_mem.c | 2 - tests/auth.c | 4 +- tests/lock.c | 9 +++-- 5 files changed, 63 insertions(+), 37 deletions(-) New commits: commit d5f2b4b411c5ca95d6f66a33d213ece387ac4fc5 Merge: 198170a... a294aa7... Author: Alan Hourihane <al...@tu...> Date: Tue Oct 23 15:34:12 2007 +0100 Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101 commit a294aa724a1e932fb6017383e08532bfcc914df0 Author: Dave Airlie <ai...@li...> Date: Tue Oct 23 17:54:07 2007 +1000 i915: require mfence before submitting batchbuffer diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index d0d65f8..f0fd603 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1044,6 +1044,9 @@ static int i915_execbuffer(struct drm_device *dev, void *data, if (ret) goto out_free; + /* make sure all previous memory operations have passed */ + asm volatile("mfence":::"memory"); + /* submit buffer */ batch->start = buffers[num_buffers-1]->offset; commit 9a115080e870f8196adef4a19598343e63e61e45 Author: Stephane Marchesin <mar...@ic...> Date: Tue Oct 23 02:18:56 2007 +0200 nouveau: fix IGP diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index e2f0b38..448b69d 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -223,7 +223,7 @@ void nouveau_mem_close(struct drm_device *dev) static uint32_t nouveau_mem_fb_amount_igp(struct drm_device *dev) { -#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) +#if defined(__linux__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) struct drm_nouveau_private *dev_priv = dev->dev_private; struct pci_dev *bridge; uint32_t mem; commit 22883ff26b8a45ab2bec60accc4b822cf6b4f214 Author: Dave Airlie <ai...@re...> Date: Mon Oct 22 11:54:41 2007 +1100 i915: split reloc execution into separate function diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5a51f6e..d0d65f8 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -873,6 +873,43 @@ out: return ret; } +static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, + drm_handle_t buf_reloc_handle, + struct drm_buffer_object **buffers, + uint32_t buf_count) +{ + struct drm_device *dev = file_priv->head->dev; + struct i915_relocatee_info relocatee; + int ret = 0; + + memset(&relocatee, 0, sizeof(relocatee)); + + mutex_lock(&dev->struct_mutex); + relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + mutex_unlock(&dev->struct_mutex); + if (!relocatee.buf) { + DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); + ret = -EINVAL; + goto out_err; + } + + while (buf_reloc_handle) { + ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); + if (ret) { + DRM_ERROR("process relocs failed\n"); + break; + } + } + + drm_bo_kunmap(&relocatee.kmap); + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&relocatee.buf); + mutex_unlock(&dev->struct_mutex); + +out_err: + return ret; +} + /* * Validate, add fence and relocate a block of bos from a userspace list */ @@ -889,7 +926,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, unsigned buf_count = 0; struct drm_device *dev = file_priv->head->dev; uint32_t buf_reloc_handle, buf_handle; - struct i915_relocatee_info relocatee; + do { if (buf_count >= *num_buffers) { @@ -950,33 +987,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buf_count++; if (buf_reloc_handle) { - memset(&relocatee, 0, sizeof(relocatee)); - - mutex_lock(&dev->struct_mutex); - relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); - mutex_unlock(&dev->struct_mutex); - if (!relocatee.buf) { - DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); - ret = -EINVAL; - goto out_err; - } - - while (buf_reloc_handle) { - ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); - if (ret) { - DRM_ERROR("process relocs failed\n"); - break; - } - } - - drm_bo_kunmap(&relocatee.kmap); - mutex_lock(&dev->struct_mutex); - drm_bo_usage_deref_locked(&relocatee.buf); - mutex_unlock(&dev->struct_mutex); - + ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); if (ret) goto out_err; - } } while (next != 0); *num_buffers = buf_count; commit 2c5c18fbd394f419a9cf650720a1187440c643cd Author: Robert Noland <rn...@2h...> Date: Wed Oct 17 13:25:31 2007 -0700 Bug #12838: Fix lock test client vs. server master race and misplaced closes. diff --git a/tests/lock.c b/tests/lock.c index 3f62755..86caa28 100644 --- a/tests/lock.c +++ b/tests/lock.c @@ -87,8 +87,6 @@ client_auth(int drmfd) struct drm_auth auth; int ret; - wait_event(0, SERVER_READY); - /* Get a client magic number and pass it to the master for auth. */ ret = ioctl(drmfd, DRM_IOCTL_GET_MAGIC, &auth); if (ret == -1) @@ -172,8 +170,6 @@ static void test_open_close_locked(drmfd) ret = drmUnlock(drmfd, lock1); if (ret != 0) errx(1, "lock lost during open/close by same pid"); - - close(drmfd); } static void client() @@ -181,6 +177,8 @@ static void client() int drmfd, ret; unsigned int time; + wait_event(0, SERVER_READY); + /* XXX: Should make sure we open the same DRM as the master */ drmfd = drm_open_any(); @@ -201,6 +199,7 @@ static void client() send_event(0, CLIENT_LOCKED); ret = write(commfd[0], &time, sizeof(time)); + close(drmfd); exit(0); } @@ -238,6 +237,8 @@ static void server() if (client_time < unlock_time) errx(1, "Client took lock before server released it"); + + close(drmfd); } int main(int argc, char **argv) commit e7523d337997018a86530266a8f3f88dd061c138 Author: Robert Noland <rn...@2h...> Date: Wed Oct 17 13:20:46 2007 -0700 Fix a race in the auth test where client prevents server from being master. diff --git a/tests/auth.c b/tests/auth.c index 4160d1d..9b6fca9 100644 --- a/tests/auth.c +++ b/tests/auth.c @@ -69,10 +69,10 @@ static void client() int drmfd, ret; /* XXX: Should make sure we open the same DRM as the master */ - drmfd = drm_open_any(); - wait_event(0, SERVER_READY); + drmfd = drm_open_any(); + /* Get a client magic number and pass it to the master for auth. */ auth.magic = 0; /* Quiet valgrind */ ret = ioctl(drmfd, DRM_IOCTL_GET_MAGIC, &auth); commit 36120264ca8f43078f8748e022faeb9471edcb36 Author: Jung-uk Kim <jkim@FreeBSD.org> Date: Wed Oct 17 12:50:29 2007 -0700 Bug #11870: FreeBSD hardware lock cleanup fix with multiple opens by a process. Previously, the lock would get released on the first close by the X Server (during AIGLX setup), and the Radeon driver would then hang in initialization due to unexpected failure in DRM calls that required the lock to be held. Based on a patch by Kostik Belousov. diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index c36b78a..d6868b9 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -538,6 +538,7 @@ static int drm_load(drm_device_t *dev) if (dev->driver.load != NULL) { DRM_LOCK(); + /* Shared code returns -errno. */ retcode = -dev->driver.load(dev, dev->id_entry->driver_private); DRM_UNLOCK(); @@ -720,6 +721,9 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) return EINVAL; } + if (--file_priv->refs != 0) + goto done; + if (dev->driver.preclose != NULL) dev->driver.preclose(dev, file_priv); @@ -795,17 +799,16 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) dev->buf_pgid = 0; #endif /* __NetBSD__ || __OpenBSD__ */ - if (--file_priv->refs == 0) { - if (dev->driver.postclose != NULL) - dev->driver.postclose(dev, file_priv); - TAILQ_REMOVE(&dev->files, file_priv, link); - free(file_priv, M_DRM); - } + if (dev->driver.postclose != NULL) + dev->driver.postclose(dev, file_priv); + TAILQ_REMOVE(&dev->files, file_priv, link); + free(file_priv, M_DRM); /* ======================================================== * End inline drm_release */ +done: atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); #ifdef __FreeBSD__ device_unbusy(dev->device); commit ec1162b212248042bf1317abcb3c47bb10db8aa3 Author: Dave Airlie <airlied@optimus.(none)> Date: Wed Oct 17 15:36:14 2007 +1000 i915: lock struct mutex about buffer object lookups diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 7209a8d..5a51f6e 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -805,7 +805,9 @@ int i915_process_relocs(struct drm_file *file_priv, memset(&reloc_kmap, 0, sizeof(reloc_kmap)); + mutex_lock(&dev->struct_mutex); reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1); + mutex_unlock(&dev->struct_mutex); if (!reloc_list_object) return -EINVAL; @@ -905,7 +907,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (arg.handled) { data = arg.next; + mutex_lock(&dev->struct_mutex); buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + mutex_unlock(&dev->struct_mutex); buf_count++; continue; } @@ -948,7 +952,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (buf_reloc_handle) { memset(&relocatee, 0, sizeof(relocatee)); + mutex_lock(&dev->struct_mutex); relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + mutex_unlock(&dev->struct_mutex); if (!relocatee.buf) { DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); ret = -EINVAL; |
From: <th...@ke...> - 2007-11-06 09:12:04
|
linux-core/Makefile.kernel | 2 linux-core/drm_agpsupport.c | 39 +++----- linux-core/drm_bo.c | 15 ++- linux-core/drm_regman.c | 205 ++++++++++++++++++++++++++++++++++++++++++++ linux-core/i915_buffer.c | 31 +++--- linux-core/i915_compat.c | 24 ++--- linux-core/i915_fence.c | 13 +- shared-core/i915_dma.c | 1 shared-core/i915_drv.h | 4 shared-core/i915_irq.c | 10 +- 10 files changed, 277 insertions(+), 67 deletions(-) New commits: commit c07dd80269fad45fdad61de0a43fe3d15cd1a119 Merge: 5ce43a3... 40fb079... Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Nov 6 10:01:52 2007 +0100 Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101 Conflicts: linux-core/Makefile.kernel shared-core/i915_dma.c shared-core/i915_drv.h shared-core/i915_irq.c diff --cc linux-core/Makefile.kernel index 47364b1,e7c280d..63c93f0 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@@ -13,8 -13,8 +13,8 @@@ drm-objs := drm_auth.o drm_bufs.o dr drm_sysfs.o drm_pci.o drm_agpsupport.o drm_scatter.o \ drm_memory_debug.o ati_pcigart.o drm_sman.o \ drm_hashtab.o drm_mm.o drm_object.o drm_compat.o \ - drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o \ - drm_regman.o + drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_crtc.o \ - drm_edid.o drm_modes.o drm_bo_lock.o ++ drm_edid.o drm_modes.o drm_bo_lock.o drm_regman.o tdfx-objs := tdfx_drv.o r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o diff --cc linux-core/i915_fence.c index 068c8be,e3c76df..21d032b --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@@ -38,9 -38,9 +38,9 @@@ * Implements an intel sync flush operation. */ - static void i915_perform_flush(struct drm_device * dev) + static void i915_perform_flush(struct drm_device *dev) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; struct drm_fence_manager *fm = &dev->fm; struct drm_fence_class_manager *fc = &fm->fence_class[0]; struct drm_fence_driver *driver = dev->driver->fence_driver; @@@ -120,10 -120,11 +120,11 @@@ void i915_poke_flush(struct drm_device write_unlock_irqrestore(&fm->lock, flags); } - int i915_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t flags, - uint32_t * sequence, uint32_t * native_type) + int i915_fence_emit_sequence(struct drm_device *dev, uint32_t class, + uint32_t flags, uint32_t *sequence, + uint32_t *native_type) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; if (!dev_priv) return -EINVAL; diff --cc shared-core/i915_dma.c index ed3a07d,541b4cc..47befeb --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@@ -1312,4 -1399,11 +1312,3 @@@ int i915_driver_device_is_agp(struct dr return 1; } - -int i915_driver_firstopen(struct drm_device *dev) -{ -#ifdef I915_HAVE_BUFFER - if (!IS_I9XX(dev)) - drm_bo_driver_init(dev); -#endif - return 0; -} diff --cc shared-core/i915_irq.c index edb6122,2c699ec..bd57607 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@@ -365,10 -365,9 +365,10 @@@ irqreturn_t i915_driver_irq_handler(DRM return IRQ_HANDLED; } - int i915_emit_irq(struct drm_device * dev) + int i915_emit_irq(struct drm_device *dev) { - drm_i915_private_t *dev_priv = dev->dev_private; + + struct drm_i915_private *dev_priv = dev->dev_private; RING_LOCALS; i915_kernel_lost_context(dev); @@@ -383,11 -382,9 +383,9 @@@ ADVANCE_LP_RING(); return dev_priv->counter; - - } -void i915_user_irq_on(drm_i915_private_t *dev_priv) +void i915_user_irq_on(struct drm_i915_private *dev_priv) { DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ @@@ -484,10 -468,11 +482,11 @@@ int i915_driver_vblank_wait2(struct drm /* Needs the lock as it touches the ring. */ - int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) + int i915_irq_emit(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_emit_t *emit = data; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_irq_emit *emit = data; int result; LOCK_TEST_WITH_RETURN(dev, file_priv); @@@ -766,8 -750,9 +765,9 @@@ void i915_driver_irq_postinstall(struc void i915_driver_irq_uninstall(struct drm_device * dev) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u16 temp; + if (!dev_priv) return; commit 40fb079aebae4277813e6a32e2e93c81dc0038e3 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Nov 6 09:47:57 2007 +0100 Avoid buffers not ending up on a list in some cases. diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 6bfc6df..b107798 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1331,16 +1331,25 @@ int drm_bo_move_buffer(struct drm_buffer_object *bo, uint64_t new_mem_flags, ret = drm_bo_handle_move_mem(bo, &mem, 0, no_wait); out_unlock: + mutex_lock(&dev->struct_mutex); if (ret || !move_unfenced) { - mutex_lock(&dev->struct_mutex); if (mem.mm_node) { if (mem.mm_node != bo->pinned_node) drm_mm_put_block(mem.mm_node); mem.mm_node = NULL; } - mutex_unlock(&dev->struct_mutex); + drm_bo_add_to_lru(bo); + if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) { + DRM_WAKEUP(&bo->event_queue); + DRM_FLAG_MASKED(bo->priv_flags, 0, + _DRM_BO_FLAG_UNFENCED); + } + } else { + list_add_tail(&bo->lru, &bm->unfenced); + DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED, + _DRM_BO_FLAG_UNFENCED); } - + mutex_unlock(&dev->struct_mutex); mutex_unlock(&bm->evict_mutex); return ret; } commit 20eecf2b884193d865419312290b2bb9f94ebf37 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Nov 6 09:36:25 2007 +0100 Add missing drm_regman.c file. diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index d1f3bb7..e7c280d 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -13,7 +13,8 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ drm_sysfs.o drm_pci.o drm_agpsupport.o drm_scatter.o \ drm_memory_debug.o ati_pcigart.o drm_sman.o \ drm_hashtab.o drm_mm.o drm_object.o drm_compat.o \ - drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o + drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o \ + drm_regman.o tdfx-objs := tdfx_drv.o r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o diff --git a/linux-core/drm_regman.c b/linux-core/drm_regman.c new file mode 100644 index 0000000..f49a25c --- /dev/null +++ b/linux-core/drm_regman.c @@ -0,0 +1,205 @@ +/************************************************************************** + * Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., 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 above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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. + * + **************************************************************************/ +/* + * An allocate-fence manager implementation intended for sets of base-registers + * or tiling-registers. + */ + +#include "drmP.h" + +/* + * Allocate a compatible register and put it on the unfenced list. + */ + +int drm_regs_alloc(struct drm_reg_manager *manager, + const void *data, + uint32_t fence_class, + uint32_t fence_type, + int interruptible, int no_wait, struct drm_reg **reg) +{ + struct drm_reg *entry, *next_entry; + int ret; + + *reg = NULL; + + /* + * Search the unfenced list. + */ + + list_for_each_entry(entry, &manager->unfenced, head) { + if (manager->reg_reusable(entry, data)) { + entry->new_fence_type |= fence_type; + goto out; + } + } + + /* + * Search the lru list. + */ + + list_for_each_entry_safe(entry, next_entry, &manager->lru, head) { + struct drm_fence_object *fence = entry->fence; + if (fence->fence_class == fence_class && + (entry->fence_type & fence_type) == entry->fence_type && + manager->reg_reusable(entry, data)) { + list_del(&entry->head); + entry->new_fence_type = fence_type; + list_add_tail(&entry->head, &manager->unfenced); + goto out; + } + } + + /* + * Search the free list. + */ + + list_for_each_entry(entry, &manager->free, head) { + list_del(&entry->head); + entry->new_fence_type = fence_type; + list_add_tail(&entry->head, &manager->unfenced); + goto out; + } + + if (no_wait) + return -EBUSY; + + /* + * Go back to the lru list and try to expire fences. + */ + + list_for_each_entry_safe(entry, next_entry, &manager->lru, head) { + BUG_ON(!entry->fence); + ret = drm_fence_object_wait(entry->fence, 0, !interruptible, + entry->fence_type); + if (ret) + return ret; + + drm_fence_usage_deref_unlocked(&entry->fence); + list_del(&entry->head); + entry->new_fence_type = fence_type; + list_add_tail(&entry->head, &manager->unfenced); + goto out; + } + + /* + * Oops. All registers are used up :(. + */ + + return -EBUSY; + out: + *reg = entry; + return 0; +} + +EXPORT_SYMBOL(drm_regs_alloc); + +void drm_regs_fence(struct drm_reg_manager *manager, + struct drm_fence_object *fence) +{ + struct drm_reg *entry; + struct drm_reg *next_entry; + + if (!fence) { + + /* + * Old fence (if any) is still valid. + * Put back on free and lru lists. + */ + + list_for_each_entry_safe_reverse(entry, next_entry, + &manager->unfenced, head) { + list_del(&entry->head); + list_add(&entry->head, (entry->fence) ? + &manager->lru : &manager->free); + } + } else { + + /* + * Fence with a new fence and put on lru list. + */ + + list_for_each_entry_safe(entry, next_entry, &manager->unfenced, + head) { + list_del(&entry->head); + if (entry->fence) + drm_fence_usage_deref_unlocked(&entry->fence); + drm_fence_reference_unlocked(&entry->fence, fence); + + entry->fence_type = entry->new_fence_type; + BUG_ON((entry->fence_type & fence->type) != + entry->fence_type); + + list_add_tail(&entry->head, &manager->lru); + } + } +} + +EXPORT_SYMBOL(drm_regs_fence); + +void drm_regs_free(struct drm_reg_manager *manager) +{ + struct drm_reg *entry; + struct drm_reg *next_entry; + + drm_regs_fence(manager, NULL); + + list_for_each_entry_safe(entry, next_entry, &manager->free, head) { + list_del(&entry->head); + manager->reg_destroy(entry); + } + + list_for_each_entry_safe(entry, next_entry, &manager->lru, head) { + + (void)drm_fence_object_wait(entry->fence, 1, 1, + entry->fence_type); + list_del(&entry->head); + drm_fence_usage_deref_unlocked(&entry->fence); + manager->reg_destroy(entry); + } +} + +EXPORT_SYMBOL(drm_regs_free); + +void drm_regs_add(struct drm_reg_manager *manager, struct drm_reg *reg) +{ + reg->fence = NULL; + list_add_tail(®->head, &manager->free); +} + +EXPORT_SYMBOL(drm_regs_add); + +void drm_regs_init(struct drm_reg_manager *manager, + int (*reg_reusable) (const struct drm_reg *, const void *), + void (*reg_destroy) (struct drm_reg *)) +{ + INIT_LIST_HEAD(&manager->free); + INIT_LIST_HEAD(&manager->lru); + INIT_LIST_HEAD(&manager->unfenced); + manager->reg_reusable = reg_reusable; + manager->reg_destroy = reg_destroy; +} + +EXPORT_SYMBOL(drm_regs_init); commit 9280076b6710e8fcc9594b7f8db87176d3e92097 Author: Dave Airlie <ai...@li...> Date: Tue Nov 6 18:13:46 2007 +1100 i915: disable TTM on 8xx chips for now until flushing is solved diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 4d77dfc..541b4cc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1402,7 +1402,8 @@ int i915_driver_device_is_agp(struct drm_device * dev) int i915_driver_firstopen(struct drm_device *dev) { #ifdef I915_HAVE_BUFFER - drm_bo_driver_init(dev); + if (!IS_I9XX(dev)) + drm_bo_driver_init(dev); #endif return 0; } commit 349eebd567246e3c2d47734772e882ae50723cb9 Author: Dave Airlie <ai...@li...> Date: Tue Nov 6 18:00:10 2007 +1100 i915: compat code doesn't work in i8xx hw. diff --git a/linux-core/i915_compat.c b/linux-core/i915_compat.c index 3a437a1..b09cc9f 100644 --- a/linux-core/i915_compat.c +++ b/linux-core/i915_compat.c @@ -2,6 +2,9 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +#include "i915_drm.h" +#include "i915_drv.h" + #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 #define PCI_DEVICE_ID_INTEL_82965G_1_HB 0x2980 #define PCI_DEVICE_ID_INTEL_82965Q_HB 0x2990 @@ -13,17 +16,6 @@ #define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0 #define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 -#define IS_I965 (agp_dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) - -#define IS_G33 (agp_dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ - agp_dev->device == PCI_DEVICE_ID_INTEL_Q33_HB) - #define I915_IFPADDR 0x60 #define I965_IFPADDR 0x70 @@ -109,11 +101,15 @@ void intel_init_chipset_flush_compat(struct drm_device *dev) { struct pci_dev *agp_dev = dev->agp->agp_info.device; + /* not flush on i8xx */ + if (!IS_I9XX(dev)) + return; + intel_private.ifp_resource.name = "GMCH IFPBAR"; intel_private.ifp_resource.flags = IORESOURCE_MEM; /* Setup chipset flush for 915 */ - if (IS_I965 || IS_G33) { + if (IS_I965G(dev) || IS_G33(dev)) { intel_i965_g33_setup_chipset_flush(agp_dev); } else { intel_i915_setup_chipset_flush(agp_dev); @@ -128,6 +124,10 @@ void intel_init_chipset_flush_compat(struct drm_device *dev) void intel_fini_chipset_flush_compat(struct drm_device *dev) { + /* not flush on i8xx */ + if (!IS_I9XX(dev)) + return; + iounmap(intel_private.flush_page); release_resource(&intel_private.ifp_resource); } commit 81b7f9b71c45fc621e0b5770062aedf5ae5e57ee Author: Zhenyu Wang <zhe...@in...> Date: Tue Nov 6 17:59:14 2007 +1100 [PATCH] i915: fix missing G33 detect in IS_I9XX G33 detect seems missing with Jesse's suspend/resume patch. diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 91d4ac0..c66b065 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -1173,7 +1173,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); (dev)->pci_device == 0x29D2) #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ - IS_I945GM(dev) || IS_I965G(dev)) + IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ IS_I945GM(dev) || IS_I965GM(dev)) commit b437c8ca0fe62a43661a31a3010284926d20f209 Author: Dave Airlie <ai...@li...> Date: Tue Nov 6 12:12:10 2007 +1000 drm/agp: kernel style fixes diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 08ea7c4..438899e 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -498,14 +498,15 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle) #define AGP_REQUIRED_MAJOR 0 #define AGP_REQUIRED_MINOR 102 -static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend) { +static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend) +{ return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); } -static int drm_agp_populate(struct drm_ttm_backend *backend, unsigned long num_pages, - struct page **pages) { - +static int drm_agp_populate(struct drm_ttm_backend *backend, + unsigned long num_pages, struct page **pages) +{ struct drm_agp_ttm_backend *agp_be = container_of(backend, struct drm_agp_ttm_backend, backend); struct page **cur_page, **last_page = pages + num_pages; @@ -521,15 +522,14 @@ static int drm_agp_populate(struct drm_ttm_backend *backend, unsigned long num_p mem = drm_agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY); #endif if (!mem) { - drm_free_memctl(num_pages *sizeof(void *)); + drm_free_memctl(num_pages * sizeof(void *)); return -1; } DRM_DEBUG("Current page count is %ld\n", (long) mem->page_count); mem->page_count = 0; - for (cur_page = pages; cur_page < last_page; ++cur_page) { + for (cur_page = pages; cur_page < last_page; ++cur_page) mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(*cur_page)); - } agp_be->mem = mem; return 0; } @@ -551,17 +551,17 @@ static int drm_agp_bind_ttm(struct drm_ttm_backend *backend, mem->type = AGP_USER_CACHED_MEMORY; ret = drm_agp_bind_memory(mem, bo_mem->mm_node->start); - if (ret) { + if (ret) DRM_ERROR("AGP Bind memory failed\n"); - } + DRM_FLAG_MASKED(backend->flags, (bo_mem->flags & DRM_BO_FLAG_CACHED) ? DRM_BE_FLAG_BOUND_CACHED : 0, DRM_BE_FLAG_BOUND_CACHED); return ret; } -static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend) { - +static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend) +{ struct drm_agp_ttm_backend *agp_be = container_of(backend, struct drm_agp_ttm_backend, backend); @@ -572,8 +572,8 @@ static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend) { return 0; } -static void drm_agp_clear_ttm(struct drm_ttm_backend *backend) { - +static void drm_agp_clear_ttm(struct drm_ttm_backend *backend) +{ struct drm_agp_ttm_backend *agp_be = container_of(backend, struct drm_agp_ttm_backend, backend); DRM_AGP_MEM *mem = agp_be->mem; @@ -583,29 +583,27 @@ static void drm_agp_clear_ttm(struct drm_ttm_backend *backend) { unsigned long num_pages = mem->page_count; backend->func->unbind(backend); agp_free_memory(mem); - drm_free_memctl(num_pages *sizeof(void *)); + drm_free_memctl(num_pages * sizeof(void *)); } agp_be->mem = NULL; } -static void drm_agp_destroy_ttm(struct drm_ttm_backend *backend) { - +static void drm_agp_destroy_ttm(struct drm_ttm_backend *backend) +{ struct drm_agp_ttm_backend *agp_be; if (backend) { DRM_DEBUG("drm_agp_destroy_ttm\n"); agp_be = container_of(backend, struct drm_agp_ttm_backend, backend); if (agp_be) { - if (agp_be->mem) { + if (agp_be->mem) backend->func->clear(backend); - } drm_ctl_free(agp_be, sizeof(*agp_be), DRM_MEM_TTM); } } } -static struct drm_ttm_backend_func agp_ttm_backend = -{ +static struct drm_ttm_backend_func agp_ttm_backend = { .needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust, .populate = drm_agp_populate, .clear = drm_agp_clear_ttm, @@ -647,7 +645,6 @@ struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev) agp_be->bridge = dev->agp->bridge; agp_be->populated = FALSE; agp_be->backend.func = &agp_ttm_backend; - // agp_be->backend.mem_type = DRM_BO_MEM_TT; agp_be->backend.dev = dev; return &agp_be->backend; commit 9493ce6ca39b65b9f955943a043c0741a5c59f7c Author: Dave Airlie <ai...@li...> Date: Tue Nov 6 11:32:58 2007 +1000 i915: cleanup most of the whitespace diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 1f88a51..fb063ee 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -33,14 +33,14 @@ #include "i915_drm.h" #include "i915_drv.h" -struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device * dev) +struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev) { return drm_agp_init_ttm(dev); } int i915_fence_types(struct drm_buffer_object *bo, - uint32_t * fclass, - uint32_t * type) + uint32_t *fclass, + uint32_t *type) { if (bo->mem.mask & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) *type = 3; @@ -49,7 +49,7 @@ int i915_fence_types(struct drm_buffer_object *bo, return 0; } -int i915_invalidate_caches(struct drm_device * dev, uint64_t flags) +int i915_invalidate_caches(struct drm_device *dev, uint64_t flags) { /* * FIXME: Only emit once per batchbuffer submission. @@ -65,8 +65,8 @@ int i915_invalidate_caches(struct drm_device * dev, uint64_t flags) return i915_emit_mi_flush(dev, flush_cmd); } -int i915_init_mem_type(struct drm_device * dev, uint32_t type, - struct drm_mem_type_manager * man) +int i915_init_mem_type(struct drm_device *dev, uint32_t type, + struct drm_mem_type_manager *man) { switch (type) { case DRM_BO_MEM_LOCAL: @@ -226,25 +226,24 @@ out_cleanup: #endif /* - * Disable i915_move_flip for now, since we can't guarantee that the hardware lock - * is held here. To re-enable we need to make sure either + * Disable i915_move_flip for now, since we can't guarantee that the hardware + * lock is held here. To re-enable we need to make sure either * a) The X server is using DRM to submit commands to the ring, or - * b) DRM can use the HP ring for these blits. This means i915 needs to implement - * a new ring submission mechanism and fence class. + * b) DRM can use the HP ring for these blits. This means i915 needs to + * implement a new ring submission mechanism and fence class. */ - -int i915_move(struct drm_buffer_object * bo, - int evict, int no_wait, struct drm_bo_mem_reg * new_mem) +int i915_move(struct drm_buffer_object *bo, + int evict, int no_wait, struct drm_bo_mem_reg *new_mem) { struct drm_bo_mem_reg *old_mem = &bo->mem; if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { - if (0 /*i915_move_flip(bo, evict, no_wait, new_mem)*/) + if (0) /*i915_move_flip(bo, evict, no_wait, new_mem)*/ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else { - if (0 /*i915_move_blit(bo, evict, no_wait, new_mem)*/) + if (0) /*i915_move_blit(bo, evict, no_wait, new_mem)*/ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } return 0; @@ -259,7 +258,7 @@ static inline void clflush(volatile void *__p) static inline void drm_cache_flush_addr(void *virt) { - int i; + int i; for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) clflush(virt+i); diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c index f2c2982..e3c76df 100644 --- a/linux-core/i915_fence.c +++ b/linux-core/i915_fence.c @@ -38,7 +38,7 @@ * Implements an intel sync flush operation. */ -static void i915_perform_flush(struct drm_device * dev) +static void i915_perform_flush(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; struct drm_fence_manager *fm = &dev->fm; @@ -63,7 +63,7 @@ static void i915_perform_flush(struct drm_device * dev) diff = (sequence - fc->last_exe_flush) & BREADCRUMB_MASK; if (diff < driver->wrap_diff && diff != 0) { - drm_fence_handler(dev, 0, sequence, + drm_fence_handler(dev, 0, sequence, DRM_FENCE_TYPE_EXE, 0); } @@ -110,7 +110,7 @@ static void i915_perform_flush(struct drm_device * dev) } -void i915_poke_flush(struct drm_device * dev, uint32_t class) +void i915_poke_flush(struct drm_device *dev, uint32_t class) { struct drm_fence_manager *fm = &dev->fm; unsigned long flags; @@ -120,8 +120,9 @@ void i915_poke_flush(struct drm_device * dev, uint32_t class) write_unlock_irqrestore(&fm->lock, flags); } -int i915_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t flags, - uint32_t * sequence, uint32_t * native_type) +int i915_fence_emit_sequence(struct drm_device *dev, uint32_t class, + 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) @@ -136,7 +137,7 @@ int i915_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t f return 0; } -void i915_fence_handler(struct drm_device * dev) +void i915_fence_handler(struct drm_device *dev) { struct drm_fence_manager *fm = &dev->fm; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 9ee79fa..91d4ac0 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -267,7 +267,7 @@ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int i915_emit_irq(struct drm_device * dev); +extern int i915_emit_irq(struct drm_device *dev); extern void i915_user_irq_on(drm_i915_private_t *dev_priv); extern void i915_user_irq_off(drm_i915_private_t *dev_priv); extern int i915_vblank_swap(struct drm_device *dev, void *data, @@ -303,7 +303,7 @@ extern int i915_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t f /* i915_buffer.c */ extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev); extern int i915_fence_types(struct drm_buffer_object *bo, uint32_t *fclass, - uint32_t *type); + uint32_t *type); extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); extern int i915_init_mem_type(struct drm_device *dev, uint32_t type, struct drm_mem_type_manager *man); diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 43e73e0..2c699ec 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -365,9 +365,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } -int i915_emit_irq(struct drm_device * dev) +int i915_emit_irq(struct drm_device *dev) { - drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -383,8 +382,6 @@ int i915_emit_irq(struct drm_device * dev) ADVANCE_LP_RING(); return dev_priv->counter; - - } void i915_user_irq_on(drm_i915_private_t *dev_priv) @@ -471,7 +468,8 @@ int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) /* Needs the lock as it touches the ring. */ -int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) +int i915_irq_emit(struct drm_device *dev, void *data, + struct drm_file *file_priv) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_irq_emit_t *emit = data; @@ -747,13 +745,14 @@ void i915_driver_irq_postinstall(struct drm_device * dev) * Initialize the hardware status page IRQ location. */ - I915_WRITE(I915REG_INSTPM, ( 1 << 5) | ( 1 << 21)); + I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); } void i915_driver_irq_uninstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; + if (!dev_priv) return; |