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: Swap framebuffer writes on big-endian machines

Swap the pixel data when writing to framebuffer memory on big-endian
machines. Fixes incorrect output. Aspeed graphics does not appear to
support big-endian framebuffers after AST2400, although the feature
has been documented.

There's a lengthy discussion at [1].

v5:
- avoid restricted cast from __be16 (kernel test robot)

Signed-off-by: René Rebe <rene@exactco.de>
Link: https://lore.kernel.org/dri-devel/20251202.170626.2134482663677806825.rene@exactco.de/ # [1]
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20251212.210504.1355099120650239629.rene@exactco.de

authored by

René Rebe and committed by
Thomas Zimmermann
50c26c30 c83e4299

+17 -5
+8 -3
drivers/gpu/drm/ast/ast_cursor.c
··· 93 93 unsigned int width, unsigned int height) 94 94 { 95 95 u8 __iomem *dst = ast_plane_vaddr(&ast->cursor_plane.base); 96 - u32 csum; 97 - 98 - csum = ast_cursor_calculate_checksum(src, width, height); 96 + u32 csum = ast_cursor_calculate_checksum(src, width, height); 99 97 100 98 /* write pixel data */ 99 + #if defined(__BIG_ENDIAN) 100 + unsigned int i; 101 + 102 + for (i = 0; i < AST_HWC_SIZE; i += 2) 103 + writew(swab16(*(const __u16 *)&src[i]), &dst[i]); 104 + #else 101 105 memcpy_toio(dst, src, AST_HWC_SIZE); 106 + #endif 102 107 103 108 /* write checksum + signature */ 104 109 dst += AST_HWC_SIZE;
+9 -2
drivers/gpu/drm/ast/ast_mode.c
··· 526 526 527 527 static void ast_handle_damage(struct ast_plane *ast_plane, struct iosys_map *src, 528 528 struct drm_framebuffer *fb, 529 - const struct drm_rect *clip) 529 + const struct drm_rect *clip, 530 + struct drm_format_conv_state *fmtcnv_state) 530 531 { 531 532 struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(ast_plane_vaddr(ast_plane)); 532 533 533 534 iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip)); 535 + 536 + #if defined(__BIG_ENDIAN) 537 + drm_fb_swab(&dst, fb->pitches, src, fb, clip, !src[0].is_iomem, fmtcnv_state); 538 + #else 534 539 drm_fb_memcpy(&dst, fb->pitches, src, fb, clip); 540 + #endif 535 541 } 536 542 537 543 static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane, ··· 567 561 if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE) == 0) { 568 562 drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); 569 563 drm_atomic_for_each_plane_damage(&iter, &damage) { 570 - ast_handle_damage(ast_plane, shadow_plane_state->data, fb, &damage); 564 + ast_handle_damage(ast_plane, shadow_plane_state->data, fb, &damage, 565 + &shadow_plane_state->fmtcnv_state); 571 566 } 572 567 573 568 drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);