Commit 43b36232 authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/gem: Provide offset-adjusted framebuffer BO mappings

Add an additional argument to drm_gem_fb_vmap() to return each BO's
mapping adjusted by the respective offset. Update all callers.

The newly returned values point to the first byite of the data stored
in the framebuffer BOs. Drivers that access the BO data should use it.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210803125928.27780-2-tzimmermann@suse.de
parent 0a6dab7d
...@@ -339,7 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p ...@@ -339,7 +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;
return drm_gem_fb_vmap(fb, shadow_plane_state->map); return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data);
} }
EXPORT_SYMBOL(drm_gem_prepare_shadow_fb); EXPORT_SYMBOL(drm_gem_prepare_shadow_fb);
......
...@@ -315,19 +315,25 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty); ...@@ -315,19 +315,25 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
* drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space * drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space
* @fb: the framebuffer * @fb: the framebuffer
* @map: returns the mapping's address for each BO * @map: returns the mapping's address for each BO
* @data: returns the data address for each BO, can be NULL
* *
* This function maps all buffer objects of the given framebuffer into * This function maps all buffer objects of the given framebuffer into
* kernel address space and stores them in struct dma_buf_map. If the * 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 * mapping operation fails for one of the BOs, the function unmaps the
* already established mappings automatically. * already established mappings automatically.
* *
* Callers that want to access a BO's stored data should pass @data.
* The argument returns the addresses of the data stored in each BO. This
* is different from @map if the framebuffer's offsets field is non-zero.
*
* See drm_gem_fb_vunmap() for unmapping. * See drm_gem_fb_vunmap() for unmapping.
* *
* Returns: * Returns:
* 0 on success, or a negative errno code otherwise. * 0 on success, or a negative errno code otherwise.
*/ */
int drm_gem_fb_vmap(struct drm_framebuffer *fb, int drm_gem_fb_vmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]) struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES])
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
unsigned int i; unsigned int i;
...@@ -344,6 +350,15 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, ...@@ -344,6 +350,15 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb,
goto err_drm_gem_vunmap; goto err_drm_gem_vunmap;
} }
if (data) {
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
memcpy(&data[i], &map[i], sizeof(data[i]));
if (dma_buf_map_is_null(&data[i]))
continue;
dma_buf_map_incr(&data[i], fb->offsets[i]);
}
}
return 0; return 0;
err_drm_gem_vunmap: err_drm_gem_vunmap:
......
...@@ -162,7 +162,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, ...@@ -162,7 +162,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb,
if (len > gdrm->bulk_len) if (len > gdrm->bulk_len)
return -E2BIG; return -E2BIG;
ret = drm_gem_fb_vmap(fb, map); ret = drm_gem_fb_vmap(fb, map, NULL);
if (ret) if (ret)
return ret; return ret;
......
...@@ -75,7 +75,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector, ...@@ -75,7 +75,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector,
if (!vkmsjob) if (!vkmsjob)
return -ENOMEM; return -ENOMEM;
ret = drm_gem_fb_vmap(job->fb, vkmsjob->map); ret = drm_gem_fb_vmap(job->fb, vkmsjob->map, NULL);
if (ret) { if (ret) {
DRM_ERROR("vmap failed: %d\n", ret); DRM_ERROR("vmap failed: %d\n", ret);
goto err_kfree; goto err_kfree;
......
...@@ -42,6 +42,14 @@ struct drm_shadow_plane_state { ...@@ -42,6 +42,14 @@ struct drm_shadow_plane_state {
* prepare_fb callback and removed in the cleanup_fb callback. * prepare_fb callback and removed in the cleanup_fb callback.
*/ */
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
/**
* @data: Address of each framebuffer BO's data
*
* The address of the data stored in each mapping. This is different
* for framebuffers with non-zero offset fields.
*/
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
}; };
/** /**
......
...@@ -40,7 +40,8 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, ...@@ -40,7 +40,8 @@ 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, int drm_gem_fb_vmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]); struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]);
void drm_gem_fb_vunmap(struct drm_framebuffer *fb, void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]); 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment