]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/ast: Wrap cursor framebuffer access in drm_gem_fb_begin/end_cpu_access()
authorThomas Zimmermann <tzimmermann@suse.de>
Wed, 26 Nov 2025 09:40:10 +0000 (10:40 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Mon, 1 Dec 2025 07:40:19 +0000 (08:40 +0100)
Call drm_gem_fb_begin_cpu_access() and drm_gem_fb_end_cpu_access()
around cursor image updates. Imported buffers might have to be
synchronized for CPU access before they can be used.

Ignore errors from drm_gem_fb_begin_cpu_access(). These errors can
often be transitory. The cursor image will be updated on the next
frame. Meanwhile display a white square where the cursor would be.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>>
Link: https://patch.msgid.link/20251126094626.41985-4-tzimmermann@suse.de
drivers/gpu/drm/ast/ast_cursor.c

index 8d473ed2738cf68202c22ba56f21bffc7f3643da..30b62d3f015133d955bfc61e079fec5acea868dd 100644 (file)
@@ -28,6 +28,7 @@
 #include <drm/drm_damage_helper.h>
 #include <drm/drm_format_helper.h>
 #include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_print.h>
 
 #include "ast_drv.h"
@@ -189,38 +190,49 @@ static const u8 *ast_cursor_plane_get_argb4444(struct ast_cursor_plane *ast_curs
        struct drm_framebuffer *fb = plane_state->fb;
        u8 *argb4444 = NULL;
 
-       switch (fb->format->format) {
-       case DRM_FORMAT_ARGB4444:
-               if (shadow_plane_state->data[0].is_iomem) {
-                       struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
-                               IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444),
-                       };
-                       unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
-                               AST_HWC_PITCH,
-                       };
-
-                       drm_fb_memcpy(argb4444_dst, argb4444_dst_pitch,
-                                     shadow_plane_state->data, fb, clip);
-                       argb4444 = argb4444_dst[0].vaddr;
-               } else {
-                       argb4444 = shadow_plane_state->data[0].vaddr;
+       if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE) == 0) {
+               switch (fb->format->format) {
+               case DRM_FORMAT_ARGB4444:
+                       if (shadow_plane_state->data[0].is_iomem) {
+                               struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
+                                       IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444),
+                               };
+                               unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+                                       AST_HWC_PITCH,
+                               };
+
+                               drm_fb_memcpy(argb4444_dst, argb4444_dst_pitch,
+                                             shadow_plane_state->data, fb, clip);
+                               argb4444 = argb4444_dst[0].vaddr;
+                       } else {
+                               argb4444 = shadow_plane_state->data[0].vaddr;
+                       }
+                       break;
+               case DRM_FORMAT_ARGB8888:
+                       {
+                               struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
+                                       IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444),
+                               };
+                               unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+                                       AST_HWC_PITCH,
+                               };
+
+                               drm_fb_argb8888_to_argb4444(argb4444_dst, argb4444_dst_pitch,
+                                                           shadow_plane_state->data, fb, clip,
+                                                           &shadow_plane_state->fmtcnv_state);
+                               argb4444 = argb4444_dst[0].vaddr;
+                       }
+                       break;
                }
-               break;
-       case DRM_FORMAT_ARGB8888:
-               {
-                       struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
-                               IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444),
-                       };
-                       unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
-                               AST_HWC_PITCH,
-                       };
-
-                       drm_fb_argb8888_to_argb4444(argb4444_dst, argb4444_dst_pitch,
-                                                   shadow_plane_state->data, fb, clip,
-                                                   &shadow_plane_state->fmtcnv_state);
-                       argb4444 = argb4444_dst[0].vaddr;
-               }
-               break;
+
+               drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
+       } else {
+               /*
+                * Fall back to white square if GEM object is not ready. Gives
+                * the user an indication where the cursor is located.
+                */
+               memset(ast_cursor_plane->argb4444, 0xff, sizeof(ast_cursor_plane->argb4444));
+               argb4444 = ast_cursor_plane->argb4444;
        }
 
        return argb4444;