Skip to content

Commit 8ad00a8

Browse files
committed
drm/format-helper: Split off byte swapping from drm_fb_xrgb8888_to_rgb565()
Move big-endian support from drm_fb_xrgb8888_to_rgb565() into the new helper drm_xrgb8888_to_rgb565be(). The functionality is required for displays with big-endian byte order. Update all callers. With the change applied, drm_fb_xrgb8888_to_rgb565() has the same signature as the other conversion functions, which is required for further updates to drm_fb_blit(). Also makes the format-conversion helper available to panic handlers, if necessary. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://lore.kernel.org/r/20250625114911.1121301-1-tzimmermann@suse.de
1 parent b462b0e commit 8ad00a8

File tree

6 files changed

+71
-32
lines changed

6 files changed

+71
-32
lines changed

drivers/gpu/drm/drm_format_helper.c

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -559,18 +559,6 @@ static void drm_fb_xrgb8888_to_rgb565_line(void *dbuf, const void *sbuf, unsigne
559559
drm_fb_xfrm_line_32to16(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_rgb565);
560560
}
561561

562-
static __always_inline u32 drm_xrgb8888_to_rgb565_swab(u32 pix)
563-
{
564-
return swab16(drm_pixel_xrgb8888_to_rgb565(pix));
565-
}
566-
567-
/* TODO: implement this helper as conversion to RGB565|BIG_ENDIAN */
568-
static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf,
569-
unsigned int pixels)
570-
{
571-
drm_fb_xfrm_line_32to16(dbuf, sbuf, pixels, drm_xrgb8888_to_rgb565_swab);
572-
}
573-
574562
/**
575563
* drm_fb_xrgb8888_to_rgb565 - Convert XRGB8888 to RGB565 clip buffer
576564
* @dst: Array of RGB565 destination buffers
@@ -580,7 +568,6 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf,
580568
* @fb: DRM framebuffer
581569
* @clip: Clip rectangle area to copy
582570
* @state: Transform and conversion state
583-
* @swab: Swap bytes
584571
*
585572
* This function copies parts of a framebuffer to display memory and converts the
586573
* color format during the process. Destination and framebuffer formats must match. The
@@ -595,23 +582,56 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf,
595582
*/
596583
void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch,
597584
const struct iosys_map *src, const struct drm_framebuffer *fb,
598-
const struct drm_rect *clip, struct drm_format_conv_state *state,
599-
bool swab)
585+
const struct drm_rect *clip, struct drm_format_conv_state *state)
600586
{
601587
static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
602588
2,
603589
};
604590

605-
void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels);
591+
drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
592+
drm_fb_xrgb8888_to_rgb565_line);
593+
}
594+
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565);
595+
596+
static void drm_fb_xrgb8888_to_rgb565be_line(void *dbuf, const void *sbuf,
597+
unsigned int pixels)
598+
{
599+
drm_fb_xfrm_line_32to16(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_rgb565be);
600+
}
606601

607-
if (swab)
608-
xfrm_line = drm_fb_xrgb8888_to_rgb565_swab_line;
609-
else
610-
xfrm_line = drm_fb_xrgb8888_to_rgb565_line;
602+
/**
603+
* drm_fb_xrgb8888_to_rgb565be - Convert XRGB8888 to RGB565|DRM_FORMAT_BIG_ENDIAN clip buffer
604+
* @dst: Array of RGB565BE destination buffers
605+
* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines
606+
* within @dst; can be NULL if scanlines are stored next to each other.
607+
* @src: Array of XRGB8888 source buffer
608+
* @fb: DRM framebuffer
609+
* @clip: Clip rectangle area to copy
610+
* @state: Transform and conversion state
611+
*
612+
* This function copies parts of a framebuffer to display memory and converts the
613+
* color format during the process. Destination and framebuffer formats must match. The
614+
* parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at
615+
* least as many entries as there are planes in @fb's format. Each entry stores the
616+
* value for the format's respective color plane at the same index.
617+
*
618+
* This function does not apply clipping on @dst (i.e. the destination is at the
619+
* top-left corner).
620+
*
621+
* Drivers can use this function for RGB565BE devices that don't support XRGB8888 natively.
622+
*/
623+
void drm_fb_xrgb8888_to_rgb565be(struct iosys_map *dst, const unsigned int *dst_pitch,
624+
const struct iosys_map *src, const struct drm_framebuffer *fb,
625+
const struct drm_rect *clip, struct drm_format_conv_state *state)
626+
{
627+
static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
628+
2,
629+
};
611630

612-
drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, xfrm_line);
631+
drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
632+
drm_fb_xrgb8888_to_rgb565be_line);
613633
}
614-
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565);
634+
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565be);
615635

616636
static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsigned int pixels)
617637
{
@@ -1188,7 +1208,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d
11881208
return 0;
11891209
} else if (fb_format == DRM_FORMAT_XRGB8888) {
11901210
if (dst_format == DRM_FORMAT_RGB565) {
1191-
drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, state, false);
1211+
drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, state);
11921212
return 0;
11931213
} else if (dst_format == DRM_FORMAT_XRGB1555) {
11941214
drm_fb_xrgb8888_to_xrgb1555(dst, dst_pitch, src, fb, clip, state);

drivers/gpu/drm/drm_format_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <linux/bits.h>
77
#include <linux/types.h>
8+
#include <linux/swab.h>
89

910
/*
1011
* Each pixel-format conversion helper takes a raw pixel in a
@@ -59,6 +60,11 @@ static inline u32 drm_pixel_xrgb8888_to_rgb565(u32 pix)
5960
((pix & 0x000000f8) >> 3);
6061
}
6162

63+
static inline u32 drm_pixel_xrgb8888_to_rgb565be(u32 pix)
64+
{
65+
return swab16(drm_pixel_xrgb8888_to_rgb565(pix));
66+
}
67+
6268
static inline u32 drm_pixel_xrgb8888_to_rgbx5551(u32 pix)
6369
{
6470
return ((pix & 0x00f80000) >> 8) |

drivers/gpu/drm/drm_mipi_dbi.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,13 @@ int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *
230230
case DRM_FORMAT_XRGB8888:
231231
switch (dbidev->pixel_format) {
232232
case DRM_FORMAT_RGB565:
233-
drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip, fmtcnv_state, swap);
233+
if (swap) {
234+
drm_fb_xrgb8888_to_rgb565be(&dst_map, NULL, src, fb, clip,
235+
fmtcnv_state);
236+
} else {
237+
drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip,
238+
fmtcnv_state);
239+
}
234240
break;
235241
case DRM_FORMAT_RGB888:
236242
drm_fb_xrgb8888_to_rgb888(&dst_map, NULL, src, fb, clip, fmtcnv_state);

drivers/gpu/drm/gud/gud_pipe.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,13 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb,
188188
} else if (format->format == DRM_FORMAT_RGB332) {
189189
drm_fb_xrgb8888_to_rgb332(&dst, NULL, src, fb, rect, fmtcnv_state);
190190
} else if (format->format == DRM_FORMAT_RGB565) {
191-
drm_fb_xrgb8888_to_rgb565(&dst, NULL, src, fb, rect, fmtcnv_state,
192-
gud_is_big_endian());
191+
if (gud_is_big_endian()) {
192+
drm_fb_xrgb8888_to_rgb565be(&dst, NULL, src, fb, rect,
193+
fmtcnv_state);
194+
} else {
195+
drm_fb_xrgb8888_to_rgb565(&dst, NULL, src, fb, rect,
196+
fmtcnv_state);
197+
}
193198
} else if (format->format == DRM_FORMAT_RGB888) {
194199
drm_fb_xrgb8888_to_rgb888(&dst, NULL, src, fb, rect, fmtcnv_state);
195200
} else {

drivers/gpu/drm/tests/drm_format_helper_test.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -735,21 +735,21 @@ static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
735735
NULL : &result->dst_pitch;
736736

737737
drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, &params->clip,
738-
&fmtcnv_state, false);
738+
&fmtcnv_state);
739739
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
740740
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
741741

742742
buf = dst.vaddr; /* restore original value of buf */
743-
drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, &params->clip,
744-
&fmtcnv_state, true);
743+
drm_fb_xrgb8888_to_rgb565be(&dst, &result->dst_pitch, &src, &fb, &params->clip,
744+
&fmtcnv_state);
745745
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
746746
KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
747747

748748
buf = dst.vaddr;
749749
memset(buf, 0, dst_size);
750750

751751
drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, &params->clip,
752-
&fmtcnv_state, false);
752+
&fmtcnv_state);
753753
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
754754
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
755755
}

include/drm/drm_format_helper.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pi
8282
const struct drm_rect *clip, struct drm_format_conv_state *state);
8383
void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch,
8484
const struct iosys_map *src, const struct drm_framebuffer *fb,
85-
const struct drm_rect *clip, struct drm_format_conv_state *state,
86-
bool swab);
85+
const struct drm_rect *clip, struct drm_format_conv_state *state);
86+
void drm_fb_xrgb8888_to_rgb565be(struct iosys_map *dst, const unsigned int *dst_pitch,
87+
const struct iosys_map *src, const struct drm_framebuffer *fb,
88+
const struct drm_rect *clip, struct drm_format_conv_state *state);
8789
void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_pitch,
8890
const struct iosys_map *src, const struct drm_framebuffer *fb,
8991
const struct drm_rect *clip, struct drm_format_conv_state *state);

0 commit comments

Comments
 (0)