From 7415287e1f3675996a4a6919fe500c30d30951f6 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 5 Apr 2019 11:52:15 +0200 Subject: drm: move tinydrm format conversion helpers to new drm_format_helper.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also rename them from tinydrm_* to drm_fb_* Pure code motion, no functional change. Signed-off-by: Gerd Hoffmann Reviewed-by: Sam Ravnborg Reviewed-by: Noralf Trønnes Link: http://patchwork.freedesktop.org/patch/msgid/20190405095219.9231-2-kraxel@redhat.com --- include/drm/drm_format_helper.h | 26 ++++++++++++++++++++++++++ include/drm/tinydrm/tinydrm-helpers.h | 10 ---------- 2 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 include/drm/drm_format_helper.h (limited to 'include') diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h new file mode 100644 index 000000000000..5a7ada6b0bef --- /dev/null +++ b/include/drm/drm_format_helper.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_DRM_FORMAT_HELPER_H +#define __LINUX_DRM_FORMAT_HELPER_H + +struct drm_framebuffer; +struct drm_rect; + +void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip); +void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip); +void drm_fb_xrgb8888_to_rgb565(u16 *dst, void *vaddr, + struct drm_framebuffer *fb, + struct drm_rect *clip, bool swap); +void drm_fb_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip); + +#endif /* __LINUX_DRM_FORMAT_HELPER_H */ diff --git a/include/drm/tinydrm/tinydrm-helpers.h b/include/drm/tinydrm/tinydrm-helpers.h index ae4a6abc43b5..7d259acb8826 100644 --- a/include/drm/tinydrm/tinydrm-helpers.h +++ b/include/drm/tinydrm/tinydrm-helpers.h @@ -46,16 +46,6 @@ int tinydrm_display_pipe_init(struct drm_device *drm, const struct drm_display_mode *mode, unsigned int rotation); -void tinydrm_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb, - struct drm_rect *clip); -void tinydrm_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, - struct drm_rect *clip); -void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr, - struct drm_framebuffer *fb, - struct drm_rect *clip, bool swap); -void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, - struct drm_rect *clip); - size_t tinydrm_spi_max_transfer_size(struct spi_device *spi, size_t max_len); bool tinydrm_spi_bpw_supported(struct spi_device *spi, u8 bpw); int tinydrm_spi_transfer(struct spi_device *spi, u32 speed_hz, -- cgit v1.2.3 From 26f024f54ab69a1012214755223d6ed61dd7bc98 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 5 Apr 2019 11:52:16 +0200 Subject: drm: add drm_fb_memcpy_dstclip() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is a drm_fb_memcpy() variant which checks the clip rectangle for the destination too. Common code between drm_fb_memcpy() and drm_fb_memcpy_dstclip() was factored out into the drm_fb_memcpy_lines() helper function. Signed-off-by: Gerd Hoffmann Reviewed-by: Noralf Trønnes Link: http://patchwork.freedesktop.org/patch/msgid/20190405095219.9231-3-kraxel@redhat.com --- drivers/gpu/drm/drm_format_helper.c | 51 +++++++++++++++++++++++++++++++------ include/drm/drm_format_helper.h | 2 ++ 2 files changed, 45 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 62bb4913d6f6..55a2d629a75f 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -16,30 +16,65 @@ #include #include +static void drm_fb_memcpy_lines(void *dst, unsigned int dst_pitch, + void *src, unsigned int src_pitch, + unsigned int linelength, unsigned int lines) +{ + int line; + + for (line = 0; line < lines; line++) { + memcpy(dst, src, linelength); + src += src_pitch; + dst += dst_pitch; + } +} + /** * drm_fb_memcpy - Copy clip buffer * @dst: Destination buffer * @vaddr: Source buffer * @fb: DRM framebuffer * @clip: Clip rectangle area to copy + * + * This function does not apply clipping on dst, i.e. the destination + * is a small buffer containing the clip rect only. */ void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip) { unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0); - unsigned int pitch = fb->pitches[0]; - void *src = vaddr + (clip->y1 * pitch) + (clip->x1 * cpp); + unsigned int offset = (clip->y1 * fb->pitches[0]) + (clip->x1 * cpp); size_t len = (clip->x2 - clip->x1) * cpp; - unsigned int y; - for (y = clip->y1; y < clip->y2; y++) { - memcpy(dst, src, len); - src += pitch; - dst += len; - } + drm_fb_memcpy_lines(dst, len, + vaddr + offset, fb->pitches[0], + len, clip->y2 - clip->y1); } EXPORT_SYMBOL(drm_fb_memcpy); +/** + * drm_fb_memcpy_dstclip - Copy clip buffer + * @dst: Destination buffer + * @vaddr: Source buffer + * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy + * + * This function applies clipping on dst, i.e. the destination is a + * full framebuffer but only the clip rect content is copied over. + */ +void drm_fb_memcpy_dstclip(void *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip) +{ + unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0); + unsigned int offset = (clip->y1 * fb->pitches[0]) + (clip->x1 * cpp); + size_t len = (clip->x2 - clip->x1) * cpp; + + drm_fb_memcpy_lines(dst + offset, fb->pitches[0], + vaddr + offset, fb->pitches[0], + len, clip->y2 - clip->y1); +} +EXPORT_SYMBOL(drm_fb_memcpy_dstclip); + /** * drm_fb_swab16 - Swap bytes into clip buffer * @dst: RGB565 destination buffer diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 5a7ada6b0bef..c52b7b9a25f0 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -15,6 +15,8 @@ struct drm_rect; void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip); +void drm_fb_memcpy_dstclip(void *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip); void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip); void drm_fb_xrgb8888_to_rgb565(u16 *dst, void *vaddr, -- cgit v1.2.3 From bcc4442008aca0e1566b7367f51670143d1ea7bf Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 5 Apr 2019 11:52:17 +0200 Subject: drm: add drm_fb_xrgb8888_to_rgb565_dstclip() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is a drm_fb_xrgb8888_to_rgb565() variant which checks the clip rectangle for the destination too. Common code between drm_fb_xrgb8888_to_rgb565() and drm_fb_xrgb8888_to_rgb565_dstclip() was factored out into the drm_fb_xrgb8888_to_rgb565_lines() helper function. Signed-off-by: Gerd Hoffmann Reviewed-by: Noralf Trønnes Link: http://patchwork.freedesktop.org/patch/msgid/20190405095219.9231-4-kraxel@redhat.com --- drivers/gpu/drm/drm_format_helper.c | 111 ++++++++++++++++++++++++++---------- include/drm/drm_format_helper.h | 5 +- 2 files changed, 85 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 55a2d629a75f..246775510c2e 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -110,6 +110,44 @@ void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, } EXPORT_SYMBOL(drm_fb_swab16); +static void drm_fb_xrgb8888_to_rgb565_lines(void *dst, unsigned int dst_pitch, + void *src, unsigned int src_pitch, + unsigned int src_linelength, + unsigned int lines, + bool swap) +{ + unsigned int linepixels = src_linelength / sizeof(u32); + unsigned int x, y; + u32 *sbuf; + u16 *dbuf, val16; + + /* + * The cma memory is write-combined so reads are uncached. + * Speed up by fetching one line at a time. + */ + sbuf = kmalloc(src_linelength, GFP_KERNEL); + if (!sbuf) + return; + + for (y = 0; y < lines; y++) { + memcpy(sbuf, src, src_linelength); + dbuf = dst; + for (x = 0; x < linepixels; x++) { + val16 = ((sbuf[x] & 0x00F80000) >> 8) | + ((sbuf[x] & 0x0000FC00) >> 5) | + ((sbuf[x] & 0x000000F8) >> 3); + if (swap) + *dbuf++ = swab16(val16); + else + *dbuf++ = val16; + } + src += src_pitch; + dst += dst_pitch; + } + + kfree(sbuf); +} + /** * drm_fb_xrgb8888_to_rgb565 - Convert XRGB8888 to RGB565 clip buffer * @dst: RGB565 destination buffer @@ -120,44 +158,57 @@ EXPORT_SYMBOL(drm_fb_swab16); * * Drivers can use this function for RGB565 devices that don't natively * support XRGB8888. + * + * This function does not apply clipping on dst, i.e. the destination + * is a small buffer containing the clip rect only. */ -void drm_fb_xrgb8888_to_rgb565(u16 *dst, void *vaddr, +void drm_fb_xrgb8888_to_rgb565(void *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip, bool swap) { - size_t len = (clip->x2 - clip->x1) * sizeof(u32); - unsigned int x, y; - u32 *src, *buf; - u16 val16; + unsigned int src_offset = (clip->y1 * fb->pitches[0]) + + (clip->x1 * sizeof(u32)); + size_t src_len = (clip->x2 - clip->x1) * sizeof(u32); + size_t dst_len = (clip->x2 - clip->x1) * sizeof(u16); - /* - * 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; + drm_fb_xrgb8888_to_rgb565_lines(dst, dst_len, + vaddr + src_offset, fb->pitches[0], + src_len, clip->y2 - clip->y1, + swap); +} +EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); - for (y = clip->y1; y < clip->y2; y++) { - src = vaddr + (y * fb->pitches[0]); - src += clip->x1; - memcpy(buf, src, len); - src = buf; - for (x = clip->x1; x < clip->x2; x++) { - val16 = ((*src & 0x00F80000) >> 8) | - ((*src & 0x0000FC00) >> 5) | - ((*src & 0x000000F8) >> 3); - src++; - if (swap) - *dst++ = swab16(val16); - else - *dst++ = val16; - } - } +/** + * drm_fb_xrgb8888_to_rgb565_dstclip - Convert XRGB8888 to RGB565 clip buffer + * @dst: RGB565 destination buffer + * @dst_pitch: destination buffer pitch + * @vaddr: XRGB8888 source buffer + * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy + * @swap: Swap bytes + * + * Drivers can use this function for RGB565 devices that don't natively + * support XRGB8888. + * + * This function applies clipping on dst, i.e. the destination is a + * full framebuffer but only the clip rect content is copied over. + */ +void drm_fb_xrgb8888_to_rgb565_dstclip(void *dst, unsigned int dst_pitch, + void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip, bool swap) +{ + unsigned int src_offset = (clip->y1 * fb->pitches[0]) + + (clip->x1 * sizeof(u32)); + unsigned int dst_offset = (clip->y1 * dst_pitch) + + (clip->x1 * sizeof(u16)); + size_t src_len = (clip->x2 - clip->x1) * sizeof(u32); - kfree(buf); + drm_fb_xrgb8888_to_rgb565_lines(dst + dst_offset, dst_pitch, + vaddr + src_offset, fb->pitches[0], + src_len, clip->y2 - clip->y1, + swap); } -EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); +EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565_dstclip); /** * drm_fb_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index c52b7b9a25f0..a84d71fa446b 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -19,9 +19,12 @@ void drm_fb_memcpy_dstclip(void *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip); void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip); -void drm_fb_xrgb8888_to_rgb565(u16 *dst, void *vaddr, +void drm_fb_xrgb8888_to_rgb565(void *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip, bool swap); +void drm_fb_xrgb8888_to_rgb565_dstclip(void *dst, unsigned int dst_pitch, + void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip, bool swap); void drm_fb_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip); -- cgit v1.2.3 From ec3de7a43e9cac8a2dc1fce069321cb9538f0b34 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 5 Apr 2019 11:52:18 +0200 Subject: drm: add drm_fb_xrgb8888_to_rgb888_dstclip() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simliar to drm_fb_xrgb8888_to_rgb565_dstclip() but converts to rgb888 instead of rgb565. Signed-off-by: Gerd Hoffmann Reviewed-by: Noralf Trønnes Link: http://patchwork.freedesktop.org/patch/msgid/20190405095219.9231-5-kraxel@redhat.com --- drivers/gpu/drm/drm_format_helper.c | 60 +++++++++++++++++++++++++++++++++++++ include/drm/drm_format_helper.h | 3 ++ 2 files changed, 63 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 246775510c2e..00d716f14173 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -210,6 +210,66 @@ void drm_fb_xrgb8888_to_rgb565_dstclip(void *dst, unsigned int dst_pitch, } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565_dstclip); +static void drm_fb_xrgb8888_to_rgb888_lines(void *dst, unsigned int dst_pitch, + void *src, unsigned int src_pitch, + unsigned int src_linelength, + unsigned int lines) +{ + unsigned int linepixels = src_linelength / 3; + unsigned int x, y; + u32 *sbuf; + u8 *dbuf; + + sbuf = kmalloc(src_linelength, GFP_KERNEL); + if (!sbuf) + return; + + for (y = 0; y < lines; y++) { + memcpy(sbuf, src, src_linelength); + dbuf = dst; + for (x = 0; x < linepixels; x++) { + *dbuf++ = (sbuf[x] & 0x000000FF) >> 0; + *dbuf++ = (sbuf[x] & 0x0000FF00) >> 8; + *dbuf++ = (sbuf[x] & 0x00FF0000) >> 16; + } + src += src_pitch; + dst += dst_pitch; + } + + kfree(sbuf); +} + +/** + * drm_fb_xrgb8888_to_rgb888_dstclip - Convert XRGB8888 to RGB888 clip buffer + * @dst: RGB565 destination buffer + * @dst_pitch: destination buffer pitch + * @vaddr: XRGB8888 source buffer + * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy + * @dstclip: Clip destination too. + * + * Drivers can use this function for RGB888 devices that don't natively + * support XRGB8888. + * + * This function applies clipping on dst, i.e. the destination is a + * full framebuffer but only the clip rect content is copied over. + */ +void drm_fb_xrgb8888_to_rgb888_dstclip(void *dst, unsigned int dst_pitch, + void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip) +{ + unsigned int src_offset = (clip->y1 * fb->pitches[0]) + + (clip->x1 * sizeof(u32)); + unsigned int dst_offset = (clip->y1 * dst_pitch) + + (clip->x1 * 3); + size_t src_len = (clip->x2 - clip->x1) * sizeof(u32); + + drm_fb_xrgb8888_to_rgb888_lines(dst + dst_offset, dst_pitch, + vaddr + src_offset, fb->pitches[0], + src_len, clip->y2 - clip->y1); +} +EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888_dstclip); + /** * drm_fb_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale * @dst: 8-bit grayscale destination buffer diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index a84d71fa446b..6f84380757ee 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -25,6 +25,9 @@ void drm_fb_xrgb8888_to_rgb565(void *dst, void *vaddr, void drm_fb_xrgb8888_to_rgb565_dstclip(void *dst, unsigned int dst_pitch, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip, bool swap); +void drm_fb_xrgb8888_to_rgb888_dstclip(void *dst, unsigned int dst_pitch, + void *vaddr, struct drm_framebuffer *fb, + struct drm_rect *clip); void drm_fb_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_rect *clip); -- cgit v1.2.3