From 6b88fb82138a28f6edf89700b44ca7d65da03163 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 4 May 2009 12:47:05 +0100 Subject: Add (untested) memory management This implements the GEM 'create' ioctl. Signed-off-by: Thomas White --- drivers/mfd/glamo/glamo-buffer.c | 114 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 7 deletions(-) (limited to 'drivers/mfd/glamo/glamo-buffer.c') diff --git a/drivers/mfd/glamo/glamo-buffer.c b/drivers/mfd/glamo/glamo-buffer.c index d72c0fb737c..a150a9c571c 100644 --- a/drivers/mfd/glamo/glamo-buffer.c +++ b/drivers/mfd/glamo/glamo-buffer.c @@ -28,15 +28,60 @@ int glamo_ioctl_gem_create(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { - printk(KERN_INFO "glamo_ioctl_gem_create\n"); + struct drm_glamo_gem_create *args = data; + struct drm_gem_object *obj; + struct glamodrm_handle *gdrm; + struct drm_glamo_gem_object *gobj; + int handle, ret; + + gdrm = dev->dev_private; + + obj = drm_gem_object_alloc(dev, args->size); + if (obj == NULL) return -ENOMEM; + + gobj = obj->driver_private; + + /* Allocate memory for this object in VRAM */ + gobj->block = drm_mm_search_free(gdrm->mmgr, args->size, + args->alignment, 1); + if (!gobj->block) { + ret = -ENOMEM; + goto fail; + } + gobj->block = drm_mm_get_block(gobj->block, args->size, + args->alignment); + if (!gobj->block) { + ret = -ENOMEM; + goto fail; + } + + 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) goto fail; + + printk(KERN_INFO "[glamo-drm] %i: allocated %li bytes at %lx\n", + handle, gobj->block->size, gobj->block->start); + args->handle = handle; + return 0; + +fail: + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + printk(KERN_INFO "[glamo-drm] Failed to allocate object\n"); + + return ret; } int glamo_ioctl_gem_mmap(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { printk(KERN_INFO "glamo_ioctl_gem_mmap\n"); return 0; @@ -44,7 +89,7 @@ int glamo_ioctl_gem_mmap(struct drm_device *dev, void *data, int glamo_ioctl_gem_pin(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { printk(KERN_INFO "glamo_ioctl_gem_pin\n"); return 0; @@ -52,7 +97,7 @@ int glamo_ioctl_gem_pin(struct drm_device *dev, void *data, int glamo_ioctl_gem_unpin(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { printk(KERN_INFO "glamo_ioctl_gem_unpin\n"); return 0; @@ -60,7 +105,7 @@ int glamo_ioctl_gem_unpin(struct drm_device *dev, void *data, int glamo_ioctl_gem_pread(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { printk(KERN_INFO "glamo_ioctl_gem_pread\n"); return 0; @@ -68,8 +113,63 @@ int glamo_ioctl_gem_pread(struct drm_device *dev, void *data, int glamo_ioctl_gem_pwrite(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { printk(KERN_INFO "glamo_ioctl_gem_pwrite\n"); return 0; } + + +int glamodrm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + return VM_FAULT_SIGBUS; +} + + +int glamodrm_gem_init_object(struct drm_gem_object *obj) +{ + struct drm_glamo_gem_object *gobj; + + printk(KERN_INFO "Hello from glamodrm_gem_init_object\n"); + + /* Allocate a private structure */ + gobj = drm_calloc(1, sizeof(*gobj), DRM_MEM_DRIVER); + if (!gobj) return -ENOMEM; + + obj->driver_private = gobj; + gobj->obj = obj; + + return 0; +} + + +void glamodrm_gem_free_object(struct drm_gem_object *obj) +{ + struct drm_glamo_gem_object *gobj; + + gobj = obj->driver_private; + + /* Free the VRAM */ + drm_mm_put_block(gobj->block); + + /* Free the private structure */ + drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); +} + + +/* Memory management initialisation */ +int glamo_buffer_init(struct glamodrm_handle *gdrm) +{ + printk(KERN_INFO "[glamo-drm] Initialising memory manager.\n"); + drm_mm_init(gdrm->mmgr, 0, gdrm->vram_size); + return 0; +} + + +/* Memory management finalisation */ +int glamo_buffer_final(struct glamodrm_handle *gdrm) +{ + printk(KERN_INFO "[glamo-drm] Shutting down memory manager.\n"); + drm_mm_takedown(gdrm->mmgr); + return 0; +} -- cgit v1.2.3