aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2009-06-11 16:28:49 +0100
committerThomas White <taw@bitwiz.org.uk>2009-06-11 16:28:49 +0100
commitd8e4b9ff4dc8bf57e53fa174f977c8fb00ec4e90 (patch)
treebc79de4a44ba183014c75f430c180e514e7b40e9
parent3a83621f0e6a52eff7402702b0774092cc7b0187 (diff)
Front buffer kludge
This makes the GEM "info" ioctl produce an object handle which can be used to refer to the front buffer (i.e. screen pixmap) in Xorg or otherwise. This is unfortunately necessary since this memory is allocated in the kernel by the framebuffer driver, and is not available to DRM until we move to KMS. Signed-off-by: Thomas White <taw@bitwiz.org.uk>
-rw-r--r--drivers/mfd/glamo/glamo-buffer.c51
-rw-r--r--drivers/mfd/glamo/glamo-buffer.h3
-rw-r--r--drivers/mfd/glamo/glamo-cmdq.c34
-rw-r--r--drivers/mfd/glamo/glamo-drm-drv.c8
-rw-r--r--drivers/mfd/glamo/glamo-drm-private.h3
-rw-r--r--include/drm/glamo_drm.h2
6 files changed, 79 insertions, 22 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 */
diff --git a/include/drm/glamo_drm.h b/include/drm/glamo_drm.h
index c14873d6527..147415f5cbe 100644
--- a/include/drm/glamo_drm.h
+++ b/include/drm/glamo_drm.h
@@ -75,8 +75,8 @@ typedef struct drm_glamo_cmd_buffer {
} drm_glamo_cmd_buffer_t;
struct drm_glamo_gem_info {
- uint64_t vram_start;
uint64_t vram_size;
+ uint32_t front_buffer_handle;
};
struct drm_glamo_gem_create {