i915: Add a dri2 init path that gets the lock from the dri2 sarea.

main
Kristian Høgsberg 2008-02-05 13:27:16 -05:00 committed by Kristian Høgsberg
parent db3f03ae35
commit 373dbcf8b2
3 changed files with 103 additions and 3 deletions

View File

@ -106,9 +106,73 @@ static int i915_dma_cleanup(struct drm_device * dev)
return 0;
}
static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
#define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16)
#define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff)
#define DRI2_SAREA_BLOCK_NEXT(p) \
((void *) ((unsigned char *) (p) + \
DRI2_SAREA_BLOCK_SIZE(*(unsigned int *) p)))
#define DRI2_SAREA_BLOCK_END 0x0000
#define DRI2_SAREA_BLOCK_LOCK 0x0001
#define DRI2_SAREA_BLOCK_EVENT_BUFFER 0x0002
static int
setup_dri2_sarea(struct drm_device * dev,
struct drm_file *file_priv,
drm_i915_init_t * init)
{
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
unsigned int *p, *end, *next;
mutex_lock(&dev->struct_mutex);
dev_priv->sarea_bo =
drm_lookup_buffer_object(file_priv,
init->sarea_handle, 1);
mutex_unlock(&dev->struct_mutex);
if (!dev_priv->sarea_bo) {
DRM_ERROR("did not find sarea bo\n");
return -EINVAL;
}
ret = drm_bo_kmap(dev_priv->sarea_bo, 0,
dev_priv->sarea_bo->num_pages,
&dev_priv->sarea_kmap);
if (ret) {
DRM_ERROR("could not map sarea bo\n");
return ret;
}
p = dev_priv->sarea_kmap.virtual;
end = (void *) p + (dev_priv->sarea_bo->num_pages << PAGE_SHIFT);
while (p < end && DRI2_SAREA_BLOCK_TYPE(*p) != DRI2_SAREA_BLOCK_END) {
switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
case DRI2_SAREA_BLOCK_LOCK:
dev->lock.hw_lock = (void *) (p + 1);
dev->sigdata.lock = dev->lock.hw_lock;
break;
}
next = DRI2_SAREA_BLOCK_NEXT(p);
if (next <= p || end < next) {
DRM_ERROR("malformed dri2 sarea: next is %p should be within %p-%p\n",
next, p, end);
return -EINVAL;
}
p = next;
}
return 0;
}
static int i915_initialize(struct drm_device * dev,
struct drm_file *file_priv,
drm_i915_init_t * init)
{
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
@ -201,6 +265,17 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
#ifdef I915_HAVE_BUFFER
mutex_init(&dev_priv->cmdbuf_mutex);
#endif
if (init->func == I915_INIT_DMA2) {
ret = setup_dri2_sarea(dev, file_priv, init);
if (ret) {
i915_dma_cleanup(dev);
DRM_ERROR("could not set up dri2 sarea\n");
return ret;
}
}
return 0;
}
@ -250,7 +325,8 @@ static int i915_dma_init(struct drm_device *dev, void *data,
switch (init->func) {
case I915_INIT_DMA:
retcode = i915_initialize(dev, init);
case I915_INIT_DMA2:
retcode = i915_initialize(dev, file_priv, init);
break;
case I915_CLEANUP_DMA:
retcode = i915_dma_cleanup(dev);
@ -1415,6 +1491,20 @@ void i915_driver_lastclose(struct drm_device * dev)
if (dev_priv->agp_heap)
i915_mem_takedown(&(dev_priv->agp_heap));
if (dev_priv->sarea_kmap.virtual) {
drm_bo_kunmap(&dev_priv->sarea_kmap);
dev_priv->sarea_kmap.virtual = NULL;
dev->lock.hw_lock = NULL;
dev->sigdata.lock = NULL;
}
if (dev_priv->sarea_bo) {
mutex_lock(&dev->struct_mutex);
drm_bo_usage_deref_locked(&dev_priv->sarea_bo);
mutex_unlock(&dev->struct_mutex);
dev_priv->sarea_bo = NULL;
}
i915_dma_cleanup(dev);
}

View File

@ -43,7 +43,12 @@ typedef struct _drm_i915_init {
enum {
I915_INIT_DMA = 0x01,
I915_CLEANUP_DMA = 0x02,
I915_RESUME_DMA = 0x03
I915_RESUME_DMA = 0x03,
/* Since this struct isn't versioned, just used a new
* 'func' code to indicate the presence of dri2 sarea
* info. */
I915_INIT_DMA2 = 0x04
} func;
unsigned int mmio_offset;
int sarea_priv_offset;
@ -61,6 +66,7 @@ typedef struct _drm_i915_init {
unsigned int depth_pitch;
unsigned int cpp;
unsigned int chipset;
unsigned int sarea_handle;
} drm_i915_init_t;
typedef struct _drm_i915_sarea {

View File

@ -147,6 +147,10 @@ typedef struct drm_i915_private {
drm_i915_vbl_swap_t vbl_swaps;
unsigned int swaps_pending;
/* DRI2 sarea */
struct drm_buffer_object *sarea_bo;
struct drm_bo_kmap_obj sarea_kmap;
/* Register state */
u8 saveLBB;
u32 saveDSPACNTR;