aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ast/ast_mode.c
diff options
context:
space:
mode:
authorThomas Zimmermann <[email protected]>2025-02-17 12:22:05 +0000
committerThomas Zimmermann <[email protected]>2025-02-20 07:38:33 +0000
commit966a0d49d1cd57165ad3e6232cf9de6fe43ecc63 (patch)
tree312a8a021d381075b299416f2000418ff349ebf5 /drivers/gpu/drm/ast/ast_mode.c
parentdrm/ast: cursor: Calculate checksum in helper (diff)
downloadkernel-966a0d49d1cd57165ad3e6232cf9de6fe43ecc63.tar.gz
kernel-966a0d49d1cd57165ad3e6232cf9de6fe43ecc63.zip
drm/ast: cursor: Move format conversion to shared helper
User-space cursor-image data is encoded in ARBG8888, while hardware supports ARGB4444. Implement the format conversion as part of the format-helper framework, so that other drivers can benefit. This allows to respect the damage area of the cursor update. In previous code, all cursor image data had to be converted on each update. Now, only the changed areas require an update. The hardware image is always updated completely, as it is required for the checksum update. The format-conversion helper still contains the old implementation's optimization of writing 2 output pixels at the same time. Signed-off-by: Thomas Zimmermann <[email protected]> Reviewed-by: Jocelyn Falempe <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Diffstat (limited to 'drivers/gpu/drm/ast/ast_mode.c')
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c71
1 files changed, 17 insertions, 54 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index d25852b0ce03..8ab006e6bc32 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -659,61 +659,16 @@ static u32 ast_cursor_calculate_checksum(const void *src, unsigned int width, un
return csum;
}
-static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, u8 *tmp, int width, int height)
+static void ast_set_cursor_image(struct ast_device *ast, const u8 *src,
+ unsigned int width, unsigned int height)
{
- union {
- u32 ul;
- u8 b[4];
- } srcdata32[2], data32;
- union {
- u16 us;
- u8 b[2];
- } data16;
+ u8 __iomem *dst = ast->cursor_plane.base.vaddr;
u32 csum;
- s32 alpha_dst_delta, last_alpha_dst_delta;
- u8 *dstxor;
- const u8 *srcxor;
- int i, j;
- u32 per_pixel_copy, two_pixel_copy;
- alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
- last_alpha_dst_delta = alpha_dst_delta - (width << 1);
-
- srcxor = src;
- dstxor = tmp + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
- per_pixel_copy = width & 1;
- two_pixel_copy = width >> 1;
-
- for (j = 0; j < height; j++) {
- for (i = 0; i < two_pixel_copy; i++) {
- srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
- srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
- data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
- data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
- data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
- data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
- memcpy(dstxor, &data32, 4);
-
- dstxor += 4;
- srcxor += 8;
- }
-
- for (i = 0; i < per_pixel_copy; i++) {
- srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
- data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
- data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
- memcpy(dstxor, &data16, 2);
-
- dstxor += 2;
- srcxor += 4;
- }
- dstxor += last_alpha_dst_delta;
- }
-
- csum = ast_cursor_calculate_checksum(tmp, width, height);
+ csum = ast_cursor_calculate_checksum(src, width, height);
/* write pixel data */
- memcpy_toio(dst, tmp, AST_HWC_SIZE);
+ memcpy_toio(dst, src, AST_HWC_SIZE);
/* write checksum + signature */
dst += AST_HWC_SIZE;
@@ -802,9 +757,7 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
struct drm_framebuffer *fb = plane_state->fb;
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
struct ast_device *ast = to_ast_device(plane->dev);
- struct iosys_map src_map = shadow_plane_state->data[0];
struct drm_rect damage;
- const u8 *src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
u64 dst_off = ast_plane->offset;
u8 __iomem *dst = ast_plane->vaddr; /* TODO: Use mapping abstraction properly */
u8 __iomem *sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */
@@ -818,8 +771,18 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
*/
if (drm_atomic_helper_damage_merged(old_plane_state, plane_state, &damage)) {
- ast_update_cursor_image(dst, src, ast_cursor_plane->argb4444,
- fb->width, fb->height);
+ u8 *argb4444 = ast_cursor_plane->argb4444;
+ struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
+ IOSYS_MAP_INIT_VADDR(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, &damage,
+ &shadow_plane_state->fmtcnv_state);
+ ast_set_cursor_image(ast, argb4444, fb->width, fb->height);
ast_set_cursor_base(ast, dst_off);
}