Commit bd34cea2 authored by Noralf Trønnes's avatar Noralf Trønnes

drm/format-helper: Add drm_fb_swab()

This replaces drm_fb_swab16() with drm_fb_swab() supporting 16 and 32-bit.
Also make pixel line caching optional.

v2:
- Bail out on cpp != 2 && 4 (Sam)
Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200509141619.32970-8-noralf@tronnes.org
parent 64593f2a
...@@ -79,39 +79,60 @@ void drm_fb_memcpy_dstclip(void __iomem *dst, void *vaddr, ...@@ -79,39 +79,60 @@ void drm_fb_memcpy_dstclip(void __iomem *dst, void *vaddr,
EXPORT_SYMBOL(drm_fb_memcpy_dstclip); EXPORT_SYMBOL(drm_fb_memcpy_dstclip);
/** /**
* drm_fb_swab16 - Swap bytes into clip buffer * drm_fb_swab - Swap bytes into clip buffer
* @dst: RGB565 destination buffer * @dst: Destination buffer
* @vaddr: RGB565 source buffer * @src: Source buffer
* @fb: DRM framebuffer * @fb: DRM framebuffer
* @clip: Clip rectangle area to copy * @clip: Clip rectangle area to copy
* @cached: Source buffer is mapped cached (eg. not write-combined)
*
* If @cached is false a temporary buffer is used to cache one pixel line at a
* time to speed up slow uncached reads.
*
* This function does not apply clipping on dst, i.e. the destination
* is a small buffer containing the clip rect only.
*/ */
void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, void drm_fb_swab(void *dst, void *src, struct drm_framebuffer *fb,
struct drm_rect *clip) struct drm_rect *clip, bool cached)
{ {
size_t len = (clip->x2 - clip->x1) * sizeof(u16); u8 cpp = fb->format->cpp[0];
size_t len = drm_rect_width(clip) * cpp;
u16 *src16, *dst16 = dst;
u32 *src32, *dst32 = dst;
unsigned int x, y; unsigned int x, y;
u16 *src, *buf; void *buf = NULL;
/* if (WARN_ON_ONCE(cpp != 2 && cpp != 4))
* The cma memory is write-combined so reads are uncached.
* Speed up by fetching one line at a time.
*/
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return; return;
if (!cached)
buf = kmalloc(len, GFP_KERNEL);
src += clip_offset(clip, fb->pitches[0], cpp);
for (y = clip->y1; y < clip->y2; y++) { for (y = clip->y1; y < clip->y2; y++) {
src = vaddr + (y * fb->pitches[0]); if (buf) {
src += clip->x1;
memcpy(buf, src, len); memcpy(buf, src, len);
src = buf; src16 = buf;
for (x = clip->x1; x < clip->x2; x++) src32 = buf;
*dst++ = swab16(*src++); } else {
src16 = src;
src32 = src;
}
for (x = clip->x1; x < clip->x2; x++) {
if (cpp == 4)
*dst32++ = swab32(*src32++);
else
*dst16++ = swab16(*src16++);
}
src += fb->pitches[0];
} }
kfree(buf); kfree(buf);
} }
EXPORT_SYMBOL(drm_fb_swab16); EXPORT_SYMBOL(drm_fb_swab);
static void drm_fb_xrgb8888_to_rgb565_line(u16 *dbuf, u32 *sbuf, static void drm_fb_xrgb8888_to_rgb565_line(u16 *dbuf, u32 *sbuf,
unsigned int pixels, unsigned int pixels,
......
...@@ -217,7 +217,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, ...@@ -217,7 +217,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
switch (fb->format->format) { switch (fb->format->format) {
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
if (swap) if (swap)
drm_fb_swab16(dst, src, fb, clip); drm_fb_swab(dst, src, fb, clip, !import_attach);
else else
drm_fb_memcpy(dst, src, fb, clip); drm_fb_memcpy(dst, src, fb, clip);
break; break;
......
...@@ -14,8 +14,8 @@ void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb, ...@@ -14,8 +14,8 @@ void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
void drm_fb_memcpy_dstclip(void __iomem *dst, void *vaddr, void drm_fb_memcpy_dstclip(void __iomem *dst, void *vaddr,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_rect *clip); struct drm_rect *clip);
void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, void drm_fb_swab(void *dst, void *src, struct drm_framebuffer *fb,
struct drm_rect *clip); struct drm_rect *clip, bool cached);
void drm_fb_xrgb8888_to_rgb565(void *dst, void *vaddr, void drm_fb_xrgb8888_to_rgb565(void *dst, void *vaddr,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_rect *clip, bool swab); struct drm_rect *clip, bool swab);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment