drm/gem: Provide offset-adjusted framebuffer BO mappings
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 3 Aug 2021 12:59:18 +0000 (14:59 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Sun, 8 Aug 2021 18:26:16 +0000 (20:26 +0200)
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: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210803125928.27780-2-tzimmermann@suse.de
drivers/gpu/drm/drm_gem_atomic_helper.c
drivers/gpu/drm/drm_gem_framebuffer_helper.c
drivers/gpu/drm/gud/gud_pipe.c
drivers/gpu/drm/vkms/vkms_writeback.c
include/drm/drm_gem_atomic_helper.h
include/drm/drm_gem_framebuffer_helper.h

index 4865870cc60e1f19078d2471e33edc8e26a98593..e570398abd78e40b9b4a3b5420f000df704632a1 100644 (file)
@@ -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);
 
index 5731a6a1dfa5ff4fbc4590d16b72579a845365a6..3c75d79dbb6517df6c569c1d45a069dfaa8012d3 100644 (file)
@@ -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:
index 7e009f562b3050ed615fdbfd1d206f603c405595..6270a1a32a65643896b7a1a30006123601d50dc8 100644 (file)
@@ -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;
 
index 425b6c6b8cad8267613affae31c638c6070a3e1e..3a8e2ed93e7c62c0d17399393aa87145802ab29c 100644 (file)
@@ -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;
index f9f8b6f0494a3967963e9eade9e624a1198cdb38..48222a107873725fbd84c785aeed057d38259429 100644 (file)
@@ -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];
 };
 
 /**
index ff2024dd7b77c8565513b6dd5c220d54c93d40e8..905727719ead3917bfce59a459778808bca2e719 100644 (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);
 
 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);