Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+41 -29
+41 -29
drivers/gpu/drm/ast/ast_cursor.c
··· 28 28 #include <drm/drm_damage_helper.h> 29 29 #include <drm/drm_format_helper.h> 30 30 #include <drm/drm_gem_atomic_helper.h> 31 + #include <drm/drm_gem_framebuffer_helper.h> 31 32 #include <drm/drm_print.h> 32 33 33 34 #include "ast_drv.h" ··· 190 189 struct drm_framebuffer *fb = plane_state->fb; 191 190 u8 *argb4444 = NULL; 192 191 193 - switch (fb->format->format) { 194 - case DRM_FORMAT_ARGB4444: 195 - if (shadow_plane_state->data[0].is_iomem) { 196 - struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = { 197 - IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444), 198 - }; 199 - unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 200 - AST_HWC_PITCH, 201 - }; 192 + if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE) == 0) { 193 + switch (fb->format->format) { 194 + case DRM_FORMAT_ARGB4444: 195 + if (shadow_plane_state->data[0].is_iomem) { 196 + struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = { 197 + IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444), 198 + }; 199 + unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 200 + AST_HWC_PITCH, 201 + }; 202 202 203 - drm_fb_memcpy(argb4444_dst, argb4444_dst_pitch, 204 - shadow_plane_state->data, fb, clip); 205 - argb4444 = argb4444_dst[0].vaddr; 206 - } else { 207 - argb4444 = shadow_plane_state->data[0].vaddr; 208 - } 209 - break; 210 - case DRM_FORMAT_ARGB8888: 211 - { 212 - struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = { 213 - IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444), 214 - }; 215 - unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 216 - AST_HWC_PITCH, 217 - }; 203 + drm_fb_memcpy(argb4444_dst, argb4444_dst_pitch, 204 + shadow_plane_state->data, fb, clip); 205 + argb4444 = argb4444_dst[0].vaddr; 206 + } else { 207 + argb4444 = shadow_plane_state->data[0].vaddr; 208 + } 209 + break; 210 + case DRM_FORMAT_ARGB8888: 211 + { 212 + struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = { 213 + IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444), 214 + }; 215 + unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 216 + AST_HWC_PITCH, 217 + }; 218 218 219 - drm_fb_argb8888_to_argb4444(argb4444_dst, argb4444_dst_pitch, 220 - shadow_plane_state->data, fb, clip, 221 - &shadow_plane_state->fmtcnv_state); 222 - argb4444 = argb4444_dst[0].vaddr; 219 + drm_fb_argb8888_to_argb4444(argb4444_dst, argb4444_dst_pitch, 220 + shadow_plane_state->data, fb, clip, 221 + &shadow_plane_state->fmtcnv_state); 222 + argb4444 = argb4444_dst[0].vaddr; 223 + } 224 + break; 223 225 } 224 - break; 226 + 227 + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); 228 + } else { 229 + /* 230 + * Fall back to white square if GEM object is not ready. Gives 231 + * the user an indication where the cursor is located. 232 + */ 233 + memset(ast_cursor_plane->argb4444, 0xff, sizeof(ast_cursor_plane->argb4444)); 234 + argb4444 = ast_cursor_plane->argb4444; 225 235 } 226 236 227 237 return argb4444;