diff options
-rw-r--r-- | drivers/gpu/drm/drm_gem_atomic_helper.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_gem_framebuffer_helper.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/gud/gud_pipe.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vkms/vkms_writeback.c | 2 | ||||
-rw-r--r-- | include/drm/drm_gem_atomic_helper.h | 8 | ||||
-rw-r--r-- | include/drm/drm_gem_framebuffer_helper.h | 3 |
6 files changed, 29 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index 4865870cc60e..e570398abd78 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -339,7 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p if (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); diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index 5731a6a1dfa5..3c75d79dbb65 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -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 * @fb: the framebuffer * @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 * 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. * + * 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. * * 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 dma_buf_map map[static DRM_FORMAT_MAX_PLANES], + struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]) { struct drm_gem_object *obj; unsigned int i; @@ -344,6 +350,15 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, 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; err_drm_gem_vunmap: diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 7e009f562b30..6270a1a32a65 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -162,7 +162,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, if (len > gdrm->bulk_len) return -E2BIG; - ret = drm_gem_fb_vmap(fb, map); + ret = drm_gem_fb_vmap(fb, map, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c index 425b6c6b8cad..3a8e2ed93e7c 100644 --- a/drivers/gpu/drm/vkms/vkms_writeback.c +++ b/drivers/gpu/drm/vkms/vkms_writeback.c @@ -75,7 +75,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector, if (!vkmsjob) return -ENOMEM; - ret = drm_gem_fb_vmap(job->fb, vkmsjob->map); + ret = drm_gem_fb_vmap(job->fb, vkmsjob->map, NULL); if (ret) { DRM_ERROR("vmap failed: %d\n", ret); goto err_kfree; diff --git a/include/drm/drm_gem_atomic_helper.h b/include/drm/drm_gem_atomic_helper.h index f9f8b6f0494a..48222a107873 100644 --- a/include/drm/drm_gem_atomic_helper.h +++ b/include/drm/drm_gem_atomic_helper.h @@ -42,6 +42,14 @@ struct drm_shadow_plane_state { * prepare_fb callback and removed in the cleanup_fb callback. */ 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]; }; /** diff --git a/include/drm/drm_gem_framebuffer_helper.h b/include/drm/drm_gem_framebuffer_helper.h index ff2024dd7b77..905727719ead 100644 --- a/include/drm/drm_gem_framebuffer_helper.h +++ b/include/drm/drm_gem_framebuffer_helper.h @@ -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); 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, 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); |