diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/glamo/glamo-buffer.c | 51 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-buffer.h | 3 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-cmdq.c | 34 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-drv.c | 8 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-private.h | 3 |
5 files changed, 78 insertions, 21 deletions
diff --git a/drivers/mfd/glamo/glamo-buffer.c b/drivers/mfd/glamo/glamo-buffer.c index 945824a1b15..ecf9cefc74c 100644 --- a/drivers/mfd/glamo/glamo-buffer.c +++ b/drivers/mfd/glamo/glamo-buffer.c @@ -27,6 +27,54 @@ #include "glamo-drm-private.h" +int glamo_ioctl_gem_info(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_glamo_gem_info *args = data; + struct glamodrm_handle *gdrm; + int ret; + + gdrm = dev->dev_private; + + /* Have we decided on a name for the front buffer yet? */ + if ( gdrm->front_buffer_handle ) { + args->front_buffer_handle = gdrm->front_buffer_handle; + } else { + + /* "Baptise" the front buffer */ + struct drm_gem_object *obj; + struct drm_glamo_gem_object *gobj; + uint32_t handle; + + /* We don't really care about this object - it's only being + * created so we can generate a handle to refer to the front + * buffer which X can use for the screen pixmap. */ + obj = drm_gem_object_alloc(dev, PAGE_SIZE); + if (obj == NULL) return -ENOMEM; + + gobj = obj->driver_private; + + ret = drm_gem_handle_create(file_priv, obj, &handle); + mutex_lock(&dev->struct_mutex); + drm_gem_object_handle_unreference(obj); + mutex_unlock(&dev->struct_mutex); + if (ret) return ret; + + /* The handle is specific to this context */ + printk(KERN_INFO "[glamo-drm] Front buffer handle: %i\n", + handle); + + args->front_buffer_handle = handle; + gdrm->front_buffer_handle = handle; + + } + + args->vram_size = gdrm->vram_size; + + return 0; +} + + int glamo_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -34,7 +82,7 @@ int glamo_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_gem_object *obj; struct glamodrm_handle *gdrm; struct drm_glamo_gem_object *gobj; - int handle, ret; + uint32_t handle, ret; gdrm = dev->dev_private; @@ -185,6 +233,7 @@ int glamo_buffer_init(struct glamodrm_handle *gdrm) { gdrm->mmgr = drm_calloc(1, sizeof(struct drm_mm), DRM_MEM_DRIVER); drm_mm_init(gdrm->mmgr, 0, gdrm->vram_size); + gdrm->front_buffer_handle = 0; return 0; } diff --git a/drivers/mfd/glamo/glamo-buffer.h b/drivers/mfd/glamo/glamo-buffer.h index 7d87e428d79..d326ecfac9e 100644 --- a/drivers/mfd/glamo/glamo-buffer.h +++ b/drivers/mfd/glamo/glamo-buffer.h @@ -36,6 +36,9 @@ extern int glamodrm_gem_init_object(struct drm_gem_object *obj); extern void glamodrm_gem_free_object(struct drm_gem_object *obj); +extern int glamo_ioctl_gem_info(struct drm_device *dev, void *data, + struct drm_file *file_priv); + extern int glamo_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/mfd/glamo/glamo-cmdq.c b/drivers/mfd/glamo/glamo-cmdq.c index 32fad98be8a..3c410f828da 100644 --- a/drivers/mfd/glamo/glamo-cmdq.c +++ b/drivers/mfd/glamo/glamo-cmdq.c @@ -243,6 +243,7 @@ static int glamo_do_relocation(struct glamodrm_handle *gdrm, struct drm_file *file_priv) { u32 *handles; + u32 front_handle; int *offsets; int nobjs = cbuf->nobjs; int i; @@ -259,6 +260,8 @@ static int glamo_do_relocation(struct glamodrm_handle *gdrm, if ( copy_from_user(offsets, cbuf->obj_pos, nobjs*sizeof(int)) ) return -1; + front_handle = gdrm->front_buffer_handle; + for ( i=0; i<nobjs; i++ ) { u32 handle = handles[i]; @@ -277,22 +280,29 @@ static int glamo_do_relocation(struct glamodrm_handle *gdrm, goto fail; } - obj = drm_gem_object_lookup(dev, file_priv, handle); - if ( obj == NULL ) return -1; + if ( handle == front_handle ) { - /* Unref the object now, or it'll never get freed. - * This should really happen after the GPU has finished - * the commands which are about to be submitted. */ - drm_gem_object_unreference(obj); + addr = GLAMO_OFFSET_FRAMEBUFFER; - gobj = obj->driver_private; - if ( gobj == NULL ) { - printk(KERN_WARNING "[glamo-drm] This object has no " - "private data!\n"); - goto fail; + } else { + obj = drm_gem_object_lookup(dev, file_priv, handle); + if ( obj == NULL ) return -1; + + /* Unref the object now, or it'll never get freed. + * This should really happen after the GPU has finished + * the commands which are about to be submitted. */ + drm_gem_object_unreference(obj); + + gobj = obj->driver_private; + if ( gobj == NULL ) { + printk(KERN_WARNING "[glamo-drm] This object " + "has no private data!\n"); + goto fail; + } + + addr = GLAMO_OFFSET_WORK + gobj->block->start; } - addr = GLAMO_OFFSET_WORK + gobj->block->start; addr_low = addr & 0xffff; addr_high = (addr >> 16) & 0x7f; printk(KERN_INFO "Addr low 0x%x, high 0x%x\n", diff --git a/drivers/mfd/glamo/glamo-drm-drv.c b/drivers/mfd/glamo/glamo-drm-drv.c index 856622d9e76..c5929aa48eb 100644 --- a/drivers/mfd/glamo/glamo-drm-drv.c +++ b/drivers/mfd/glamo/glamo-drm-drv.c @@ -49,14 +49,6 @@ static int glamo_ioctl_swap(struct drm_device *dev, void *data, } -static int glamo_ioctl_gem_info(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - printk(KERN_INFO "glamo_ioctl_gem_info\n"); - return 0; -} - - static int glamo_ioctl_gem_wait_rendering(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/drivers/mfd/glamo/glamo-drm-private.h b/drivers/mfd/glamo/glamo-drm-private.h index 4cc5877e118..07ee1b1041b 100644 --- a/drivers/mfd/glamo/glamo-drm-private.h +++ b/drivers/mfd/glamo/glamo-drm-private.h @@ -61,6 +61,9 @@ struct glamodrm_handle { /* semaphore against concurrent ioctl */ struct semaphore add_to_ring; + + /* Front buffer kludge */ + uint32_t front_buffer_handle; }; /* Private data. This is where we keep our memory management bits */ |