Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b2ba700 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'prime-merge' of ssh://people.freedesktop.org/~airlied/linux into drm-core-next

* 'prime-merge' of ssh://people.freedesktop.org/~airlied/linux:
  drm/radeon: add PRIME support (v2)
  i915: add dmabuf/prime buffer sharing support.
  nouveau: add PRIME support
  ttm: add prime sharing support to TTM (v2)
  udl: add prime fd->handle support.
  drm/prime: add exported buffers to current fprivs imported buffer list (v2)
  drm/prime: introduce sg->pages/addr arrays helper
parents 4d93914a 40f5cf99
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -201,6 +201,19 @@ free:
}
EXPORT_SYMBOL(drm_gem_object_alloc);

static void
drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
{
	if (obj->import_attach) {
		drm_prime_remove_imported_buf_handle(&filp->prime,
				obj->import_attach->dmabuf);
	}
	if (obj->export_dma_buf) {
		drm_prime_remove_imported_buf_handle(&filp->prime,
				obj->export_dma_buf);
	}
}

/**
 * Removes the mapping from handle to filp for this object.
 */
@@ -233,9 +246,7 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
	idr_remove(&filp->object_idr, handle);
	spin_unlock(&filp->table_lock);

	if (obj->import_attach)
		drm_prime_remove_imported_buf_handle(&filp->prime,
				obj->import_attach->dmabuf);
	drm_gem_remove_prime_handles(obj, filp);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, filp);
@@ -530,9 +541,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
	struct drm_gem_object *obj = ptr;
	struct drm_device *dev = obj->dev;

	if (obj->import_attach)
		drm_prime_remove_imported_buf_handle(&file_priv->prime,
				obj->import_attach->dmabuf);
	drm_gem_remove_prime_handles(obj, file_priv);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, file_priv);
+48 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
{
	struct drm_gem_object *obj;
	void *buf;
	int ret;

	obj = drm_gem_object_lookup(dev, file_priv, handle);
	if (!obj)
@@ -100,6 +101,17 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
		obj->export_dma_buf = buf;
		*prime_fd = dma_buf_fd(buf, flags);
	}
	/* if we've exported this buffer the cheat and add it to the import list
	 * so we get the correct handle back
	 */
	ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
			obj->export_dma_buf, handle);
	if (ret) {
		drm_gem_object_unreference_unlocked(obj);
		mutex_unlock(&file_priv->prime.lock);
		return ret;
	}

	mutex_unlock(&file_priv->prime.lock);
	return 0;
}
@@ -227,6 +239,42 @@ out:
}
EXPORT_SYMBOL(drm_prime_pages_to_sg);

/* export an sg table into an array of pages and addresses
   this is currently required by the TTM driver in order to do correct fault
   handling */
int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
				     dma_addr_t *addrs, int max_pages)
{
	unsigned count;
	struct scatterlist *sg;
	struct page *page;
	u32 len, offset;
	int pg_index;
	dma_addr_t addr;

	pg_index = 0;
	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
		len = sg->length;
		offset = sg->offset;
		page = sg_page(sg);
		addr = sg_dma_address(sg);

		while (len > 0) {
			if (WARN_ON(pg_index >= max_pages))
				return -1;
			pages[pg_index] = page;
			if (addrs)
				addrs[pg_index] = addr;

			page++;
			addr += PAGE_SIZE;
			len -= PAGE_SIZE;
			pg_index++;
		}
	}
	return 0;
}
EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
/* helper function to cleanup a GEM/prime object */
void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
{
+2 −1
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
	  dvo_ch7017.o \
	  dvo_ivch.o \
	  dvo_tfp410.o \
	  dvo_sil164.o
	  dvo_sil164.o \
	  i915_gem_dmabuf.o

i915-$(CONFIG_COMPAT)   += i915_ioc32.o

+7 −1
Original line number Diff line number Diff line
@@ -1039,7 +1039,7 @@ static struct drm_driver driver = {
	 */
	.driver_features =
	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME,
	.load = i915_driver_load,
	.unload = i915_driver_unload,
	.open = i915_driver_open,
@@ -1062,6 +1062,12 @@ static struct drm_driver driver = {
	.gem_init_object = i915_gem_init_object,
	.gem_free_object = i915_gem_free_object,
	.gem_vm_ops = &i915_gem_vm_ops,

	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
	.gem_prime_export = i915_gem_prime_export,
	.gem_prime_import = i915_gem_prime_import,

	.dumb_create = i915_gem_dumb_create,
	.dumb_map_offset = i915_gem_mmap_gtt,
	.dumb_destroy = i915_gem_dumb_destroy,
+11 −0
Original line number Diff line number Diff line
@@ -940,6 +940,8 @@ struct drm_i915_gem_object {
	struct scatterlist *sg_list;
	int num_sg;

	/* prime dma-buf support */
	struct sg_table *sg_table;
	/**
	 * Used for performing relocations during execbuffer insertion.
	 */
@@ -1245,6 +1247,8 @@ int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj);
void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev);

int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
				  gfp_t gfpmask);
int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj);
int i915_gem_object_sync(struct drm_i915_gem_object *obj,
@@ -1342,6 +1346,13 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev,
int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
				    enum i915_cache_level cache_level);

struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
				struct dma_buf *dma_buf);

struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
				struct drm_gem_object *gem_obj, int flags);


/* i915_gem_gtt.c */
int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev);
void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev);
Loading