On Thu, Nov 03, 2011 at 06:20:58PM +0000, Alan Cox wrote:
From: Alan Cox alan@linux.intel.com
The driver uses GEM along with a couple of small bits of wrapping of its own. The only real oddity here is the support for using the 'stolen' memory rather than wasting several MB.
We use a simple resource manager as we don't need to manage our space intensively at all as we only do 2D work. We also have a GTT which is entirely GPU facing so in the Cedarview case are not even allocating from host address space.
Signed-off-by: Alan Cox alan@linux.intel.com
One tiny comment below (has no effect on the actual code) and your drm_glue.c is already merged through some patches from Rob Clarke.
Reviewed-by: Signed-Off-by: Daniel Vetter daniel.vetter@ffwll.ch
[snip]
+static int psb_gem_create(struct drm_file *file,
- struct drm_device *dev, uint64_t size, uint32_t *handlep)
+{
- struct gtt_range *r;
- int ret;
- u32 handle;
- size = roundup(size, PAGE_SIZE);
- /* Allocate our object - for now a direct gtt range which is not
stolen memory backed */
- r = psb_gtt_alloc_range(dev, size, "gem", 0);
- if (r == NULL) {
dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
return -ENOSPC;
- }
- /* Initialize the extra goodies GEM needs to do all the hard work */
- if (drm_gem_object_init(dev, &r->gem, size) != 0) {
psb_gtt_free_range(dev, r);
/* GEM doesn't give an error code and we don't have an
EGEMSUCKS so make something up for now - FIXME */
dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM;
Actually my drm_gem_object_init here returns -ENOMEM in the (currently only) failure case ...
- }
- /* Give the object a handle so we can carry it more easily */
- ret = drm_gem_handle_create(file, &r->gem, &handle);
- if (ret) {
dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
&r->gem, size);
drm_gem_object_release(&r->gem);
psb_gtt_free_range(dev, r);
return ret;
- }
- /* We have the initial and handle reference but need only one now */
- drm_gem_object_unreference(&r->gem);
- *handlep = handle;
- return 0;
+}
[snip]
diff --git a/drivers/gpu/drm/gma500/gem_glue.c b/drivers/gpu/drm/gma500/gem_glue.c new file mode 100644 index 0000000..daac121 --- /dev/null +++ b/drivers/gpu/drm/gma500/gem_glue.c @@ -0,0 +1,89 @@ +/**************************************************************************
- Copyright (c) 2011, Intel Corporation.
- All Rights Reserved.
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- **************************************************************************/
+#include <drm/drmP.h> +#include <drm/drm.h>
+void drm_gem_object_release_wrap(struct drm_gem_object *obj) +{
- /* Remove the list map if one is present */
- if (obj->map_list.map) {
struct drm_gem_mm *mm = obj->dev->mm_private;
struct drm_map_list *list = &obj->map_list;
drm_ht_remove_item(&mm->offset_hash, &list->hash);
drm_mm_put_block(list->file_offset_node);
kfree(list->map);
list->map = NULL;
drm_gem_free_mmap_offset from Rob Clarke does that for you.
- }
- drm_gem_object_release(obj);
+}
+/**
- gem_create_mmap_offset - invent an mmap offset
- @obj: our object
- Standard implementation of offset generation for mmap as is
- duplicated in several drivers. This belongs in GEM.
- */
+int gem_create_mmap_offset(struct drm_gem_object *obj)
Already merged.
+{
- struct drm_device *dev = obj->dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_local_map *map;
- int ret;
- list = &obj->map_list;
- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
- if (list->map == NULL)
return -ENOMEM;
- map = list->map;
- map->type = _DRM_GEM;
- map->size = obj->size;
- map->handle = obj;
- list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
obj->size / PAGE_SIZE, 0, 0);
- if (!list->file_offset_node) {
dev_err(dev->dev, "failed to allocate offset for bo %d\n",
obj->name);
ret = -ENOSPC;
goto free_it;
- }
- list->file_offset_node = drm_mm_get_block(list->file_offset_node,
obj->size / PAGE_SIZE, 0);
- if (!list->file_offset_node) {
ret = -ENOMEM;
goto free_it;
- }
- list->hash.key = list->file_offset_node->start;
- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
- if (ret) {
dev_err(dev->dev, "failed to add to map hash\n");
goto free_mm;
- }
- return 0;
+free_mm:
- drm_mm_put_block(list->file_offset_node);
+free_it:
- kfree(list->map);
- list->map = NULL;
- return ret;
+} diff --git a/drivers/gpu/drm/gma500/gem_glue.h b/drivers/gpu/drm/gma500/gem_glue.h new file mode 100644 index 0000000..ce5ce30 --- /dev/null +++ b/drivers/gpu/drm/gma500/gem_glue.h @@ -0,0 +1,2 @@ +extern void drm_gem_object_release_wrap(struct drm_gem_object *obj); +extern int gem_create_mmap_offset(struct drm_gem_object *obj);
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel