Commit 6542ad89 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/vram-helpers: Add helpers for prepare_fb() and cleanup_fb()



The new helpers pin and unpin a framebuffer's GEM VRAM objects during
plane updates. This should be sufficient for most drivers' implementation
of prepare_fb() and cleanup_fb().

v2:
	* provide helpers for struct drm_simple_display_pipe_funcs
	* rename plane-helper funcs

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20191024081404.6978-2-tzimmermann@suse.de
parent 606be047
Loading
Loading
Loading
Loading
+126 −0
Original line number Diff line number Diff line
@@ -3,10 +3,13 @@
#include <drm/drm_debugfs.h>
#include <drm/drm_device.h>
#include <drm/drm_file.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_gem_vram_helper.h>
#include <drm/drm_mode.h>
#include <drm/drm_plane.h>
#include <drm/drm_prime.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/ttm/ttm_page_alloc.h>

static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
@@ -646,6 +649,129 @@ int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
}
EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);

/*
 * Helpers for struct drm_plane_helper_funcs
 */

/**
 * drm_gem_vram_plane_helper_prepare_fb() - \
 *	Implements &struct drm_plane_helper_funcs.prepare_fb
 * @plane:	a DRM plane
 * @new_state:	the plane's new state
 *
 * During plane updates, this function pins the GEM VRAM
 * objects of the plane's new framebuffer to VRAM. Call
 * drm_gem_vram_plane_helper_cleanup_fb() to unpin them.
 *
 * Returns:
 *	0 on success, or
 *	a negative errno code otherwise.
 */
int
drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane,
				     struct drm_plane_state *new_state)
{
	size_t i;
	struct drm_gem_vram_object *gbo;
	int ret;

	if (!new_state->fb)
		return 0;

	for (i = 0; i < ARRAY_SIZE(new_state->fb->obj); ++i) {
		if (!new_state->fb->obj[i])
			continue;
		gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]);
		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
		if (ret)
			goto err_drm_gem_vram_unpin;
	}

	return 0;

err_drm_gem_vram_unpin:
	while (i) {
		--i;
		gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]);
		drm_gem_vram_unpin(gbo);
	}
	return ret;
}
EXPORT_SYMBOL(drm_gem_vram_plane_helper_prepare_fb);

/**
 * drm_gem_vram_plane_helper_cleanup_fb() - \
 *	Implements &struct drm_plane_helper_funcs.cleanup_fb
 * @plane:	a DRM plane
 * @old_state:	the plane's old state
 *
 * During plane updates, this function unpins the GEM VRAM
 * objects of the plane's old framebuffer from VRAM. Complements
 * drm_gem_vram_plane_helper_prepare_fb().
 */
void
drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane,
				     struct drm_plane_state *old_state)
{
	size_t i;
	struct drm_gem_vram_object *gbo;

	if (!old_state->fb)
		return;

	for (i = 0; i < ARRAY_SIZE(old_state->fb->obj); ++i) {
		if (!old_state->fb->obj[i])
			continue;
		gbo = drm_gem_vram_of_gem(old_state->fb->obj[i]);
		drm_gem_vram_unpin(gbo);
	}
}
EXPORT_SYMBOL(drm_gem_vram_plane_helper_cleanup_fb);

/*
 * Helpers for struct drm_simple_display_pipe_funcs
 */

/**
 * drm_gem_vram_simple_display_pipe_prepare_fb() - \
 *	Implements &struct drm_simple_display_pipe_funcs.prepare_fb
 * @pipe:	a simple display pipe
 * @new_state:	the plane's new state
 *
 * During plane updates, this function pins the GEM VRAM
 * objects of the plane's new framebuffer to VRAM. Call
 * drm_gem_vram_simple_display_pipe_cleanup_fb() to unpin them.
 *
 * Returns:
 *	0 on success, or
 *	a negative errno code otherwise.
 */
int drm_gem_vram_simple_display_pipe_prepare_fb(
	struct drm_simple_display_pipe *pipe,
	struct drm_plane_state *new_state)
{
	return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state);
}
EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_prepare_fb);

/**
 * drm_gem_vram_simple_display_pipe_cleanup_fb() - \
 *	Implements &struct drm_simple_display_pipe_funcs.cleanup_fb
 * @pipe:	a simple display pipe
 * @old_state:	the plane's old state
 *
 * During plane updates, this function unpins the GEM VRAM
 * objects of the plane's old framebuffer from VRAM. Complements
 * drm_gem_vram_simple_display_pipe_prepare_fb().
 */
void drm_gem_vram_simple_display_pipe_cleanup_fb(
	struct drm_simple_display_pipe *pipe,
	struct drm_plane_state *old_state)
{
	drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state);
}
EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb);

/*
 * PRIME helpers
 */
+25 −0
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@
#include <linux/kernel.h> /* for container_of() */

struct drm_mode_create_dumb;
struct drm_plane;
struct drm_plane_state;
struct drm_simple_display_pipe;
struct drm_vram_mm_funcs;
struct filp;
struct vm_area_struct;
@@ -124,6 +127,28 @@ int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
					 struct drm_device *dev,
					 uint32_t handle, uint64_t *offset);

/*
 * Helpers for struct drm_plane_helper_funcs
 */
int
drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane,
				     struct drm_plane_state *new_state);
void
drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane,
				     struct drm_plane_state *old_state);

/*
 * Helpers for struct drm_simple_display_pipe_funcs
 */

int drm_gem_vram_simple_display_pipe_prepare_fb(
	struct drm_simple_display_pipe *pipe,
	struct drm_plane_state *new_state);

void drm_gem_vram_simple_display_pipe_cleanup_fb(
	struct drm_simple_display_pipe *pipe,
	struct drm_plane_state *old_state);

/**
 * define DRM_GEM_VRAM_DRIVER - default callback functions for \
	&struct drm_driver