From 4dfb97060f22c6c5bea995302f0f58936d8f3271 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 26 Nov 2025 10:40:10 +0100 Subject: [PATCH] drm/ast: Wrap cursor framebuffer access in drm_gem_fb_begin/end_cpu_access() 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 Reviewed-by: Jocelyn Falempe > Link: https://patch.msgid.link/20251126094626.41985-4-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_cursor.c | 74 +++++++++++++++++++------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c index 8d473ed2738cf..30b62d3f01513 100644 --- a/drivers/gpu/drm/ast/ast_cursor.c +++ b/drivers/gpu/drm/ast/ast_cursor.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #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; -- 2.47.3