[PATCH 02/12] gma500: GEM and GEM glue

Daniel Vetter daniel at ffwll.ch
Thu Nov 3 12:27:30 PDT 2011


On Thu, Nov 03, 2011 at 06:20:58PM +0000, Alan Cox wrote:
> From: Alan Cox <alan at 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 at 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 at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48


More information about the dri-devel mailing list