aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2009-05-04 12:47:05 +0100
committerThomas White <taw@bitwiz.org.uk>2009-05-04 12:47:05 +0100
commit6b88fb82138a28f6edf89700b44ca7d65da03163 (patch)
tree2bf7dd8e8b3548a459fd99513329a79796f41433 /drivers/mfd
parent3d56235cb9b596ad4fcc72db109d4d499b4b92c1 (diff)
Add (untested) memory management
This implements the GEM 'create' ioctl. Signed-off-by: Thomas White <taw@bitwiz.org.uk>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/glamo/glamo-buffer.c114
-rw-r--r--drivers/mfd/glamo/glamo-buffer.h9
-rw-r--r--drivers/mfd/glamo/glamo-drm-drv.c44
-rw-r--r--drivers/mfd/glamo/glamo-drm-private.h12
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 */