From e9fa8fe7342fad710bee4f65bc23ec06d3020f05 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 28 Nov 2007 22:46:06 +1000 Subject: i965: oops force mi batchbuffer start --- shared-core/i915_dma.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9aff752c..06dd3629 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -165,6 +165,9 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) * private backbuffer/depthbuffer usage. */ dev_priv->use_mi_batchbuffer_start = 0; + if (IS_I965G(dev)) + dev_priv->use_mi_batchbuffer_start = 1; + /* Allow hardware batchbuffers unless told otherwise. */ -- cgit v1.2.3 From dc338921f94daad17055105a38214483d5ac33e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 Nov 2007 09:37:51 +1000 Subject: drm: more cleanups --- linux-core/drm_agpsupport.c | 4 ++-- linux-core/drm_ioctl.c | 16 ++++++++++------ linux-core/i915_buffer.c | 2 +- shared-core/i915_dma.c | 19 +++++++++---------- shared-core/i915_drm.h | 3 ++- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index cb665009..b5dcbb35 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -522,7 +522,7 @@ static int drm_agp_populate(struct drm_ttm_backend *backend, 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; } @@ -652,7 +652,7 @@ struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev) EXPORT_SYMBOL(drm_agp_init_ttm); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) -void drm_agp_flush_chipset(struct drm_device *dev) +void drm_agp_chipset_flush(struct drm_device *dev) { agp_flush_chipset(dev->agp->bridge); } diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index 395f7b4e..3df163db 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -98,12 +98,14 @@ int drm_setunique(struct drm_device *dev, void *data, dev->unique[dev->unique_len] = '\0'; - dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2, - DRM_MEM_DRIVER); + dev->devname = + drm_alloc(strlen(dev->driver->pci_driver.name) + + strlen(dev->unique) + 2, DRM_MEM_DRIVER); if (!dev->devname) return -ENOMEM; - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); + sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, + dev->unique); /* Return error if the busid submitted doesn't match the device's actual * busid. @@ -142,12 +144,14 @@ static int drm_set_busid(struct drm_device * dev) if (len > dev->unique_len) DRM_ERROR("buffer overflow"); - dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2, - DRM_MEM_DRIVER); + dev->devname = + drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + + 2, DRM_MEM_DRIVER); if (dev->devname == NULL) return -ENOMEM; - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); + sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, + dev->unique); return 0; } diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index fb063ee7..b000a725 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -277,7 +277,7 @@ void i915_flush_ttm(struct drm_ttm *ttm) return; DRM_MEMORYBARRIER(); - for (i = ttm->num_pages-1; i >= 0; i--) + for (i = ttm->num_pages - 1; i >= 0; i--) drm_cache_flush_page(drm_ttm_get_page(ttm, i)); DRM_MEMORYBARRIER(); } diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 06dd3629..c7d563fe 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -165,9 +165,8 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) * private backbuffer/depthbuffer usage. */ dev_priv->use_mi_batchbuffer_start = 0; - if (IS_I965G(dev)) + if (IS_I965G(dev)) /* 965 doesn't support older method */ dev_priv->use_mi_batchbuffer_start = 1; - /* Allow hardware batchbuffers unless told otherwise. */ @@ -339,7 +338,7 @@ static int validate_cmd(int cmd) return ret; } -static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, +static int i915_emit_cmds(struct drm_device *dev, int __user *buffer, int dwords) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -495,7 +494,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, return ret; } - i915_emit_breadcrumb( dev ); + i915_emit_breadcrumb(dev); #ifdef I915_HAVE_FENCE drm_fence_flush_old(dev, 0, dev_priv->counter); #endif @@ -549,7 +548,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, } } - i915_emit_breadcrumb( dev ); + i915_emit_breadcrumb(dev); #ifdef I915_HAVE_FENCE drm_fence_flush_old(dev, 0, dev_priv->counter); #endif @@ -630,7 +629,7 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) #endif } -static int i915_quiescent(struct drm_device * dev) +static int i915_quiescent(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -1035,10 +1034,10 @@ static int i915_execbuffer(struct drm_device *dev, void *data, buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); if (!buffers) { - drm_bo_read_unlock(&dev->bm.bm_lock); + drm_bo_read_unlock(&dev->bm.bm_lock); mutex_unlock(&dev_priv->cmdbuf_mutex); return -ENOMEM; - } + } /* validate buffer list + fixup relocations */ ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list, @@ -1247,9 +1246,9 @@ static int i915_mmio(struct drm_device *dev, void *data, case I915_MMIO_WRITE: if (!(e->flag & I915_MMIO_MAY_WRITE)) return -EINVAL; - if(DRM_COPY_FROM_USER(buf, mmio->data, e->size)) { + if (DRM_COPY_FROM_USER(buf, mmio->data, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return -EFAULT; + return -EFAULT; } for (i = 0; i < e->size / 4; i++) I915_WRITE(e->offset + i * 4, buf[i]); diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 8a3be4e0..cfa3f93a 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -178,6 +178,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) +#define DRM_IOCTL_I915_MMIO DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_MMIO, drm_i915_mmio) #define DRM_IOCTL_I915_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_EXECBUFFER, struct drm_i915_execbuffer) /* Asynchronous page flipping: @@ -274,7 +275,7 @@ typedef struct drm_i915_mem_init_heap { * rotate): */ typedef struct drm_i915_mem_destroy_heap { - int region; + int region; } drm_i915_mem_destroy_heap_t; /* Allow X server to configure which pipes to monitor for vblank signals -- cgit v1.2.3 From 9be085cbf44ac8bd3bc6fe3e9b55df6fec7ac389 Mon Sep 17 00:00:00 2001 From: "Robert C. Noland III" Date: Wed, 28 Nov 2007 00:33:42 -0500 Subject: Fix up drm_ati_pcigart_info --- bsd-core/ati_pcigart.c | 4 ++-- bsd-core/drmP.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c index db19a75d..bb0c46e2 100644 --- a/bsd-core/ati_pcigart.c +++ b/bsd-core/ati_pcigart.c @@ -35,7 +35,7 @@ #define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */ -int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) +int drm_ati_pcigart_init(drm_device_t *dev, struct drm_ati_pcigart_info *gart_info) { unsigned long pages; u32 *pci_gart = NULL, page_base; @@ -94,7 +94,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) return 1; } -int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) +int drm_ati_pcigart_cleanup(drm_device_t *dev, struct drm_ati_pcigart_info *gart_info) { if (dev->sg == NULL) { DRM_ERROR( "no scatter/gather memory!\n" ); diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 1dd27282..d90660a3 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -614,14 +614,14 @@ typedef struct drm_vbl_sig { #define DRM_ATI_GART_PCIE 2 #define DRM_ATI_GART_IGP 3 -typedef struct ati_pcigart_info { +struct drm_ati_pcigart_info { int gart_table_location; int gart_reg_if; void *addr; dma_addr_t bus_addr; drm_local_map_t mapping; int table_size; -} drm_ati_pcigart_info; +}; struct drm_driver_info { int (*load)(struct drm_device *, unsigned long flags); @@ -925,9 +925,9 @@ extern int drm_sysctl_cleanup(drm_device_t *dev); /* ATI PCIGART support (ati_pcigart.c) */ int drm_ati_pcigart_init(drm_device_t *dev, - drm_ati_pcigart_info *gart_info); + struct drm_ati_pcigart_info *gart_info); int drm_ati_pcigart_cleanup(drm_device_t *dev, - drm_ati_pcigart_info *gart_info); + struct drm_ati_pcigart_info *gart_info); /* Locking IOCTL support (drm_drv.c) */ int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv); -- cgit v1.2.3 From 4602b6687ebb0dcf5047f2c3d88dccd751558c81 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 Nov 2007 09:46:02 +1000 Subject: drm: oops not a cleanup.. --- linux-core/drm_agpsupport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index b5dcbb35..e8bfaea4 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -522,7 +522,7 @@ static int drm_agp_populate(struct drm_ttm_backend *backend, 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; } -- cgit v1.2.3 From 32c9a109b10c087f63964b4b055603feee522cc0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 Nov 2007 09:47:24 +1000 Subject: drm: enable udev node creation --- linux-core/drm_sysfs.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index caec120a..3aaac11b 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -162,12 +162,7 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) dev->dev.parent = &dev->pdev->dev; dev->dev.class = drm_class; dev->dev.release = drm_sysfs_device_release; - /* - * This will actually add the major:minor file so that udev - * will create the device node. We don't want to do that just - * yet... - */ - /* dev->dev.devt = head->device; */ + dev->dev.devt = head->device; snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); err = device_register(&dev->dev); -- cgit v1.2.3 From 309b2c4c05d02a7e7311a9491b74044f6c7f06a4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 29 Nov 2007 09:55:38 +1000 Subject: Beside the emitted warning, the added cast (u64 -> unsigned) strips out part of address on 64 bit. Cast to unsigned long instead. Signed-off-by: Jiri Slaby --- shared-core/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index c7d563fe..f14b9b07 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -918,7 +918,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buffers[buf_count] = NULL; - if (copy_from_user(&arg, (void __user *)(unsigned)data, sizeof(arg))) { + if (copy_from_user(&arg, (void __user *)(unsigned long)data, sizeof(arg))) { ret = -EFAULT; goto out_err; } @@ -969,7 +969,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, arg.handled = 1; arg.d.rep = rep; - if (copy_to_user((void __user *)(unsigned)data, &arg, sizeof(arg))) + if (copy_to_user((void __user *)(unsigned long)data, &arg, sizeof(arg))) return -EFAULT; data = next; -- cgit v1.2.3 From 887b920a7fd2cfa70b41425d26e4d3707d4075b9 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 30 Nov 2007 22:50:34 +0100 Subject: nouveau: Properly identify NV40 and NV44 generation. --- shared-core/nouveau_state.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 7c9503e8..16c86494 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -454,6 +454,9 @@ int nouveau_firstopen(struct drm_device *dev) return 0; } +#define NV40_CHIPSET_MASK 0x00000baf +#define NV44_CHIPSET_MASK 0x00005450 + int nouveau_load(struct drm_device *dev, unsigned long flags) { struct drm_nouveau_private *dev_priv; @@ -497,10 +500,16 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) if (architecture >= 0x50) { dev_priv->card_type = NV_50; - } else if (architecture >= 0x44) { - dev_priv->card_type = NV_44; } else if (architecture >= 0x40) { - dev_priv->card_type = NV_40; + uint8_t subarch = architecture & 0xf; + /* Selection criteria borrowed from NV40EXA */ + if (NV40_CHIPSET_MASK & (1 << subarch)) { + dev_priv->card_type = NV_40; + } else if (NV44_CHIPSET_MASK & (1 << subarch)) { + dev_priv->card_type = NV_44; + } else { + dev_priv->card_type = NV_UNKNOWN; + } } else if (architecture >= 0x30) { dev_priv->card_type = NV_30; } else if (architecture >= 0x20) { -- cgit v1.2.3 From 83e62be6f449ad480eb590ee9d4131974c9920e2 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 1 Dec 2007 02:32:23 -0500 Subject: bsd: Move counter initialization to load time. --- bsd-core/drm_drv.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index d6868b9c..2e976107 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -403,17 +403,6 @@ static int drm_firstopen(drm_device_t *dev) return i; } - dev->counters = 6; - dev->types[0] = _DRM_STAT_LOCK; - dev->types[1] = _DRM_STAT_OPENS; - dev->types[2] = _DRM_STAT_CLOSES; - dev->types[3] = _DRM_STAT_IOCTLS; - dev->types[4] = _DRM_STAT_LOCKS; - dev->types[5] = _DRM_STAT_UNLOCKS; - - for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ ) - atomic_set( &dev->counts[i], 0 ); - for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { dev->magiclist[i].head = NULL; dev->magiclist[i].tail = NULL; @@ -511,7 +500,7 @@ static int drm_lastclose(drm_device_t *dev) static int drm_load(drm_device_t *dev) { - int retcode; + int i, retcode; DRM_DEBUG( "\n" ); @@ -536,6 +525,17 @@ static int drm_load(drm_device_t *dev) #endif TAILQ_INIT(&dev->files); + dev->counters = 6; + dev->types[0] = _DRM_STAT_LOCK; + dev->types[1] = _DRM_STAT_OPENS; + dev->types[2] = _DRM_STAT_CLOSES; + dev->types[3] = _DRM_STAT_IOCTLS; + dev->types[4] = _DRM_STAT_LOCKS; + dev->types[5] = _DRM_STAT_UNLOCKS; + + for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ ) + atomic_set( &dev->counts[i], 0 ); + if (dev->driver.load != NULL) { DRM_LOCK(); /* Shared code returns -errno. */ -- cgit v1.2.3 From d6295cc9ffe9f36f78131f8049baf24e77d35e15 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 1 Dec 2007 02:40:13 -0500 Subject: drm: Add _DRM_DRIVER map flag. This flag indicates that the driver is responsible for the map. --- bsd-core/drm_drv.c | 4 ++-- linux-core/drm_drv.c | 6 ++++-- shared-core/drm.h | 3 ++- shared-core/i915_dma.c | 5 +++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index 2e976107..96dc4d35 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -484,10 +484,10 @@ static int drm_lastclose(drm_device_t *dev) } TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) { - drm_rmmap(dev, map); + if (!(map->flags & _DRM_DRIVER)) + drm_rmmap(dev, map); } - drm_dma_takedown(dev); if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 9d03434f..869748f8 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -246,8 +246,10 @@ int drm_lastclose(struct drm_device * dev) } list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { - drm_rmmap_locked(dev, r_list->map); - r_list = NULL; + if (!(r_list->map->flags & _DRM_DRIVER)) { + drm_rmmap_locked(dev, r_list->map); + r_list = NULL; + } } if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { diff --git a/shared-core/drm.h b/shared-core/drm.h index 636c1217..ec07b895 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -249,7 +249,8 @@ enum drm_map_flags { _DRM_KERNEL = 0x08, /**< kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40 /**< Removable mapping */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80 /**< Managed by driver */ }; struct drm_ctx_priv_map { diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f14b9b07..67424408 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1320,14 +1320,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) base = drm_get_resource_start(dev, mmio_bar); size = drm_get_resource_len(dev, mmio_bar); - ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL, - &dev_priv->mmio_map); + ret = drm_addmap(dev, base, size, _DRM_REGISTERS, + _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map); #ifdef __linux__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) intel_init_chipset_flush_compat(dev); #endif #endif + return ret; } -- cgit v1.2.3 From 453a295c829dd9e07175f4b2e8fe7e179e5a4d79 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 24 Nov 2007 01:56:05 -0500 Subject: DRM_DEBUG already prints the function name. --- shared-core/i915_dma.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 67424408..d86f86cc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -204,7 +204,7 @@ static int i915_dma_resume(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - DRM_DEBUG("%s\n", __FUNCTION__); + DRM_DEBUG("\n"); if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); @@ -612,8 +612,7 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) drm_i915_private_t *dev_priv = dev->dev_private; int i; - DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n", - __FUNCTION__, + DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n", planes, dev_priv->sarea_priv->pf_current_page); i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH); @@ -1097,7 +1096,7 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; - DRM_DEBUG("%s\n", __FUNCTION__); + DRM_DEBUG("\n"); for (i = 0, planes = 0; i < 2; i++) if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { @@ -1118,7 +1117,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f { drm_i915_flip_t *param = data; - DRM_DEBUG("%s\n", __FUNCTION__); + DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); -- cgit v1.2.3 From b2f8368b571efe610750640c5f10f4c4e0bf7133 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 25 Nov 2007 12:50:07 -0500 Subject: Clarify order of operations --- shared-core/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index d86f86cc..31df743f 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1102,7 +1102,7 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev) if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { dev_priv->sarea_priv->pf_current_page = (dev_priv->sarea_priv->pf_current_page & - ~(0x3 << (2 * i))) | (num_pages - 1) << (2 * i); + ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i)); planes |= 1 << i; } -- cgit v1.2.3 From 0c3e5261b63f6a642f4c62d287e56a52954c2b06 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 25 Nov 2007 12:54:31 -0500 Subject: mtx_sleep is preferred to msleep Calling semantics are the same and both were introduced in 5.0 --- bsd-core/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index 96dc4d35..8466ce33 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -772,7 +772,7 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) } /* Contention */ #if defined(__FreeBSD__) && __FreeBSD_version > 500000 - retcode = msleep((void *)&dev->lock.lock_queue, + retcode = mtx_sleep((void *)&dev->lock.lock_queue, &dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); #else retcode = tsleep((void *)&dev->lock.lock_queue, -- cgit v1.2.3 From e6ca3f5754d649b6290ea017f815aeb18d565718 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 1 Dec 2007 16:35:48 -0500 Subject: bsd: Fix typo in i915_drv.c --- bsd-core/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsd-core/i915_drv.c b/bsd-core/i915_drv.c index d42b2076..89a1eb70 100644 --- a/bsd-core/i915_drv.c +++ b/bsd-core/i915_drv.c @@ -46,7 +46,7 @@ static void i915_configure(drm_device_t *dev) dev->driver.load = i915_driver_load; dev->driver.preclose = i915_driver_preclose; dev->driver.lastclose = i915_driver_lastclose; - dev->driver.device_is_agp = i915_driver_device_is_agp, + dev->driver.device_is_agp = i915_driver_device_is_agp; dev->driver.vblank_wait = i915_driver_vblank_wait; dev->driver.irq_preinstall = i915_driver_irq_preinstall; dev->driver.irq_postinstall = i915_driver_irq_postinstall; -- cgit v1.2.3 From 787d500c15c964f2a715ea0c949177c1d38dc367 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 1 Dec 2007 17:09:49 -0500 Subject: bsd: Hook secondary vblank support. --- bsd-core/drmP.h | 1 + bsd-core/drm_irq.c | 10 ++++++++-- bsd-core/i915_drv.c | 1 + bsd-core/radeon_drv.c | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index d90660a3..243a984c 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -650,6 +650,7 @@ struct drm_driver_info { void (*irq_uninstall)(drm_device_t *dev); void (*irq_handler)(DRM_IRQ_ARGS); int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence); + int (*vblank_wait2)(drm_device_t *dev, unsigned int *sequence); drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */ diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c index 0772445a..a58307c5 100644 --- a/bsd-core/drm_irq.c +++ b/bsd-core/drm_irq.c @@ -244,8 +244,14 @@ int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv) } else { DRM_LOCK(); /* shared code returns -errno */ - ret = -dev->driver.vblank_wait(dev, - &vblwait->request.sequence); + if (flags & _DRM_VBLANK_SECONDARY) { + if (dev->driver.vblank_wait2) + ret = -dev->driver.vblank_wait2(dev, + &vblwait->request.sequence); + } else if (dev->driver.vblank_wait) + ret = -dev->driver.vblank_wait(dev, + &vblwait->request.sequence); + DRM_UNLOCK(); microtime(&now); diff --git a/bsd-core/i915_drv.c b/bsd-core/i915_drv.c index 89a1eb70..5150cf9f 100644 --- a/bsd-core/i915_drv.c +++ b/bsd-core/i915_drv.c @@ -48,6 +48,7 @@ static void i915_configure(drm_device_t *dev) dev->driver.lastclose = i915_driver_lastclose; dev->driver.device_is_agp = i915_driver_device_is_agp; dev->driver.vblank_wait = i915_driver_vblank_wait; + dev->driver.vblank_wait2 = i915_driver_vblank_wait2; dev->driver.irq_preinstall = i915_driver_irq_preinstall; dev->driver.irq_postinstall = i915_driver_irq_postinstall; dev->driver.irq_uninstall = i915_driver_irq_uninstall; diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c index f66bc795..114b98dd 100644 --- a/bsd-core/radeon_drv.c +++ b/bsd-core/radeon_drv.c @@ -53,6 +53,7 @@ static void radeon_configure(drm_device_t *dev) dev->driver.postclose = radeon_driver_postclose; dev->driver.lastclose = radeon_driver_lastclose; dev->driver.vblank_wait = radeon_driver_vblank_wait; + dev->driver.vblank_wait2 = radeon_driver_vblank_wait2; dev->driver.irq_preinstall = radeon_driver_irq_preinstall; dev->driver.irq_postinstall = radeon_driver_irq_postinstall; dev->driver.irq_uninstall = radeon_driver_irq_uninstall; -- cgit v1.2.3 From fbc307274f7cb29f986daae3d8e367d53172e3ba Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 2 Dec 2007 01:23:11 -0500 Subject: bsd: Now make secondary vblank work We needed to specifically check for driver support and test the correct vbl_received value. Also pulled over support for _DRM_VBLANK_NEXTONMISS from the linux code. --- bsd-core/drmP.h | 1 + bsd-core/drm_irq.c | 42 ++++++++++++++++++++++++++++++++++-------- bsd-core/i915_drv.c | 1 + bsd-core/radeon_drv.c | 1 + 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 243a984c..56605d1f 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -687,6 +687,7 @@ struct drm_driver_info { unsigned use_dma_queue :1; unsigned use_irq :1; unsigned use_vbl_irq :1; + unsigned use_vbl_irq2 :1; unsigned use_mtrr :1; }; diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c index a58307c5..6a852873 100644 --- a/bsd-core/drm_irq.c +++ b/bsd-core/drm_irq.c @@ -211,17 +211,43 @@ int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv) { drm_wait_vblank_t *vblwait = data; struct timeval now; - int ret, flags; + int ret = 0; + int flags, seq; if (!dev->irq_enabled) return EINVAL; - if (vblwait->request.type & _DRM_VBLANK_RELATIVE) { - vblwait->request.sequence += atomic_read(&dev->vbl_received); - vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; + if (vblwait->request.type & + ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { + DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", + vblwait->request.type, + (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)); + return EINVAL; } flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; + + if ((flags & _DRM_VBLANK_SECONDARY) && !dev->driver.use_vbl_irq2) + return EINVAL; + + seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? + &dev->vbl_received2 : &dev->vbl_received); + + switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { + case _DRM_VBLANK_RELATIVE: + vblwait->request.sequence += seq; + vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; + case _DRM_VBLANK_ABSOLUTE: + break; + default: + return EINVAL; + } + + if ((flags & _DRM_VBLANK_NEXTONMISS) && + (seq - vblwait->request.sequence) <= (1<<23)) { + vblwait->request.sequence = seq + 1; + } + if (flags & _DRM_VBLANK_SIGNAL) { #if 0 /* disabled */ drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t), M_DRM, @@ -247,10 +273,10 @@ int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv) if (flags & _DRM_VBLANK_SECONDARY) { if (dev->driver.vblank_wait2) ret = -dev->driver.vblank_wait2(dev, - &vblwait->request.sequence); - } else if (dev->driver.vblank_wait) - ret = -dev->driver.vblank_wait(dev, - &vblwait->request.sequence); + &vblwait->request.sequence); + } else if (dev->driver.vblank_wait) + ret = -dev->driver.vblank_wait(dev, + &vblwait->request.sequence); DRM_UNLOCK(); diff --git a/bsd-core/i915_drv.c b/bsd-core/i915_drv.c index 5150cf9f..e8897fbe 100644 --- a/bsd-core/i915_drv.c +++ b/bsd-core/i915_drv.c @@ -69,6 +69,7 @@ static void i915_configure(drm_device_t *dev) dev->driver.use_mtrr = 1; dev->driver.use_irq = 1; dev->driver.use_vbl_irq = 1; + dev->driver.use_vbl_irq2 = 1; } #ifdef __FreeBSD__ diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c index 114b98dd..93f875c5 100644 --- a/bsd-core/radeon_drv.c +++ b/bsd-core/radeon_drv.c @@ -77,6 +77,7 @@ static void radeon_configure(drm_device_t *dev) dev->driver.use_dma = 1; dev->driver.use_irq = 1; dev->driver.use_vbl_irq = 1; + dev->driver.use_vbl_irq2 = 1; } #ifdef __FreeBSD__ -- cgit v1.2.3 From 690dd04d1b9a4da92139793d3f5129a80f9c7353 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 2 Dec 2007 01:45:09 -0500 Subject: bsd: Replace other occurrences of msleep with mtx_sleep --- bsd-core/drmP.h | 2 +- bsd-core/drm_irq.c | 2 +- bsd-core/drm_lock.c | 2 +- shared-core/radeon_cp.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 56605d1f..99457bf8 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -388,7 +388,7 @@ for ( ret = 0 ; !ret && !(condition) ; ) { \ DRM_UNLOCK(); \ mtx_lock(&dev->irq_lock); \ if (!(condition)) \ - ret = -msleep(&(queue), &dev->irq_lock, \ + ret = -mtx_sleep(&(queue), &dev->irq_lock, \ PZERO | PCATCH, "drmwtq", (timeout)); \ mtx_unlock(&dev->irq_lock); \ DRM_LOCK(); \ diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c index 6a852873..40d0b71f 100644 --- a/bsd-core/drm_irq.c +++ b/bsd-core/drm_irq.c @@ -335,7 +335,7 @@ static void drm_locked_task(void *context, int pending __unused) /* Contention */ #if defined(__FreeBSD__) && __FreeBSD_version > 500000 - ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock, + ret = mtx_sleep((void *)&dev->lock.lock_queue, &dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); #else ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH, diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index fb86fc68..9731ff92 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -140,7 +140,7 @@ int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv) /* Contention */ #if defined(__FreeBSD__) && __FreeBSD_version > 500000 - ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock, + ret = mtx_sleep((void *)&dev->lock.lock_queue, &dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); #else ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH, diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 8f95a077..fc1fe07a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1952,7 +1952,7 @@ void radeon_do_release(struct drm_device * dev) schedule(); #else #if defined(__FreeBSD__) && __FreeBSD_version > 500000 - msleep(&ret, &dev->dev_lock, PZERO, "rdnrel", + mtx_sleep(&ret, &dev->dev_lock, PZERO, "rdnrel", 1); #else tsleep(&ret, PZERO, "rdnrel", 1); -- cgit v1.2.3 From 2f6e53342156ecb0e61a13816043445032c2b539 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 5 Dec 2007 04:54:58 +1000 Subject: patch from -mm kernel to use upper_32_bits --- linux-core/i915_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-core/i915_compat.c b/linux-core/i915_compat.c index e119a992..58fb8418 100644 --- a/linux-core/i915_compat.c +++ b/linux-core/i915_compat.c @@ -84,7 +84,8 @@ static void intel_i965_g33_setup_chipset_flush(struct pci_dev *pdev) intel_alloc_chipset_flush_resource(pdev); - pci_write_config_dword(pdev, I965_IFPADDR + 4, (i9xx_private.ifp_resource.start >> 32)); + pci_write_config_dword(pdev, I965_IFPADDR + 4, + upper_32_bits(i9xx_private.ifp_resource.start)); pci_write_config_dword(pdev, I965_IFPADDR, (i9xx_private.ifp_resource.start & 0xffffffff) | 0x1); } else { u64 l64; -- cgit v1.2.3 From e38749ebe5ece08ec63dfd37aca28108ad5cc7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 5 Dec 2007 14:43:22 -0500 Subject: Remove references to the sarea_priv perf_boxes field. This field isn't touched or read by any other code in the stack so it's time to retire these last few references. --- shared-core/i915_dma.c | 5 ----- shared-core/i915_irq.c | 2 -- 2 files changed, 7 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 31df743f..42114beb 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -51,8 +51,6 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) if (ring->space >= n) return 0; - dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - if (ring->head != last_head) i = 0; @@ -73,9 +71,6 @@ void i915_kernel_lost_context(struct drm_device * dev) ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->Size; - - if (ring->head == ring->tail) - dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; } static int i915_dma_cleanup(struct drm_device * dev) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 2c699ecd..e7f3b083 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -417,8 +417,6 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (READ_BREADCRUMB(dev_priv) >= irq_nr) return 0; - dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - i915_user_irq_on(dev_priv); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); -- cgit v1.2.3 From 46ecd12c07f921bb015f87cb07ddb02baa94b382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 5 Dec 2007 00:10:39 +0000 Subject: mach64: use utf-8 --- shared-core/mach64_dma.c | 2 +- shared-core/mach64_drv.h | 2 +- shared-core/mach64_state.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index 13fa0446..dd3547f8 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -6,7 +6,7 @@ * \author Gareth Hughes * \author Frank C. Earl * \author Leif Delgass - * \author Jose Fonseca + * \author José Fonseca */ /* diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h index 79c2c61d..347c9426 100644 --- a/shared-core/mach64_drv.h +++ b/shared-core/mach64_drv.h @@ -29,7 +29,7 @@ * Gareth Hughes * Frank C. Earl * Leif Delgass - * Jos�Fonseca + * José Fonseca */ #ifndef __MACH64_DRV_H__ diff --git a/shared-core/mach64_state.c b/shared-core/mach64_state.c index 89b6c6ce..6fcae948 100644 --- a/shared-core/mach64_state.c +++ b/shared-core/mach64_state.c @@ -27,7 +27,7 @@ * Authors: * Gareth Hughes * Leif Delgass - * Jos�Fonseca + * José Fonseca */ #include "drmP.h" -- cgit v1.2.3 From a64a4373e85a321a359e147b2c7220d501dff06a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 5 Dec 2007 22:53:02 +0000 Subject: mach64: make buffer emission macros normal functions --- shared-core/mach64_dma.c | 227 +++++++++++++++++++++++++++++++++++++++++++++ shared-core/mach64_drv.h | 233 +++-------------------------------------------- 2 files changed, 239 insertions(+), 221 deletions(-) diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index dd3547f8..9aa3f768 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -558,6 +558,233 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv) /*@}*/ +/*******************************************************************/ +/** \name DMA descriptor ring macros */ +/*@{*/ + +static __inline__ void mach64_set_dma_eol(volatile u32 * addr) +{ +#if defined(__i386__) + int nr = 31; + + /* Taken from include/asm-i386/bitops.h linux header */ + __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr) + :"Ir"(nr)); +#elif defined(__powerpc__) + u32 old; + u32 mask = cpu_to_le32(MACH64_DMA_EOL); + + /* Taken from the include/asm-ppc/bitops.h linux header */ + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + or %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ + bne- 1b":"=&r"(old), "=m"(*addr) + :"r"(mask), "r"(addr), "m"(*addr) + :"cc"); +#elif defined(__alpha__) + u32 temp; + u32 mask = MACH64_DMA_EOL; + + /* Taken from the include/asm-alpha/bitops.h linux header */ + __asm__ __volatile__("1: ldl_l %0,%3\n" + " bis %0,%2,%0\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous":"=&r"(temp), "=m"(*addr) + :"Ir"(mask), "m"(*addr)); +#else + u32 mask = cpu_to_le32(MACH64_DMA_EOL); + + *addr |= mask; +#endif +} + +static __inline__ void mach64_clear_dma_eol(volatile u32 * addr) +{ +#if defined(__i386__) + int nr = 31; + + /* Taken from include/asm-i386/bitops.h linux header */ + __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr) + :"Ir"(nr)); +#elif defined(__powerpc__) + u32 old; + u32 mask = cpu_to_le32(MACH64_DMA_EOL); + + /* Taken from the include/asm-ppc/bitops.h linux header */ + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + andc %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ + bne- 1b":"=&r"(old), "=m"(*addr) + :"r"(mask), "r"(addr), "m"(*addr) + :"cc"); +#elif defined(__alpha__) + u32 temp; + u32 mask = ~MACH64_DMA_EOL; + + /* Taken from the include/asm-alpha/bitops.h linux header */ + __asm__ __volatile__("1: ldl_l %0,%3\n" + " and %0,%2,%0\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous":"=&r"(temp), "=m"(*addr) + :"Ir"(mask), "m"(*addr)); +#else + u32 mask = cpu_to_le32(~MACH64_DMA_EOL); + + *addr &= mask; +#endif +} + +#define RING_LOCALS \ + int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring + +#define RING_WRITE_OFS _ring_write + +#define BEGIN_RING( n ) \ +do { \ + if ( MACH64_VERBOSE ) { \ + DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ + (n), __FUNCTION__ ); \ + } \ + if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + int ret; \ + if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \ + DRM_ERROR( "wait_ring failed, resetting engine\n"); \ + mach64_dump_engine_info( dev_priv ); \ + mach64_do_engine_reset( dev_priv ); \ + return ret; \ + } \ + } \ + dev_priv->ring.space -= (n) * sizeof(u32); \ + _ring = (u32 *) dev_priv->ring.start; \ + _ring_tail = _ring_write = dev_priv->ring.tail; \ + _ring_mask = dev_priv->ring.tail_mask; \ +} while (0) + +#define OUT_RING( x ) \ +do { \ + if ( MACH64_VERBOSE ) { \ + DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ + (unsigned int)(x), _ring_write ); \ + } \ + _ring[_ring_write++] = cpu_to_le32( x ); \ + _ring_write &= _ring_mask; \ +} while (0) + +#define ADVANCE_RING() \ +do { \ + if ( MACH64_VERBOSE ) { \ + DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ + _ring_write, _ring_tail ); \ + } \ + DRM_MEMORYBARRIER(); \ + mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \ + DRM_MEMORYBARRIER(); \ + dev_priv->ring.tail = _ring_write; \ + mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ +} while (0) + + +int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, + drm_mach64_freelist_t *entry) +{ + int bytes, pages, remainder; + u32 address, page; + int i; + struct drm_buf *buf = entry->buf; + RING_LOCALS; + + bytes = buf->used; + address = GETBUFADDR( buf ); + pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; + + BEGIN_RING( pages * 4 ); + + for ( i = 0 ; i < pages-1 ; i++ ) { + page = address + i * MACH64_DMA_CHUNKSIZE; + OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); + OUT_RING( page ); + OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); + OUT_RING( 0 ); + } + + /* generate the final descriptor for any remaining commands in this buffer */ + page = address + i * MACH64_DMA_CHUNKSIZE; + remainder = bytes - i * MACH64_DMA_CHUNKSIZE; + + /* Save dword offset of last descriptor for this buffer. + * This is needed to check for completion of the buffer in freelist_get + */ + entry->ring_ofs = RING_WRITE_OFS; + + OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); + OUT_RING( page ); + OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); + OUT_RING( 0 ); + + ADVANCE_RING(); + + return 0; +} + +int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv, + drm_mach64_freelist_t *entry) +{ + int bytes, pages, remainder; + u32 address, page; + int i; + struct drm_buf *buf = entry->buf; + RING_LOCALS; + + bytes = buf->used - MACH64_HOSTDATA_BLIT_OFFSET; + pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; + address = GETBUFADDR( buf ); + + BEGIN_RING( 4 + pages * 4 ); + + OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); + OUT_RING( address ); + OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET ); + OUT_RING( 0 ); + address += MACH64_HOSTDATA_BLIT_OFFSET; + + for ( i = 0 ; i < pages-1 ; i++ ) { + page = address + i * MACH64_DMA_CHUNKSIZE; + OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); + OUT_RING( page ); + OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); + OUT_RING( 0 ); + } + + /* generate the final descriptor for any remaining commands in this buffer */ + page = address + i * MACH64_DMA_CHUNKSIZE; + remainder = bytes - i * MACH64_DMA_CHUNKSIZE; + + /* Save dword offset of last descriptor for this buffer. + * This is needed to check for completion of the buffer in freelist_get + */ + entry->ring_ofs = RING_WRITE_OFS; + + OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); + OUT_RING( page ); + OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); + OUT_RING( 0 ); + + ADVANCE_RING(); + + return 0; +} + +/*@}*/ + + /*******************************************************************/ /** \name DMA test and initialization */ /*@{*/ diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h index 347c9426..7bd40a68 100644 --- a/shared-core/mach64_drv.h +++ b/shared-core/mach64_drv.h @@ -140,6 +140,11 @@ extern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv); extern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv); extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv); +extern int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, + drm_mach64_freelist_t *_entry); +extern int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv, + drm_mach64_freelist_t *_entry); + extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv); extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv); extern int mach64_do_cleanup_dma(struct drm_device * dev); @@ -521,89 +526,9 @@ extern void mach64_driver_irq_uninstall(struct drm_device * dev); #define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */ /* ================================================================ - * Misc helper macros + * Ring operations */ -static __inline__ void mach64_set_dma_eol(volatile u32 * addr) -{ -#if defined(__i386__) - int nr = 31; - - /* Taken from include/asm-i386/bitops.h linux header */ - __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr) - :"Ir"(nr)); -#elif defined(__powerpc__) - u32 old; - u32 mask = cpu_to_le32(MACH64_DMA_EOL); - - /* Taken from the include/asm-ppc/bitops.h linux header */ - __asm__ __volatile__("\n\ -1: lwarx %0,0,%3 \n\ - or %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ - bne- 1b":"=&r"(old), "=m"(*addr) - :"r"(mask), "r"(addr), "m"(*addr) - :"cc"); -#elif defined(__alpha__) - u32 temp; - u32 mask = MACH64_DMA_EOL; - - /* Taken from the include/asm-alpha/bitops.h linux header */ - __asm__ __volatile__("1: ldl_l %0,%3\n" - " bis %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous":"=&r"(temp), "=m"(*addr) - :"Ir"(mask), "m"(*addr)); -#else - u32 mask = cpu_to_le32(MACH64_DMA_EOL); - - *addr |= mask; -#endif -} - -static __inline__ void mach64_clear_dma_eol(volatile u32 * addr) -{ -#if defined(__i386__) - int nr = 31; - - /* Taken from include/asm-i386/bitops.h linux header */ - __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr) - :"Ir"(nr)); -#elif defined(__powerpc__) - u32 old; - u32 mask = cpu_to_le32(MACH64_DMA_EOL); - - /* Taken from the include/asm-ppc/bitops.h linux header */ - __asm__ __volatile__("\n\ -1: lwarx %0,0,%3 \n\ - andc %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ - bne- 1b":"=&r"(old), "=m"(*addr) - :"r"(mask), "r"(addr), "m"(*addr) - :"cc"); -#elif defined(__alpha__) - u32 temp; - u32 mask = ~MACH64_DMA_EOL; - - /* Taken from the include/asm-alpha/bitops.h linux header */ - __asm__ __volatile__("1: ldl_l %0,%3\n" - " and %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous":"=&r"(temp), "=m"(*addr) - :"Ir"(mask), "m"(*addr)); -#else - u32 mask = cpu_to_le32(~MACH64_DMA_EOL); - - *addr &= mask; -#endif -} - static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv) { drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; @@ -749,59 +674,6 @@ mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv) } } -/* ================================================================ - * DMA descriptor ring macros - */ - -#define RING_LOCALS \ - int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring - -#define RING_WRITE_OFS _ring_write - -#define BEGIN_RING( n ) \ -do { \ - if ( MACH64_VERBOSE ) { \ - DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ - (n), __FUNCTION__ ); \ - } \ - if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ - int ret; \ - if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \ - DRM_ERROR( "wait_ring failed, resetting engine\n"); \ - mach64_dump_engine_info( dev_priv ); \ - mach64_do_engine_reset( dev_priv ); \ - return ret; \ - } \ - } \ - dev_priv->ring.space -= (n) * sizeof(u32); \ - _ring = (u32 *) dev_priv->ring.start; \ - _ring_tail = _ring_write = dev_priv->ring.tail; \ - _ring_mask = dev_priv->ring.tail_mask; \ -} while (0) - -#define OUT_RING( x ) \ -do { \ - if ( MACH64_VERBOSE ) { \ - DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ - (unsigned int)(x), _ring_write ); \ - } \ - _ring[_ring_write++] = cpu_to_le32( x ); \ - _ring_write &= _ring_mask; \ -} while (0) - -#define ADVANCE_RING() \ -do { \ - if ( MACH64_VERBOSE ) { \ - DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ - _ring_write, _ring_tail ); \ - } \ - DRM_MEMORYBARRIER(); \ - mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \ - DRM_MEMORYBARRIER(); \ - dev_priv->ring.tail = _ring_write; \ - mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ -} while (0) - /* ================================================================ * DMA macros */ @@ -889,7 +761,7 @@ do { \ #define DMAADVANCE( dev_priv, _discard ) \ do { \ struct list_head *ptr; \ - RING_LOCALS; \ + int ret; \ \ if ( MACH64_VERBOSE ) { \ DRM_INFO( "DMAADVANCE() in %s\n", __FUNCTION__ ); \ @@ -902,7 +774,6 @@ do { \ } \ if (_buf->pending) { \ /* This is a resued buffer, so we need to find it in the pending list */ \ - int ret; \ if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) { \ DRM_ERROR( "DMAADVANCE() in %s: couldn't find pending buf %d\n", \ __FUNCTION__, _buf->idx ); \ @@ -927,7 +798,8 @@ do { \ list_add_tail(ptr, &dev_priv->pending); \ } \ _entry->discard = (_discard); \ - ADD_BUF_TO_RING( dev_priv ); \ + if ( (ret = mach64_add_buf_to_ring( dev_priv, _entry )) ) \ + return ret; \ } while (0) #define DMADISCARDBUF() \ @@ -943,48 +815,10 @@ do { \ _entry->discard = 1; \ } while(0) -#define ADD_BUF_TO_RING( dev_priv ) \ -do { \ - int bytes, pages, remainder; \ - u32 address, page; \ - int i; \ - \ - bytes = _buf->used; \ - address = GETBUFADDR( _buf ); \ - \ - pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; \ - \ - BEGIN_RING( pages * 4 ); \ - \ - for ( i = 0 ; i < pages-1 ; i++ ) { \ - page = address + i * MACH64_DMA_CHUNKSIZE; \ - OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); \ - OUT_RING( page ); \ - OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); \ - OUT_RING( 0 ); \ - } \ - \ - /* generate the final descriptor for any remaining commands in this buffer */ \ - page = address + i * MACH64_DMA_CHUNKSIZE; \ - remainder = bytes - i * MACH64_DMA_CHUNKSIZE; \ - \ - /* Save dword offset of last descriptor for this buffer. \ - * This is needed to check for completion of the buffer in freelist_get \ - */ \ - _entry->ring_ofs = RING_WRITE_OFS; \ - \ - OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); \ - OUT_RING( page ); \ - OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); \ - OUT_RING( 0 ); \ - \ - ADVANCE_RING(); \ -} while(0) - #define DMAADVANCEHOSTDATA( dev_priv ) \ do { \ struct list_head *ptr; \ - RING_LOCALS; \ + int ret; \ \ if ( MACH64_VERBOSE ) { \ DRM_INFO( "DMAADVANCEHOSTDATA() in %s\n", __FUNCTION__ ); \ @@ -1008,51 +842,8 @@ do { \ _entry->buf->pending = 1; \ list_add_tail(ptr, &dev_priv->pending); \ _entry->discard = 1; \ - ADD_HOSTDATA_BUF_TO_RING( dev_priv ); \ + if ( (ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry )) ) \ + return ret; \ } while (0) -#define ADD_HOSTDATA_BUF_TO_RING( dev_priv ) \ -do { \ - int bytes, pages, remainder; \ - u32 address, page; \ - int i; \ - \ - bytes = _buf->used - MACH64_HOSTDATA_BLIT_OFFSET; \ - pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; \ - address = GETBUFADDR( _buf ); \ - \ - BEGIN_RING( 4 + pages * 4 ); \ - \ - OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); \ - OUT_RING( address ); \ - OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET ); \ - OUT_RING( 0 ); \ - \ - address += MACH64_HOSTDATA_BLIT_OFFSET; \ - \ - for ( i = 0 ; i < pages-1 ; i++ ) { \ - page = address + i * MACH64_DMA_CHUNKSIZE; \ - OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); \ - OUT_RING( page ); \ - OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); \ - OUT_RING( 0 ); \ - } \ - \ - /* generate the final descriptor for any remaining commands in this buffer */ \ - page = address + i * MACH64_DMA_CHUNKSIZE; \ - remainder = bytes - i * MACH64_DMA_CHUNKSIZE; \ - \ - /* Save dword offset of last descriptor for this buffer. \ - * This is needed to check for completion of the buffer in freelist_get \ - */ \ - _entry->ring_ofs = RING_WRITE_OFS; \ - \ - OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); \ - OUT_RING( page ); \ - OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); \ - OUT_RING( 0 ); \ - \ - ADVANCE_RING(); \ -} while(0) - #endif /* __MACH64_DRV_H__ */ -- cgit v1.2.3 From f1a99ddc14ebca303f20b6c23bd289fc887243ae Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 6 Dec 2007 16:03:28 +1000 Subject: take down stuff after asking driver to unload --- linux-core/drm_drv.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 869748f8..343d5f32 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -394,15 +394,6 @@ static void drm_cleanup(struct drm_device * dev) drm_lastclose(dev); drm_fence_manager_takedown(dev); - drm_ht_remove(&dev->map_hash); - drm_mm_takedown(&dev->offset_manager); - drm_ht_remove(&dev->object_hash); - - if (!drm_fb_loaded) - pci_disable_device(dev->pdev); - - drm_ctxbitmap_cleanup(dev); - if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp && dev->agp->agp_mtrr >= 0) { int retval; @@ -419,6 +410,14 @@ static void drm_cleanup(struct drm_device * dev) if (dev->driver->unload) dev->driver->unload(dev); + if (!drm_fb_loaded) + pci_disable_device(dev->pdev); + + drm_ctxbitmap_cleanup(dev); + drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); + drm_ht_remove(&dev->object_hash); + drm_put_head(&dev->primary); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); -- cgit v1.2.3 From bfc29606e4a818897eebca46a5e23bbe7bc3ce25 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 7 Dec 2007 14:24:45 -0800 Subject: Fix pipe<->plane mapping vs. vblank handling (again) If drmMinor >= 6, the intel DDX driver will enable vblank events on both pipes. If drmMinor >= 10 on pre-965 chipsets, the intel DDX driver will swap the pipe<->plane mapping to allow for framebuffer compression on laptop screens. This means the secondary vblank counter (corresponding to pipe B) will be incremented when vblank interrupts occur. Now Mesa waits for vblank events on whichever plane has a greater portion of the displayed window. So it will happly ask to wait for the primary counter even though that one won't increment. So we can fix this in either the DDX driver, Mesa or the kernel (though I thought we already had several times). Since current (and previous) userspace assumes it's talking about a pipe == plane situation and now uses planes when talking to the kernel, we should probably just hide the mapping details there (indeed they already are hidden there for vblank swaps), which this patch does. So as far as userland is concerned, whether we call things planes or pipes is irrelevant, as long as kernel developers understand that userland hands them planes and they have to figure out which pipe that corresponds to (which will typically be the same on 965+ hardware and reversed on pre-965 mobile chips). --- shared-core/i915_irq.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index e7f3b083..ee7c40b5 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -456,12 +456,25 @@ static int i915_driver_vblank_do_wait(struct drm_device *dev, int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) { - return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); + atomic_t *counter; + + if (i915_get_pipe(dev, 0) == 0) + counter = &dev->vbl_received; + else + counter = &dev->vbl_received2; + return i915_driver_vblank_do_wait(dev, sequence, counter); } int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) { - return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); + atomic_t *counter; + + if (i915_get_pipe(dev, 1) == 0) + counter = &dev->vbl_received; + else + counter = &dev->vbl_received2; + + return i915_driver_vblank_do_wait(dev, sequence, counter); } /* Needs the lock as it touches the ring. -- cgit v1.2.3 From 7d08b816b7af3cd415bebf65f44313415fea091a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 8 Dec 2007 19:21:27 +0000 Subject: mach64: comment bus master / ring buffer behavior and security --- shared-core/mach64_dma.c | 28 +++++++++++++++++++++++++++- shared-core/mach64_drv.h | 20 ++++++++++++++++++++ shared-core/mach64_state.c | 14 ++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index 9aa3f768..411b98d5 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -562,6 +562,14 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv) /** \name DMA descriptor ring macros */ /*@{*/ +/** + * Add the end mark to the ring's new tail position. + * + * The bus master engine will keep processing the DMA buffers listed in the ring + * until it finds this mark, making it stop. + * + * \sa mach64_clear_dma_eol + */ static __inline__ void mach64_set_dma_eol(volatile u32 * addr) { #if defined(__i386__) @@ -602,6 +610,17 @@ static __inline__ void mach64_set_dma_eol(volatile u32 * addr) #endif } +/** + * Remove the end mark from the ring's old tail position. + * + * It should be called after calling mach64_set_dma_eol to mark the ring's new + * tail position. + * + * We update the end marks while the bus master engine is in operation. Since + * the bus master engine may potentially be reading from the same position + * that we write, we must change atomically to avoid having intermediary bad + * data. + */ static __inline__ void mach64_clear_dma_eol(volatile u32 * addr) { #if defined(__i386__) @@ -691,7 +710,9 @@ do { \ mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ } while (0) - +/** + * Queue a DMA buffer of registers writes into the ring buffer. + */ int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, drm_mach64_freelist_t *entry) { @@ -734,6 +755,11 @@ int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, return 0; } +/** + * Queue DMA buffer controlling host data tranfers (e.g., blit). + * + * Almost identical to mach64_add_buf_to_ring. + */ int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv, drm_mach64_freelist_t *entry) { diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h index 7bd40a68..1768a2a4 100644 --- a/shared-core/mach64_drv.h +++ b/shared-core/mach64_drv.h @@ -527,6 +527,9 @@ extern void mach64_driver_irq_uninstall(struct drm_device * dev); /* ================================================================ * Ring operations + * + * Since the Mach64 bus master engine requires polling, these functions end + * up being called frequently, hence being inline. */ static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv) @@ -591,6 +594,18 @@ static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv, } } +/** + * Poll the ring head and make sure the bus master is alive. + * + * Mach64's bus master engine will stop if there are no more entries to process. + * This function polls the engine for the last processed entry and calls + * mach64_ring_resume if there is an unprocessed entry. + * + * Note also that, since we update the ring tail while the bus master engine is + * in operation, it is possible that the last tail update was too late to be + * processed, and the bus master engine stops at the previous tail position. + * Therefore it is important to call this function frequently. + */ static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv, drm_mach64_descriptor_ring_t * ring) { @@ -676,6 +691,11 @@ mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv) /* ================================================================ * DMA macros + * + * Mach64's ring buffer doesn't take register writes directly. These + * have to be written indirectly in DMA buffers. These macros simplify + * the task of setting up a buffer, writing commands to it, and + * queuing the buffer in the ring. */ #define DMALOCALS \ diff --git a/shared-core/mach64_state.c b/shared-core/mach64_state.c index 6fcae948..88ff4843 100644 --- a/shared-core/mach64_state.c +++ b/shared-core/mach64_state.c @@ -575,6 +575,10 @@ static int mach64_dma_dispatch_vertex(struct drm_device * dev, return -EAGAIN; } + /* Mach64's vertex data is actually register writes. To avoid security + * compromises these register writes have to be verified and copied from + * user space into a private DMA buffer. + */ verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used); if (verify_ret != 0) { @@ -698,6 +702,16 @@ static int mach64_dma_dispatch_blit(struct drm_device * dev, return -EAGAIN; } + /* Copy the blit data from userspace. + * + * XXX: This is overkill. The most efficient solution would be having + * two sets of buffers (one set private for vertex data, the other set + * client-writable for blits). However that would bring more complexity + * and would break backward compatability. The solution currently + * implemented is keeping all buffers private, allowing to secure the + * driver, without increasing complexity at the expense of some speed + * transfering data. + */ verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used); if (verify_ret != 0) { -- cgit v1.2.3 From cfa21b22b43c7113107b5eb086b5f4d4ec36dc0a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Dec 2007 10:13:52 +1000 Subject: drm: move agp include outside CONFIG_AGP as it isn't dependant on agp in kernel --- linux-core/drmP.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 78b4b84c..dbf2a924 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -66,8 +66,8 @@ #ifdef CONFIG_MTRR #include #endif -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) #include +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) #include #include #endif -- cgit v1.2.3