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

Commit 3248877e authored by Dave Airlie's avatar Dave Airlie
Browse files

drm: base prime/dma-buf support (v5)



This adds the basic drm dma-buf interface layer, called PRIME. This
commit doesn't add any driver support, it is simply and agreed upon starting
point so we can work towards merging driver support for the next merge window.

Current drivers with work done are nouveau, i915, udl, exynos and omap.

The main APIs exposed to userspace allow translating a 32-bit object handle
to a file descriptor, and a file descriptor to a 32-bit object handle.

The flags value is currently limited to O_CLOEXEC.

Acknowledgements:
Daniel Vetter: lots of review
Rob Clark: cleaned up lots of the internals and did lifetime review.

v2: rename some functions after Chris preferred a green shed
fix IS_ERR_OR_NULL -> IS_ERR
v3: Fix Ville pointed out using buffer + kmalloc
v4: add locking as per ickle review
v5: allow re-exporting the original dma-buf (Daniel)

Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarRob Clark <rob.clark@linaro.org>
Reviewed-by: default avatarSumit Semwal <sumit.semwal@linaro.org>
Reviewed-by: default avatarInki Dae <inki.dae@samsung.com>
Acked-by: default avatarBen Widawsky <benjamin.widawsky@intel.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent f52b69f8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ menuconfig DRM
	depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
	select I2C
	select I2C_ALGOBIT
	select DMA_SHARED_BUFFER
	help
	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
	  introduced in XFree86 4.0. If you say Y here, you need to select
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
		drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
		drm_crtc.o drm_modes.o drm_edid.o \
		drm_info.o drm_debugfs.o drm_encoder_slave.o \
		drm_trace_points.o drm_global.o
		drm_trace_points.o drm_global.o drm_prime.o

drm-$(CONFIG_COMPAT) += drm_ioc32.o

+4 −0
Original line number Diff line number Diff line
@@ -136,6 +136,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),

	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),

	DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED),

	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+7 −0
Original line number Diff line number Diff line
@@ -271,6 +271,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
	if (dev->driver->driver_features & DRIVER_GEM)
		drm_gem_open(dev, priv);

	if (drm_core_check_feature(dev, DRIVER_PRIME))
		drm_prime_init_file_private(&priv->prime);

	if (dev->driver->open) {
		ret = dev->driver->open(dev, priv);
		if (ret < 0)
@@ -571,6 +574,10 @@ int drm_release(struct inode *inode, struct file *filp)

	if (dev->driver->postclose)
		dev->driver->postclose(dev, file_priv);

	if (drm_core_check_feature(dev, DRIVER_PRIME))
		drm_prime_destroy_file_private(&file_priv->prime);

	kfree(file_priv);

	/* ========================================================
+9 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
#include "drmP.h"

/** @file drm_gem.c
@@ -232,6 +233,10 @@ 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);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, filp);
	drm_gem_object_handle_unreference_unlocked(obj);
@@ -527,6 +532,10 @@ 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);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, file_priv);

Loading