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 <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>>
Link: https://patch.msgid.link/20251126094626.41985-4-tzimmermann@suse.de
This commit is contained in:
Thomas Zimmermann 2025-11-26 10:40:10 +01:00
parent ef4ed8621a
commit 4dfb97060f

View 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,
};
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_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;
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;
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;