Good morning,

On Thu, 11 Dec 2025 08:22:12 +0100, Thomas Zimmermann <[email protected]> 
wrote:

> Hi
> 
> Am 10.12.25 um 17:56 schrieb René Rebe:
> > Hi,
> >
> > On Wed, 10 Dec 2025 16:41:50 +0100, Thomas Zimmermann
> > <[email protected]> wrote:
> >
> >> Hi
> >>
> >> Am 10.12.25 um 16:33 schrieb René Rebe:
> >>> Hallo,
> >>>
> >>> On Wed, 10 Dec 2025 09:55:50 +0100, Thomas Zimmermann
> >>> <[email protected]> wrote:
> >>> ...
> >>>>>> Does that fix the color corruption?
> >>>>> Following your suggestions conversion does not want to just work:
> >>>>>
> >>>>> root@XCODE_SPARC_T4_1:~# dmesg  | tail
> >>>>> [  105.444761] ast 0000:0a:00.0: AST 2200 detected
> >>>>> [ 105.444947] ast 0000:0a:00.0: [drm] dram MCLK=266 Mhz type=2
> >>>>> bus_width=32
> >>>>> [  105.444963] ast 0000:0a:00.0: [drm] Using analog VGA
> >>>>> [  105.445470] [drm] Initialized ast 0.1.0 for 0000:0a:00.0 on minor 0
> >>>>> [ 105.673289] ast 0000:0a:00.0: [drm] format BX24 little-endian
> >>>>> (0x34325842) not supported
> >>>>> [  105.673302] ast 0000:0a:00.0: [drm] No compatible format found
> >>>>> [ 105.673348] ast 0000:0a:00.0: [drm] *ERROR* fbdev: Failed to setup
> >>>>> emulation (ret=-22)
> >>>>> [ 105.901306] ast 0000:0a:00.0: [drm] format BX24 little-endian
> >>>>> (0x34325842) not supported
> >>>>> [  105.901319] ast 0000:0a:00.0: [drm] No compatible format found
> >>>>> [ 105.901350] ast 0000:0a:00.0: [drm] *ERROR* fbdev: Failed to setup
> >>>>> emulation (ret=-22)
> >>>> Oh well...
> >>>>
> >>>> There's a very simple patch attach. Does it fix the problem?
> >>> Yes, only leaving the hardcoded swapping from my patch liek this fixes
> >>> the byte-swapped output as expected on the sparc64 Sun T4.
> >> Great.
> >>
> >>> How would you like me to go from here? Just use the chip_id to force
> >>> swapping and enable hw swapper for pre-AST2400 chips or fix the
> >>> generic format selection to work as you had suggested?
> >>>
> >>> Does the ast_primary_plane_formats need to byte swapped formats for it
> >>> to work?
> >> I'll send out a full patch that implements the byte swapping. Once
> >> reviewed, it can be merged quickly. Can I add your Tested-by tag to
> >> the patch?
> > I'd be happy to finish my work.
> 
> Of course, no problem.
> 
> The code for the primary plane should be fine now. But we also need
> something for the cursor plane as well. There's a
> ast_set_cursor_image() with a memcpy_toio() [1] and several additional
> writes. IIUC they all have to be swapped as well.

Of course, any obvious style issue or endianess swapping linux-kernel
would like to see differently? You did not answer if I should just
conditionalize on the chip id. I used a bool to avoid intermangled
#ifdef conditionals to hopefully match kernel style.
Btw. checkpatch.pl warns:

WARNING: Missing or malformed SPDX-License-Identifier tag in line 1

I could add this if desired while at it.

Only compile tested, will do a final hw test once patch is approved in
general.

Thanks!
        René
---
 drivers/gpu/drm/ast/ast_cursor.c | 20 +++++++++++++++++-
 drivers/gpu/drm/ast/ast_mode.c   | 35 +++++++++++++++++++++++++++++---
 drivers/gpu/drm/ast/ast_reg.h    |  2 ++
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
index 2d3ad7610c2e..a16745cff83e 100644
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ b/drivers/gpu/drm/ast/ast_cursor.c
@@ -92,12 +92,30 @@ static void ast_set_cursor_image(struct ast_device *ast, 
const u8 *src,
                                 unsigned int width, unsigned int height)
 {
        u8 __iomem *dst = ast_plane_vaddr(&ast->cursor_plane.base);
+       bool sw_swab = false;
+       int i;
        u32 csum;
 
        csum = ast_cursor_calculate_checksum(src, width, height);
 
+#ifdef __BIG_ENDIAN
+       /* HW swap bytes on big-endian formats, if possible */
+       if (ast->chip < AST2400)
+               ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa2, 0x3f, 
AST_IO_VGACRA2_BE_MODE_16);
+       else
+               sw_swab = true;
+#endif
+
        /* write pixel data */
-       memcpy_toio(dst, src, AST_HWC_SIZE);
+       if (!sw_swab)
+               memcpy_toio(dst, src, AST_HWC_SIZE);
+       else {
+               for (i = 0; i < AST_HWC_SIZE / 2; i += 2) {
+                       const u16 *src16 = (const u16 *)(src + i);
+
+                       writel(*src16, dst + i);
+               }
+       }
 
        /* write checksum + signature */
        dst += AST_HWC_SIZE;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index cd08990a10f9..9a18f0dc1a99 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -526,12 +526,24 @@ static int ast_primary_plane_helper_atomic_check(struct 
drm_plane *plane,
 
 static void ast_handle_damage(struct ast_plane *ast_plane, struct iosys_map 
*src,
                              struct drm_framebuffer *fb,
-                             const struct drm_rect *clip)
+                             const struct drm_rect *clip,
+                             struct drm_format_conv_state *fmtcnv_state)
 {
        struct iosys_map dst = 
IOSYS_MAP_INIT_VADDR_IOMEM(ast_plane_vaddr(ast_plane));
+       bool sw_swab = false;
 
        iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, 
clip));
-       drm_fb_memcpy(&dst, fb->pitches, src, fb, clip);
+
+#ifdef __BIG_ENDIAN
+       /* Swap bytes on big-endian formats */
+       if (ast->chip >= AST2400)
+               sw_swab = true;
+#endif
+
+       if (sw_swab)
+               drm_fb_swab(&dst, fb->pitches, src, fb, clip, false, 
fmtcnv_state);
+       else
+               drm_fb_memcpy(&dst, fb->pitches, src, fb, clip);
 }
 
 static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
@@ -559,9 +571,26 @@ static void ast_primary_plane_helper_atomic_update(struct 
drm_plane *plane,
 
        /* if the buffer comes from another device */
        if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE) == 0) {
+#ifdef __BIG_ENDIAN
+               /* HW swap bytes on big-endian formats, if possible */
+               if (ast->chip < AST2400) {
+                       switch (fb->format->format) {
+                       case DRM_FORMAT_RGB565:
+                               ast_set_index_reg_mask(ast, AST_IO_VGACRI, 
0xa2, 0x3f,
+                                                      
AST_IO_VGACRA2_BE_MODE_16);
+                               break;
+                       case DRM_FORMAT_XRGB8888:
+                               ast_set_index_reg_mask(ast, AST_IO_VGACRI, 
0xa2, 0x3f,
+                                                      AST_IO_VGACRA2_BE_MODE);
+                               break;
+                       }
+               }
+#endif
+
                drm_atomic_helper_damage_iter_init(&iter, old_plane_state, 
plane_state);
                drm_atomic_for_each_plane_damage(&iter, &damage) {
-                       ast_handle_damage(ast_plane, shadow_plane_state->data, 
fb, &damage);
+                       ast_handle_damage(ast_plane, shadow_plane_state->data, 
fb, &damage,
+                                         &shadow_plane_state->fmtcnv_state);
                }
 
                drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h
index 30578e3b07e4..bcd39d7438b9 100644
--- a/drivers/gpu/drm/ast/ast_reg.h
+++ b/drivers/gpu/drm/ast/ast_reg.h
@@ -34,6 +34,8 @@
 #define AST_IO_VGACR99_VGAMEM_RSRV_MASK        GENMASK(1, 0)
 #define AST_IO_VGACRA1_VGAIO_DISABLED  BIT(1)
 #define AST_IO_VGACRA1_MMIO_ENABLED    BIT(2)
+#define AST_IO_VGACRA2_BE_MODE         BIT(7)
+#define AST_IO_VGACRA2_BE_MODE_16      (BIT(7) | BIT(6))
 #define AST_IO_VGACRA3_DVO_ENABLED     BIT(7)
 #define AST_IO_VGACRAA_VGAMEM_SIZE_MASK        GENMASK(1, 0)
 #define AST_IO_VGACRB6_HSYNC_OFF       BIT(0)
-- 
2.52.0



> [1]
> https://gitlab.freedesktop.org/drm/misc/kernel/-/blob/drm-misc-next/drivers/gpu/drm/ast/ast_cursor.c#L101
> 
> Best regards
> Thomas

-- 
René Rebe, ExactCODE GmbH, Berlin, Germany
https://exactco.dehttps://t2linux.comhttps://patreon.com/renerebe

Reply via email to