Commit f6424ecd authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/gem: Provide drm_gem_fb_{vmap,vunmap}()



Move framebuffer vmap code from shadow-buffered plane state into the new
interfaces drm_gem_fb_vmap() and drm_gem_fb_vunmap(). These functions
provide mappings of a framebuffer's BOs into kernel address space. No
functional changes.

v4:
	* remove duplicated blank line
v2:
	* using [static N] for array parameters enables compile-time checks
	* include <drm/drm_fourcc.h> for DRM_FORMAT_MAX_PLANES (kernel
	  test robot)

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210730183511.20080-3-tzimmermann@suse.de
parent 279cc2e9
Loading
Loading
Loading
Loading
+2 −33
Original line number Original line Diff line number Diff line
@@ -330,10 +330,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p
{
{
	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
	struct drm_framebuffer *fb = plane_state->fb;
	struct drm_framebuffer *fb = plane_state->fb;
	struct drm_gem_object *obj;
	struct dma_buf_map map;
	int ret;
	int ret;
	size_t i;


	if (!fb)
	if (!fb)
		return 0;
		return 0;
@@ -342,27 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p
	if (ret)
	if (ret)
		return ret;
		return ret;


	for (i = 0; i < ARRAY_SIZE(shadow_plane_state->map); ++i) {
	return drm_gem_fb_vmap(fb, shadow_plane_state->map);
		obj = drm_gem_fb_get_obj(fb, i);
		if (!obj)
			continue;
		ret = drm_gem_vmap(obj, &map);
		if (ret)
			goto err_drm_gem_vunmap;
		shadow_plane_state->map[i] = map;
	}

	return 0;

err_drm_gem_vunmap:
	while (i) {
		--i;
		obj = drm_gem_fb_get_obj(fb, i);
		if (!obj)
			continue;
		drm_gem_vunmap(obj, &shadow_plane_state->map[i]);
	}
	return ret;
}
}
EXPORT_SYMBOL(drm_gem_prepare_shadow_fb);
EXPORT_SYMBOL(drm_gem_prepare_shadow_fb);


@@ -380,19 +357,11 @@ void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *
{
{
	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
	struct drm_framebuffer *fb = plane_state->fb;
	struct drm_framebuffer *fb = plane_state->fb;
	size_t i = ARRAY_SIZE(shadow_plane_state->map);
	struct drm_gem_object *obj;


	if (!fb)
	if (!fb)
		return;
		return;


	while (i) {
	drm_gem_fb_vunmap(fb, shadow_plane_state->map);
		--i;
		obj = drm_gem_fb_get_obj(fb, i);
		if (!obj)
			continue;
		drm_gem_vunmap(obj, &shadow_plane_state->map[i]);
	}
}
}
EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb);
EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb);


+72 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,8 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper.h>


#include "drm_internal.h"

#define AFBC_HEADER_SIZE		16
#define AFBC_HEADER_SIZE		16
#define AFBC_TH_LAYOUT_ALIGNMENT	8
#define AFBC_TH_LAYOUT_ALIGNMENT	8
#define AFBC_HDR_ALIGN			64
#define AFBC_HDR_ALIGN			64
@@ -309,6 +311,76 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
}
}
EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);


/**
 * drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space
 * @fb: the framebuffer
 * @map: returns the mapping's address for each BO
 *
 * This function maps all buffer objects of the given framebuffer into
 * kernel address space and stores them in struct dma_buf_map. If the
 * mapping operation fails for one of the BOs, the function unmaps the
 * already established mappings automatically.
 *
 * See drm_gem_fb_vunmap() for unmapping.
 *
 * Returns:
 * 0 on success, or a negative errno code otherwise.
 */
int drm_gem_fb_vmap(struct drm_framebuffer *fb,
		    struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES])
{
	struct drm_gem_object *obj;
	unsigned int i;
	int ret;

	for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
		obj = drm_gem_fb_get_obj(fb, i);
		if (!obj)
			continue;
		ret = drm_gem_vmap(obj, &map[i]);
		if (ret)
			goto err_drm_gem_vunmap;
	}

	return 0;

err_drm_gem_vunmap:
	while (i) {
		--i;
		obj = drm_gem_fb_get_obj(fb, i);
		if (!obj)
			continue;
		drm_gem_vunmap(obj, &map[i]);
	}
	return ret;
}
EXPORT_SYMBOL(drm_gem_fb_vmap);

/**
 * drm_gem_fb_vunmap - unmaps framebuffer BOs from kernel address space
 * @fb: the framebuffer
 * @map: mapping addresses as returned by drm_gem_fb_vmap()
 *
 * This function unmaps all buffer objects of the given framebuffer.
 *
 * See drm_gem_fb_vmap() for more information.
 */
void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
		       struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES])
{
	unsigned int i = DRM_FORMAT_MAX_PLANES;
	struct drm_gem_object *obj;

	while (i) {
		--i;
		obj = drm_gem_fb_get_obj(fb, i);
		if (!obj)
			continue;
		drm_gem_vunmap(obj, &map[i]);
	}
}
EXPORT_SYMBOL(drm_gem_fb_vunmap);

/**
/**
 * drm_gem_fb_begin_cpu_access - prepares GEM buffer objects for CPU access
 * drm_gem_fb_begin_cpu_access - prepares GEM buffer objects for CPU access
 * @fb: the framebuffer
 * @fb: the framebuffer
+6 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,8 @@
#include <linux/dma-buf.h>
#include <linux/dma-buf.h>
#include <linux/dma-buf-map.h>
#include <linux/dma-buf-map.h>


#include <drm/drm_fourcc.h>

struct drm_afbc_framebuffer;
struct drm_afbc_framebuffer;
struct drm_device;
struct drm_device;
struct drm_fb_helper_surface_size;
struct drm_fb_helper_surface_size;
@@ -37,6 +39,10 @@ struct drm_framebuffer *
drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
			     const struct drm_mode_fb_cmd2 *mode_cmd);
			     const struct drm_mode_fb_cmd2 *mode_cmd);


int drm_gem_fb_vmap(struct drm_framebuffer *fb,
		    struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]);
void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
		       struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]);
int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);