diff options
author | Thomas White <taw@bitwiz.org.uk> | 2009-05-04 12:47:05 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2009-05-04 12:47:05 +0100 |
commit | 6b88fb82138a28f6edf89700b44ca7d65da03163 (patch) | |
tree | 2bf7dd8e8b3548a459fd99513329a79796f41433 | |
parent | 3d56235cb9b596ad4fcc72db109d4d499b4b92c1 (diff) |
Add (untested) memory management
This implements the GEM 'create' ioctl.
Signed-off-by: Thomas White <taw@bitwiz.org.uk>
-rw-r--r-- | drivers/mfd/glamo/glamo-buffer.c | 114 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-buffer.h | 9 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-drv.c | 44 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-private.h | 12 |
4 files changed, 150 insertions, 29 deletions
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; +} diff --git a/drivers/mfd/glamo/glamo-buffer.h b/drivers/mfd/glamo/glamo-buffer.h index f4d5b3c3aae..7d87e428d79 100644 --- a/drivers/mfd/glamo/glamo-buffer.h +++ b/drivers/mfd/glamo/glamo-buffer.h @@ -27,6 +27,15 @@ #include "glamo-drm-private.h" +extern int glamo_buffer_init(struct glamodrm_handle *gdrm); +extern int glamo_buffer_final(struct glamodrm_handle *gdrm); + +extern int glamodrm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); + +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_create(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/mfd/glamo/glamo-drm-drv.c b/drivers/mfd/glamo/glamo-drm-drv.c index d402b780c66..2208a8ef5f7 100644 --- a/drivers/mfd/glamo/glamo-drm-drv.c +++ b/drivers/mfd/glamo/glamo-drm-drv.c @@ -47,6 +47,7 @@ static int glamo_ioctl_swap(struct drm_device *dev, void *data, return 0; } + static int glamo_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -54,6 +55,7 @@ static int glamo_ioctl_gem_info(struct drm_device *dev, void *data, return 0; } + static int glamo_ioctl_gem_wait_rendering(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -61,6 +63,7 @@ static int glamo_ioctl_gem_wait_rendering(struct drm_device *dev, void *data, return 0; } + struct drm_ioctl_desc glamo_ioctls[] = { DRM_IOCTL_DEF(DRM_GLAMO_CMDBUF, glamo_ioctl_cmdbuf, DRM_AUTH), DRM_IOCTL_DEF(DRM_GLAMO_SWAP, glamo_ioctl_swap, DRM_AUTH), @@ -75,18 +78,21 @@ struct drm_ioctl_desc glamo_ioctls[] = { glamo_ioctl_gem_wait_rendering, DRM_AUTH), }; + static int glamodrm_firstopen(struct drm_device *dev) { DRM_DEBUG("\n"); return 0; } + static int glamodrm_open(struct drm_device *dev, struct drm_file *fh) { DRM_DEBUG("\n"); return 0; } + static void glamodrm_preclose(struct drm_device *dev, struct drm_file *fh) { DRM_DEBUG("\n"); @@ -97,11 +103,13 @@ static void glamodrm_postclose(struct drm_device *dev, struct drm_file *fh) DRM_DEBUG("\n"); } + static void glamodrm_lastclose(struct drm_device *dev) { DRM_DEBUG("\n"); } + static int glamodrm_master_create(struct drm_device *dev, struct drm_master *master) { @@ -110,26 +118,13 @@ static int glamodrm_master_create(struct drm_device *dev, return 0; } + static void glamodrm_master_destroy(struct drm_device *dev, struct drm_master *master) { DRM_DEBUG("\n"); } -static int glamodrm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return VM_FAULT_SIGBUS; -} - -static int glamodrm_gem_init_object(struct drm_gem_object *obj) -{ - return 0; -} - -static void glamodrm_gem_free_object(struct drm_gem_object *obj) -{ -} - static struct vm_operations_struct glamodrm_gem_vm_ops = { .fault = glamodrm_gem_fault, @@ -252,6 +247,7 @@ static int glamodrm_probe(struct platform_device *pdev) /* Initialise DRM */ drm_platform_init(&glamodrm_drm_driver, pdev, (void *)gdrm); + glamo_buffer_init(gdrm); glamo_cmdq_init(gdrm); return 0; @@ -275,29 +271,30 @@ out_free: static int glamodrm_remove(struct platform_device *pdev) { - struct glamodrm_handle *glamodrm = platform_get_drvdata(pdev); + struct glamodrm_handle *gdrm = platform_get_drvdata(pdev); struct glamo_core *glamocore = pdev->dev.platform_data; glamo_engine_disable(glamocore, GLAMO_ENGINE_2D); glamo_engine_disable(glamocore, GLAMO_ENGINE_3D); + glamo_buffer_final(gdrm); drm_exit(&glamodrm_drm_driver); platform_set_drvdata(pdev, NULL); /* Release registers */ - iounmap(glamodrm->reg_base); - release_mem_region(glamodrm->reg->start, RESSIZE(glamodrm->reg)); + iounmap(gdrm->reg_base); + release_mem_region(gdrm->reg->start, RESSIZE(gdrm->reg)); /* Release VRAM */ - iounmap(glamodrm->vram_base); - release_mem_region(glamodrm->vram->start, RESSIZE(glamodrm->vram)); + iounmap(gdrm->vram_base); + release_mem_region(gdrm->vram->start, RESSIZE(gdrm->vram)); /* Release command queue */ - iounmap(glamodrm->cmdq_base); - release_mem_region(glamodrm->cmdq->start, RESSIZE(glamodrm->cmdq)); + iounmap(gdrm->cmdq_base); + release_mem_region(gdrm->cmdq->start, RESSIZE(gdrm->cmdq)); - kfree(glamodrm); + kfree(gdrm); return 0; } @@ -329,17 +326,20 @@ static struct platform_driver glamodrm_driver = { }, }; + static int __devinit glamodrm_init(void) { glamodrm_drm_driver.num_ioctls = DRM_ARRAY_SIZE(glamo_ioctls); return platform_driver_register(&glamodrm_driver); } + static void __exit glamodrm_exit(void) { platform_driver_unregister(&glamodrm_driver); } + module_init(glamodrm_init); module_exit(glamodrm_exit); diff --git a/drivers/mfd/glamo/glamo-drm-private.h b/drivers/mfd/glamo/glamo-drm-private.h index f6bc5b17e5e..59fbc2488c5 100644 --- a/drivers/mfd/glamo/glamo-drm-private.h +++ b/drivers/mfd/glamo/glamo-drm-private.h @@ -26,11 +26,13 @@ #ifndef __GLAMO_DRMPRIV_H #define __GLAMO_DRMPRIV_H + #include <linux/module.h> #include <linux/platform_device.h> #include "glamo-core.h" + struct glamodrm_handle { /* This device */ @@ -51,7 +53,17 @@ struct glamodrm_handle { char __iomem *cmdq_base; ssize_t vram_size; + + /* Memory management */ + struct drm_mm *mmgr; }; +/* Private data. This is where we keep our memory management bits */ +struct drm_glamo_gem_object { + struct drm_gem_object *obj; /* The GEM object this refers to */ + struct drm_mm_node *block; /* Block handle for drm_mm */ +}; + + #endif /* __GLAMO_DRMPRIV_H */ |