Skip to content

Commit 877691b

Browse files
marcanThomas Zimmermann
authored andcommitted
drm/format-helper: Add drm_fb_xrgb8888_to_xrgb2101010_toio()
Add XRGB8888 emulation support for devices that can only do XRGB2101010. This is chiefly useful for simpledrm on Apple devices where the bootloader-provided framebuffer is 10-bit. Signed-off-by: Hector Martin <[email protected]> Reviewed-by: Thomas Zimmermann <[email protected]> Signed-off-by: Thomas Zimmermann <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 2f92ea2 commit 877691b

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

drivers/gpu/drm/drm_format_helper.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,61 @@ void drm_fb_xrgb8888_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch,
409409
}
410410
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888_toio);
411411

412+
static void drm_fb_xrgb8888_to_xrgb2101010_line(u32 *dbuf, const u32 *sbuf,
413+
unsigned int pixels)
414+
{
415+
unsigned int x;
416+
u32 val32;
417+
418+
for (x = 0; x < pixels; x++) {
419+
val32 = ((sbuf[x] & 0x000000FF) << 2) |
420+
((sbuf[x] & 0x0000FF00) << 4) |
421+
((sbuf[x] & 0x00FF0000) << 6);
422+
*dbuf++ = val32 | ((val32 >> 8) & 0x00300C03);
423+
}
424+
}
425+
426+
/**
427+
* drm_fb_xrgb8888_to_xrgb2101010_toio - Convert XRGB8888 to XRGB2101010 clip
428+
* buffer
429+
* @dst: XRGB2101010 destination buffer (iomem)
430+
* @dst_pitch: Number of bytes between two consecutive scanlines within dst
431+
* @vaddr: XRGB8888 source buffer
432+
* @fb: DRM framebuffer
433+
* @clip: Clip rectangle area to copy
434+
*
435+
* Drivers can use this function for XRGB2101010 devices that don't natively
436+
* support XRGB8888.
437+
*/
438+
void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst,
439+
unsigned int dst_pitch, const void *vaddr,
440+
const struct drm_framebuffer *fb,
441+
const struct drm_rect *clip)
442+
{
443+
size_t linepixels = clip->x2 - clip->x1;
444+
size_t dst_len = linepixels * sizeof(u32);
445+
unsigned int y, lines = clip->y2 - clip->y1;
446+
void *dbuf;
447+
448+
if (!dst_pitch)
449+
dst_pitch = dst_len;
450+
451+
dbuf = kmalloc(dst_len, GFP_KERNEL);
452+
if (!dbuf)
453+
return;
454+
455+
vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
456+
for (y = 0; y < lines; y++) {
457+
drm_fb_xrgb8888_to_xrgb2101010_line(dbuf, vaddr, linepixels);
458+
memcpy_toio(dst, dbuf, dst_len);
459+
vaddr += fb->pitches[0];
460+
dst += dst_pitch;
461+
}
462+
463+
kfree(dbuf);
464+
}
465+
EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010_toio);
466+
412467
/**
413468
* drm_fb_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale
414469
* @dst: 8-bit grayscale destination buffer
@@ -500,6 +555,10 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for
500555
fb_format = DRM_FORMAT_XRGB8888;
501556
if (dst_format == DRM_FORMAT_ARGB8888)
502557
dst_format = DRM_FORMAT_XRGB8888;
558+
if (fb_format == DRM_FORMAT_ARGB2101010)
559+
fb_format = DRM_FORMAT_XRGB2101010;
560+
if (dst_format == DRM_FORMAT_ARGB2101010)
561+
dst_format = DRM_FORMAT_XRGB2101010;
503562

504563
if (dst_format == fb_format) {
505564
drm_fb_memcpy_toio(dst, dst_pitch, vmap, fb, clip);
@@ -515,6 +574,11 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for
515574
drm_fb_xrgb8888_to_rgb888_toio(dst, dst_pitch, vmap, fb, clip);
516575
return 0;
517576
}
577+
} else if (dst_format == DRM_FORMAT_XRGB2101010) {
578+
if (fb_format == DRM_FORMAT_XRGB8888) {
579+
drm_fb_xrgb8888_to_xrgb2101010_toio(dst, dst_pitch, vmap, fb, clip);
580+
return 0;
581+
}
518582
}
519583

520584
return -EINVAL;

include/drm/drm_format_helper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ void drm_fb_xrgb8888_to_rgb888(void *dst, unsigned int dst_pitch, const void *sr
3333
void drm_fb_xrgb8888_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch,
3434
const void *vaddr, const struct drm_framebuffer *fb,
3535
const struct drm_rect *clip);
36+
void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, unsigned int dst_pitch,
37+
const void *vaddr, const struct drm_framebuffer *fb,
38+
const struct drm_rect *clip);
3639
void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr,
3740
const struct drm_framebuffer *fb, const struct drm_rect *clip);
3841

0 commit comments

Comments
 (0)