Merge branch 'master' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-101

Conflicts:

	linux-core/drm_drv.c
	shared-core/drm.h
	shared-core/i915_dma.c
This commit is contained in:
Dave Airlie 2007-12-11 16:58:00 +10:00
commit 8d2da20233
23 changed files with 440 additions and 312 deletions

View file

@ -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" );

View file

@ -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(); \
@ -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);
@ -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 */
@ -686,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;
};
@ -925,9 +927,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);

View file

@ -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;
@ -495,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 */
@ -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. */
@ -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,

View file

@ -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,
@ -244,8 +270,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);
@ -303,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,

View file

@ -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,

View file

@ -46,8 +46,9 @@ 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.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;
@ -68,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__

View file

@ -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;
@ -76,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__

View file

@ -66,8 +66,8 @@
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
#include <asm/agp.h>
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
#include <linux/types.h>
#include <linux/agp_backend.h>
#endif

View file

@ -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);
}

View file

@ -395,14 +395,6 @@ static void drm_cleanup(struct drm_device * dev)
drm_lastclose(dev);
drm_fence_manager_takedown(dev);
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;
@ -424,6 +416,11 @@ static void drm_cleanup(struct drm_device * 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");

View file

@ -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;
}

View file

@ -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);

View file

@ -280,7 +280,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();
}

View file

@ -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;

View file

@ -250,7 +250,7 @@ enum drm_map_flags {
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
_DRM_REMOVABLE = 0x40, /**< Removable mapping */
_DRM_DRIVER = 0x80 /**< Driver will take care of it */
_DRM_DRIVER = 0x80 /**< Managed by driver */
};
struct drm_ctx_priv_map {

View file

@ -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;
}
int i915_dma_cleanup(struct drm_device * dev)
@ -144,6 +139,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)) /* 965 doesn't support older method */
dev_priv->use_mi_batchbuffer_start = 1;
/* Allow hardware batchbuffers unless told otherwise.
*/
@ -181,7 +178,7 @@ static int i915_dma_resume(struct drm_device * dev)
{
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
DRM_DEBUG("\n");
if (!dev_priv->sarea) {
DRM_ERROR("can not find sarea!\n");
@ -315,7 +312,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)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@ -471,7 +468,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
@ -525,7 +522,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
@ -589,8 +586,7 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
struct drm_i915_private *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);
@ -606,7 +602,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)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@ -895,7 +891,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;
}
@ -946,7 +942,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;
@ -1011,10 +1007,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,
@ -1074,15 +1070,13 @@ int i915_do_cleanup_pageflip(struct drm_device * dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int i, planes, num_pages;
DRM_DEBUG("%s\n", __FUNCTION__);
if (!dev_priv->sarea_priv)
return 0;
DRM_DEBUG("\n");
num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
for (i = 0, planes = 0; i < 2; i++) {
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;
}
@ -1098,7 +1092,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f
{
struct drm_i915_flip *param = data;
DRM_DEBUG("%s\n", __FUNCTION__);
DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@ -1226,9 +1220,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]);

View file

@ -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

View file

@ -418,8 +418,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);
@ -472,12 +470,25 @@ void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe)
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.

View file

@ -6,7 +6,7 @@
* \author Gareth Hughes <gareth@valinux.com>
* \author Frank C. Earl <fearl@airmail.net>
* \author Leif Delgass <ldelgass@retinalburn.net>
* \author Jose Fonseca <j_r_fonseca@yahoo.co.uk>
* \author José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
/*
@ -558,6 +558,259 @@ 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__)
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
}
/**
* 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__)
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)
/**
* 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)
{
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;
}
/**
* 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)
{
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 */
/*@{*/

View file

@ -29,7 +29,7 @@
* Gareth Hughes <gareth@valinux.com>
* Frank C. Earl <fearl@airmail.net>
* Leif Delgass <ldelgass@retinalburn.net>
* Jos<EFBFBD>Fonseca <j_r_fonseca@yahoo.co.uk>
* José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
#ifndef __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,12 @@ 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
*
* Since the Mach64 bus master engine requires polling, these functions end
* up being called frequently, hence being inline.
*/
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;
@ -666,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)
{
@ -749,61 +689,13 @@ 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
*
* 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 \
@ -889,7 +781,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 +794,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 +818,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 +835,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 +862,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__ */

View file

@ -27,7 +27,7 @@
* Authors:
* Gareth Hughes <gareth@valinux.com>
* Leif Delgass <ldelgass@retinalburn.net>
* Jos<EFBFBD>Fonseca <j_r_fonseca@yahoo.co.uk>
* José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
#include "drmP.h"
@ -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) {

View file

@ -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) {

View file

@ -1974,7 +1974,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);