Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 00/14] drm/format-helper: Move to struct iosys_map
Change format-conversion helpers to use struct iosys_map for source and destination buffers. Update all users. Also prepare interface for multi-plane color formats. The format-conversion helpers mostly used to convert to I/O memory or system memory. To actual memory type depended on the usecase. We now have drivers upcomming that do the conversion entirely in system memory. It's a good opportunity to stream-line the interface of the conversion helpers to use struct iosys_map. Source and destination buffers can now be either in system or in I/O memory. Note that the implementation still only supports source buffers in system memory. This patchset also changes the interface to support multi-plane color formats, where the values for each component are stored in distinct memory locations. Converting from RGBRGBRGB to RRRGGGBBB would require a single source buffer with RGB values and 3 destination buffers for the R, G and B values. Conversion-helper interfaces now support this. v2: * add IOSYS_MAP_INIT_VADDR_IOMEM (Sam) * use drm_format_info_bpp() (Sam) * update documentation (Sam) * rename 'vmap' to 'src' (Sam) * many smaller cleanups and fixes (Sam, Jose) Thomas Zimmermann (14): iosys-map: Add IOSYS_MAP_INIT_VADDR_IOMEM() drm/format-helper: Provide drm_fb_blit() drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() drm/format-helper: Convert drm_fb_swab() to struct iosys_map drm/format-helper: Rework XRGB8888-to-RGBG332 conversion drm/format-helper: Rework XRGB8888-to-RGBG565 conversion drm/format-helper: Rework XRGB8888-to-RGB888 conversion drm/format-helper: Rework RGB565-to-XRGB8888 conversion drm/format-helper: Rework RGB888-to-XRGB8888 conversion drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion drm/format-helper: Rework XRGB8888-to-GRAY8 conversion drm/format-helper: Rework XRGB8888-to-MONO conversion drm/format-helper: Move destination-buffer handling into internal helper drm/format-helper: Rename parameter vmap to src drivers/gpu/drm/drm_format_helper.c | 509 ++++++++++-------- drivers/gpu/drm/drm_mipi_dbi.c | 9 +- drivers/gpu/drm/gud/gud_pipe.c | 20 +- drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 9 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 9 +- drivers/gpu/drm/solomon/ssd130x.c | 7 +- .../gpu/drm/tests/drm_format_helper_test.c | 45 +- drivers/gpu/drm/tiny/cirrus.c | 19 +- drivers/gpu/drm/tiny/repaper.c | 6 +- drivers/gpu/drm/tiny/simpledrm.c | 8 +- drivers/gpu/drm/tiny/st7586.c | 5 +- include/drm/drm_format_helper.h | 56 +- include/linux/iosys-map.h | 15 +- 13 files changed, 416 insertions(+), 301 deletions(-) base-commit: 2bdae66c9988dd0f07633629c0a85383cfc05940 prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24 prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6 -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 01/14] iosys-map: Add IOSYS_MAP_INIT_VADDR_IOMEM()
Add IOSYS_MAP_INIT_VADDR_IOMEM() for static init of variables of type struct iosys_map. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- include/linux/iosys-map.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h index a533cae189d7..cb71aa616bd3 100644 --- a/include/linux/iosys-map.h +++ b/include/linux/iosys-map.h @@ -46,10 +46,13 @@ * * iosys_map_set_vaddr(&map, 0xdeadbeaf); * - * To set an address in I/O memory, use iosys_map_set_vaddr_iomem(). + * To set an address in I/O memory, use IOSYS_MAP_INIT_VADDR_IOMEM() or + * iosys_map_set_vaddr_iomem(). * * .. code-block:: c * + * struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(0xdeadbeaf); + * * iosys_map_set_vaddr_iomem(&map, 0xdeadbeaf); * * Instances of struct iosys_map do not have to be cleaned up, but @@ -121,6 +124,16 @@ struct iosys_map { .is_iomem = false, \ } +/** + * IOSYS_MAP_INIT_VADDR_IOMEM - Initializes struct iosys_map to an address in I/O memory + * @vaddr_iomem_: An I/O-memory address + */ +#define IOSYS_MAP_INIT_VADDR_IOMEM(vaddr_iomem_) \ + { \ + .vaddr_iomem = (vaddr_iomem_), \ + .is_iomem = true, \ + } + /** * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map * @map_: The dma-buf mapping structure to copy from -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 02/14] drm/format-helper: Provide drm_fb_blit()
Provide drm_fb_blit() that works with struct iosys_map. Update all users of drm_fb_blit_toio(), which required a destination buffer in I/O memory. This patch only updates the function's interface. The implementation still relies on the destination buffer to be located in I/O memory. See the follow-up patches for implementational changes. The new function's interface works with multi-plane color formats, but again implementation only supports a single plane for now. v2: * rebase onto refactored simpledrm * use IOSYS_MAP_INIT_VADDR() (Sam) * update the commit message on the use of I/O memory (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 44 ++++++++++++++++++----------- drivers/gpu/drm/tiny/simpledrm.c | 8 +++--- include/drm/drm_format_helper.h | 7 +++-- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 400b16d9147d..07f329f607a3 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -8,9 +8,10 @@ * (at your option) any later version. */ +#include <linux/io.h> +#include <linux/iosys-map.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/io.h> #include <drm/drm_device.h> #include <drm/drm_format_helper.h> @@ -545,9 +546,10 @@ void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vad EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); /** - * drm_fb_blit_toio - Copy parts of a framebuffer to display memory - * @dst: The display memory to copy to - * @dst_pitch: Number of bytes between two consecutive scanlines within dst + * drm_fb_blit - Copy parts of a framebuffer to display memory + * @dst: Array of display-memory addresses to copy to + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. * @dst_format: FOURCC code of the display's color format * @vmap: The framebuffer memory to copy from * @fb: The framebuffer to copy from @@ -555,16 +557,22 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); * * This function copies parts of a framebuffer to display memory. If the * formats of the display and the framebuffer mismatch, the blit function - * will attempt to convert between them. + * will attempt to convert between them during the process. The parameters @dst, + * @dst_pitch and @vmap refer to arrays. Each array must have at least as many + * entries as there are planes in @dst_format's format. Each entry stores the + * value for the format's respective color plane at the same index. + * + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). * * Returns: * 0 on success, or * -EINVAL if the color-format conversion failed, or * a negative error code otherwise. */ -int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_format, - const void *vmap, const struct drm_framebuffer *fb, - const struct drm_rect *clip) +int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { uint32_t fb_format = fb->format->format; @@ -579,30 +587,35 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for dst_format = DRM_FORMAT_XRGB2101010; if (dst_format == fb_format) { - drm_fb_memcpy_toio(dst, dst_pitch, vmap, fb, clip); + drm_fb_memcpy_toio(dst[0].vaddr_iomem, dst_pitch[0], vmap[0].vaddr, fb, clip); return 0; } else if (dst_format == DRM_FORMAT_RGB565) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_rgb565_toio(dst, dst_pitch, vmap, fb, clip, false); + drm_fb_xrgb8888_to_rgb565_toio(dst[0].vaddr_iomem, dst_pitch[0], + vmap[0].vaddr, fb, clip, false); return 0; } } else if (dst_format == DRM_FORMAT_RGB888) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_rgb888_toio(dst, dst_pitch, vmap, fb, clip); + drm_fb_xrgb8888_to_rgb888_toio(dst[0].vaddr_iomem, dst_pitch[0], + vmap[0].vaddr, fb, clip); return 0; } } else if (dst_format == DRM_FORMAT_XRGB8888) { if (fb_format == DRM_FORMAT_RGB888) { - drm_fb_rgb888_to_xrgb8888_toio(dst, dst_pitch, vmap, fb, clip); + drm_fb_rgb888_to_xrgb8888_toio(dst[0].vaddr_iomem, dst_pitch[0], + vmap[0].vaddr, fb, clip); return 0; } else if (fb_format == DRM_FORMAT_RGB565) { - drm_fb_rgb565_to_xrgb8888_toio(dst, dst_pitch, vmap, fb, clip); + drm_fb_rgb565_to_xrgb8888_toio(dst[0].vaddr_iomem, dst_pitch[0], + vmap[0].vaddr, fb, clip); return 0; } } else if (dst_format == DRM_FORMAT_XRGB2101010) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_xrgb2101010_toio(dst, dst_pitch, vmap, fb, clip); + drm_fb_xrgb8888_to_xrgb2101010_toio(dst[0].vaddr_iomem, dst_pitch[0], + vmap[0].vaddr, fb, clip); return 0; } } @@ -612,8 +625,7 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for return -EINVAL; } -EXPORT_SYMBOL(drm_fb_blit_toio); - +EXPORT_SYMBOL(drm_fb_blit); static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int pixels) { diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index 82fd98f77981..a81f91814595 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -508,11 +508,10 @@ static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane struct drm_plane_state *plane_state = plane->state; struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); - void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */ struct drm_framebuffer *fb = plane_state->fb; struct drm_device *dev = plane->dev; struct simpledrm_device *sdev = simpledrm_device_of_dev(dev); - void __iomem *dst = sdev->screen_base; + struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base); struct drm_rect src_clip, dst_clip; int idx; @@ -529,8 +528,9 @@ static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane if (!drm_dev_enter(dev, &idx)) return; - dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip); - drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip); + iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip)); + drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, fb, + &src_clip); drm_dev_exit(idx); } diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 55145eca0782..21daea7fda99 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -6,6 +6,7 @@ #ifndef __LINUX_DRM_FORMAT_HELPER_H #define __LINUX_DRM_FORMAT_HELPER_H +struct iosys_map; struct drm_format_info; struct drm_framebuffer; struct drm_rect; @@ -39,9 +40,9 @@ void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, unsigned int dst_pit void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip); -int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_format, - const void *vmap, const struct drm_framebuffer *fb, - const struct drm_rect *rect); +int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *rect); void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 03/14] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
Merge drm_fb_memcpy() and drm_fb_memcpy_toio() into a drm_fb_memcpy() that uses struct iosys_map for buffers. The new function also supports multi-plane color formats. Convert all users of the original helpers. v2: * rebase onto refactored mgag200 * use drm_formap_info_bpp() (Sam) * do static init in hyperv and mgag200 (Sam) * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- drivers/gpu/drm/drm_format_helper.c | 90 ++++++++++----------- drivers/gpu/drm/drm_mipi_dbi.c | 3 +- drivers/gpu/drm/gud/gud_pipe.c | 4 +- drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 9 +-- drivers/gpu/drm/mgag200/mgag200_mode.c | 9 +-- drivers/gpu/drm/tiny/cirrus.c | 21 ++--- include/drm/drm_format_helper.h | 7 +- 7 files changed, 70 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 07f329f607a3..7489c665a47c 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -131,63 +131,57 @@ static int drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned /** * drm_fb_memcpy - Copy clip buffer - * @dst: Destination buffer - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: Source buffer + * @dst: Array of destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * - * This function does not apply clipping on dst, i.e. the destination - * is at the top-left corner. - */ -void drm_fb_memcpy(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip) -{ - unsigned int cpp = fb->format->cpp[0]; - size_t len = (clip->x2 - clip->x1) * cpp; - unsigned int y, lines = clip->y2 - clip->y1; - - if (!dst_pitch) - dst_pitch = len; - - vaddr += clip_offset(clip, fb->pitches[0], cpp); - for (y = 0; y < lines; y++) { - memcpy(dst, vaddr, len); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } -} -EXPORT_SYMBOL(drm_fb_memcpy); - -/** - * drm_fb_memcpy_toio - Copy clip buffer - * @dst: Destination buffer (iomem) - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: Source buffer - * @fb: DRM framebuffer - * @clip: Clip rectangle area to copy + * This function copies parts of a framebuffer to display memory. Destination and + * framebuffer formats must match. No conversion takes place. The parameters @dst, + * @dst_pitch and @vmap refer to arrays. Each array must have at least as many entries + * as there are planes in @fb's format. Each entry stores the value for the format's + * respective color plane at the same index. * - * This function does not apply clipping on dst, i.e. the destination - * is at the top-left corner. + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). */ -void drm_fb_memcpy_toio(void __iomem *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip) +void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - unsigned int cpp = fb->format->cpp[0]; - size_t len = (clip->x2 - clip->x1) * cpp; - unsigned int y, lines = clip->y2 - clip->y1; + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; - if (!dst_pitch) - dst_pitch = len; + const struct drm_format_info *format = fb->format; + unsigned int i, y, lines = drm_rect_height(clip); - vaddr += clip_offset(clip, fb->pitches[0], cpp); - for (y = 0; y < lines; y++) { - memcpy_toio(dst, vaddr, len); - vaddr += fb->pitches[0]; - dst += dst_pitch; + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + for (i = 0; i < format->num_planes; ++i) { + unsigned int bpp_i = drm_format_info_bpp(format, i); + unsigned int cpp_i = DIV_ROUND_UP(bpp_i, 8); + size_t len_i = DIV_ROUND_UP(drm_rect_width(clip) * bpp_i, 8); + unsigned int dst_pitch_i = dst_pitch[i]; + struct iosys_map dst_i = dst[i]; + struct iosys_map vmap_i = vmap[i]; + + if (!dst_pitch_i) + dst_pitch_i = len_i; + + iosys_map_incr(&vmap_i, clip_offset(clip, fb->pitches[i], cpp_i)); + for (y = 0; y < lines; y++) { + /* TODO: handle vmap_i in I/O memory here */ + iosys_map_memcpy_to(&dst_i, 0, vmap_i.vaddr, len_i); + iosys_map_incr(&vmap_i, fb->pitches[i]); + iosys_map_incr(&dst_i, dst_pitch_i); + } } } -EXPORT_SYMBOL(drm_fb_memcpy_toio); +EXPORT_SYMBOL(drm_fb_memcpy); static void drm_fb_swab16_line(void *dbuf, const void *sbuf, unsigned int pixels) { @@ -587,7 +581,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d dst_format = DRM_FORMAT_XRGB2101010; if (dst_format == fb_format) { - drm_fb_memcpy_toio(dst[0].vaddr_iomem, dst_pitch[0], vmap[0].vaddr, fb, clip); + drm_fb_memcpy(dst, dst_pitch, vmap, fb, clip); return 0; } else if (dst_format == DRM_FORMAT_RGB565) { diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 2ecaf3cb7afb..1ba506ca83e1 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -205,6 +205,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0); struct iosys_map map[DRM_FORMAT_MAX_PLANES]; struct iosys_map data[DRM_FORMAT_MAX_PLANES]; + struct iosys_map dst_map = IOSYS_MAP_INIT_VADDR(dst); void *src; int ret; @@ -222,7 +223,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, if (swap) drm_fb_swab(dst, 0, src, fb, clip, !gem->import_attach); else - drm_fb_memcpy(dst, 0, src, fb, clip); + drm_fb_memcpy(&dst_map, NULL, data, fb, clip); break; case DRM_FORMAT_XRGB8888: drm_fb_xrgb8888_to_rgb565(dst, 0, src, fb, clip, swap); diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index d42592f6daab..449c95a4aee0 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -156,6 +156,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, u8 compression = gdrm->compression; struct iosys_map map[DRM_FORMAT_MAX_PLANES]; struct iosys_map map_data[DRM_FORMAT_MAX_PLANES]; + struct iosys_map dst; void *vaddr, *buf; size_t pitch, len; int ret = 0; @@ -179,6 +180,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, buf = gdrm->compress_buf; else buf = gdrm->bulk_buf; + iosys_map_set_vaddr(&dst, buf); /* * Imported buffers are assumed to be write-combined and thus uncached @@ -208,7 +210,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, /* can compress directly from the framebuffer */ buf = vaddr + rect->y1 * pitch; } else { - drm_fb_memcpy(buf, 0, vaddr, fb, rect); + drm_fb_memcpy(&dst, NULL, map_data, fb, rect); } memset(req, 0, sizeof(*req)); diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c index b8e64dd8d3a6..28e732f94bf2 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c @@ -21,19 +21,18 @@ #include "hyperv_drm.h" static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb, - const struct iosys_map *map, + const struct iosys_map *vmap, struct drm_rect *rect) { struct hyperv_drm_device *hv = to_hv(fb->dev); - void __iomem *dst = hv->vram; - void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */ + struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(hv->vram); int idx; if (!drm_dev_enter(&hv->dev, &idx)) return -ENODEV; - dst += drm_fb_clip_offset(fb->pitches[0], fb->format, rect); - drm_fb_memcpy_toio(dst, fb->pitches[0], vmap, fb, rect); + iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, rect)); + drm_fb_memcpy(&dst, fb->pitches, vmap, fb, rect); drm_dev_exit(idx); diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 1f26d4716679..bbab2549243a 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -430,13 +430,12 @@ static void mgag200_disable_display(struct mga_device *mdev) } static void mgag200_handle_damage(struct mga_device *mdev, const struct iosys_map *vmap, - struct drm_framebuffer *fb, const struct drm_rect *clip) + struct drm_framebuffer *fb, struct drm_rect *clip) { - void __iomem *dst = mdev->vram; - void *vaddr = vmap[0].vaddr; /* TODO: Use mapping abstraction properly */ + struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram); - dst += drm_fb_clip_offset(fb->pitches[0], fb->format, clip); - drm_fb_memcpy_toio(dst, fb->pitches[0], vaddr, fb, clip); + iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip)); + drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip); } /* diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index c4f5beea1f90..73fb9f63d227 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -316,28 +316,31 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, } static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, - const struct iosys_map *map, + const struct iosys_map *vmap, struct drm_rect *rect) { struct cirrus_device *cirrus = to_cirrus(fb->dev); - void __iomem *dst = cirrus->vram; - void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */ + struct iosys_map dst; + void *vaddr = vmap->vaddr; /* TODO: Use mapping abstraction properly */ int idx; if (!drm_dev_enter(&cirrus->dev, &idx)) return -ENODEV; + iosys_map_set_vaddr_iomem(&dst, cirrus->vram); + if (cirrus->cpp == fb->format->cpp[0]) { - dst += drm_fb_clip_offset(fb->pitches[0], fb->format, rect); - drm_fb_memcpy_toio(dst, fb->pitches[0], vmap, fb, rect); + iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, rect)); + drm_fb_memcpy(&dst, fb->pitches, vmap, fb, rect); } else if (fb->format->cpp[0] == 4 && cirrus->cpp == 2) { - dst += drm_fb_clip_offset(cirrus->pitch, fb->format, rect); - drm_fb_xrgb8888_to_rgb565_toio(dst, cirrus->pitch, vmap, fb, rect, false); + iosys_map_incr(&dst, drm_fb_clip_offset(cirrus->pitch, fb->format, rect)); + drm_fb_xrgb8888_to_rgb565_toio(dst.vaddr_iomem, cirrus->pitch, vaddr, fb, rect, + false); } else if (fb->format->cpp[0] == 4 && cirrus->cpp == 3) { - dst += drm_fb_clip_offset(cirrus->pitch, fb->format, rect); - drm_fb_xrgb8888_to_rgb888_toio(dst, cirrus->pitch, vmap, fb, rect); + iosys_map_incr(&dst, drm_fb_clip_offset(cirrus->pitch, fb->format, rect)); + drm_fb_xrgb8888_to_rgb888_toio(dst.vaddr_iomem, cirrus->pitch, vaddr, fb, rect); } else { WARN_ON_ONCE("cpp mismatch"); diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 21daea7fda99..8af6a2717bc9 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -14,10 +14,9 @@ struct drm_rect; unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format, const struct drm_rect *clip); -void drm_fb_memcpy(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip); -void drm_fb_memcpy_toio(void __iomem *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip); +void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip); void drm_fb_swab(void *dst, unsigned int dst_pitch, const void *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 04/14] drm/format-helper: Convert drm_fb_swab() to struct iosys_map
Convert drm_fb_swab() to use struct iosys_map() and convert users. The new interface supports multi-plane color formats, but implementation only supports a single plane for now. v2: * use drm_format_info_bpp() (Sam) * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- drivers/gpu/drm/drm_format_helper.c | 53 +++++++++++++++++++++-------- drivers/gpu/drm/drm_mipi_dbi.c | 2 +- drivers/gpu/drm/gud/gud_pipe.c | 2 +- include/drm/drm_format_helper.h | 6 ++-- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 7489c665a47c..b5ed058984ae 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -205,37 +205,62 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels /** * drm_fb_swab - Swap bytes into clip buffer - * @dst: Destination buffer - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @src: Source buffer + * @dst: Array of destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of source buffers * @fb: DRM framebuffer * @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 copies parts of a framebuffer to display memory and swaps per-pixel + * bytes during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. 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 at the top-left corner. + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). */ -void drm_fb_swab(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, const struct drm_rect *clip, - bool cached) +void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool cached) { - u8 cpp = fb->format->cpp[0]; + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + const struct drm_format_info *format = fb->format; + u8 cpp = DIV_ROUND_UP(drm_format_info_bpp(format, 0), 8); + void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels); switch (cpp) { case 4: - drm_fb_xfrm(dst, dst_pitch, cpp, src, fb, clip, cached, drm_fb_swab32_line); + swab_line = drm_fb_swab32_line; break; case 2: - drm_fb_xfrm(dst, dst_pitch, cpp, src, fb, clip, cached, drm_fb_swab16_line); + swab_line = drm_fb_swab16_line; break; default: drm_warn_once(fb->dev, "Format %p4cc has unsupported pixel size.\n", - &fb->format->format); + &format->format); + swab_line = NULL; break; } + if (!swab_line) + return; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst->is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], cpp, + vmap[0].vaddr, fb, clip, cached, swab_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], cpp, vmap[0].vaddr, fb, + clip, cached, swab_line); } EXPORT_SYMBOL(drm_fb_swab); diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 1ba506ca83e1..a44b7d6ae06c 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -221,7 +221,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, switch (fb->format->format) { case DRM_FORMAT_RGB565: if (swap) - drm_fb_swab(dst, 0, src, fb, clip, !gem->import_attach); + drm_fb_swab(&dst_map, NULL, data, fb, clip, !gem->import_attach); else drm_fb_memcpy(&dst_map, NULL, data, fb, clip); break; diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 449c95a4aee0..a15cda9ba058 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -205,7 +205,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, len = gud_xrgb8888_to_color(buf, format, vaddr, fb, rect); } } else if (gud_is_big_endian() && format->cpp[0] > 1) { - drm_fb_swab(buf, 0, vaddr, fb, rect, !import_attach); + drm_fb_swab(&dst, NULL, map_data, fb, rect, !import_attach); } else if (compression && !import_attach && pitch == fb->pitches[0]) { /* can compress directly from the framebuffer */ buf = vaddr + rect->y1 * pitch; diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 8af6a2717bc9..60944feaa936 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -17,9 +17,9 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip); -void drm_fb_swab(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, const struct drm_rect *clip, - bool cached); +void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool cached); void drm_fb_xrgb8888_to_rgb332(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip); void drm_fb_xrgb8888_to_rgb565(void *dst, unsigned int dst_pitch, const void *vaddr, -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 05/14] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
Update XRGB8888-to-RGB332 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * rebase onto refactored Kunit tests * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 38 +++++++++++++++---- drivers/gpu/drm/gud/gud_pipe.c | 2 +- .../gpu/drm/tests/drm_format_helper_test.c | 20 +++++----- include/drm/drm_format_helper.h | 5 ++- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index b5ed058984ae..248fd87f0a36 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -281,18 +281,42 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne /** * drm_fb_xrgb8888_to_rgb332 - Convert XRGB8888 to RGB332 clip buffer - * @dst: RGB332 destination buffer - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @src: XRGB8888 source buffer + * @dst: Array of RGB332 destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * - * Drivers can use this function for RGB332 devices that don't natively support XRGB8888. + * This function copies parts of a framebuffer to display memory and converts the + * color format during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. + * + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). + * + * Drivers can use this function for RGB332 devices that don't support XRGB8888 natively. */ -void drm_fb_xrgb8888_to_rgb332(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, const struct drm_rect *clip) +void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - drm_fb_xfrm(dst, dst_pitch, 1, src, fb, clip, false, drm_fb_xrgb8888_to_rgb332_line); + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 1, vmap[0].vaddr, fb, clip, + false, drm_fb_xrgb8888_to_rgb332_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 1, vmap[0].vaddr, fb, clip, + false, drm_fb_xrgb8888_to_rgb332_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index a15cda9ba058..426a3ae6cc50 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -196,7 +196,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, } else if (format->format == DRM_FORMAT_R8) { drm_fb_xrgb8888_to_gray8(buf, 0, vaddr, fb, rect); } else if (format->format == DRM_FORMAT_RGB332) { - drm_fb_xrgb8888_to_rgb332(buf, 0, vaddr, fb, rect); + drm_fb_xrgb8888_to_rgb332(&dst, NULL, map_data, fb, rect); } else if (format->format == DRM_FORMAT_RGB565) { drm_fb_xrgb8888_to_rgb565(buf, 0, vaddr, fb, rect, gud_is_big_endian()); } else if (format->format == DRM_FORMAT_RGB888) { diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c index 26ecf3b4b137..7b14694ead59 100644 --- a/drivers/gpu/drm/tests/drm_format_helper_test.c +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c @@ -197,8 +197,9 @@ static void xrgb8888_to_rgb332_test(struct kunit *test) const struct convert_xrgb8888_case *params = test->param_value; const struct convert_to_rgb332_result *result = ¶ms->rgb332_result; size_t dst_size; - __u8 *dst = NULL; - __u32 *src = NULL; + __u8 *buf = NULL; + __u32 *xrgb8888 = NULL; + struct iosys_map dst, src; struct drm_framebuffer fb = { .format = drm_format_info(DRM_FORMAT_XRGB8888), @@ -209,15 +210,16 @@ static void xrgb8888_to_rgb332_test(struct kunit *test) ¶ms->clip); KUNIT_ASSERT_GT(test, dst_size, 0); - dst = kunit_kzalloc(test, dst_size, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst); + buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); + iosys_map_set_vaddr(&dst, buf); - src = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, src); + xrgb8888 = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); + iosys_map_set_vaddr(&src, xrgb8888); - drm_fb_xrgb8888_to_rgb332(dst, result->dst_pitch, src, &fb, - ¶ms->clip); - KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0); + drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); + KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0); } static void xrgb8888_to_rgb565_test(struct kunit *test) diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 60944feaa936..3c28f099e3ed 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -20,8 +20,9 @@ void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached); -void drm_fb_xrgb8888_to_rgb332(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip); +void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip); void drm_fb_xrgb8888_to_rgb565(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 06/14] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion
Update XRGB8888-to-RGB565 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * update new Kunit tests * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 73 +++++++++---------- drivers/gpu/drm/drm_mipi_dbi.c | 4 +- drivers/gpu/drm/gud/gud_pipe.c | 3 +- .../gpu/drm/tests/drm_format_helper_test.c | 25 ++++--- drivers/gpu/drm/tiny/cirrus.c | 3 +- include/drm/drm_format_helper.h | 9 +-- 6 files changed, 55 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 248fd87f0a36..a77291d2f9b9 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -357,53 +357,51 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf, /** * drm_fb_xrgb8888_to_rgb565 - Convert XRGB8888 to RGB565 clip buffer - * @dst: RGB565 destination buffer - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: XRGB8888 source buffer + * @dst: Array of RGB565 destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of XRGB8888 source buffer * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * @swab: Swap bytes * - * Drivers can use this function for RGB565 devices that don't natively - * support XRGB8888. + * This function copies parts of a framebuffer to display memory and converts the + * color format during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. + * + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). + * + * Drivers can use this function for RGB565 devices that don't support XRGB8888 natively. */ -void drm_fb_xrgb8888_to_rgb565(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip, - bool swab) +void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool swab) { + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels); + if (swab) - drm_fb_xfrm(dst, dst_pitch, 2, vaddr, fb, clip, false, - drm_fb_xrgb8888_to_rgb565_swab_line); + xfrm_line = drm_fb_xrgb8888_to_rgb565_swab_line; else - drm_fb_xfrm(dst, dst_pitch, 2, vaddr, fb, clip, false, - drm_fb_xrgb8888_to_rgb565_line); -} -EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); + xfrm_line = drm_fb_xrgb8888_to_rgb565_line; -/** - * drm_fb_xrgb8888_to_rgb565_toio - Convert XRGB8888 to RGB565 clip buffer - * @dst: RGB565 destination buffer (iomem) - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: XRGB8888 source buffer - * @fb: DRM framebuffer - * @clip: Clip rectangle area to copy - * @swab: Swap bytes - * - * Drivers can use this function for RGB565 devices that don't natively - * support XRGB8888. - */ -void drm_fb_xrgb8888_to_rgb565_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip, bool swab) -{ - if (swab) - drm_fb_xfrm_toio(dst, dst_pitch, 2, vaddr, fb, clip, false, - drm_fb_xrgb8888_to_rgb565_swab_line); + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 2, vmap[0].vaddr, fb, clip, + false, xfrm_line); else - drm_fb_xfrm_toio(dst, dst_pitch, 2, vaddr, fb, clip, false, - drm_fb_xrgb8888_to_rgb565_line); + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 2, vmap[0].vaddr, fb, clip, + false, xfrm_line); } -EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565_toio); +EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigned int pixels) { @@ -635,8 +633,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d } else if (dst_format == DRM_FORMAT_RGB565) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_rgb565_toio(dst[0].vaddr_iomem, dst_pitch[0], - vmap[0].vaddr, fb, clip, false); + drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, vmap, fb, clip, false); return 0; } } else if (dst_format == DRM_FORMAT_RGB888) { diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index a44b7d6ae06c..84abc3920b57 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -206,7 +206,6 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, struct iosys_map map[DRM_FORMAT_MAX_PLANES]; struct iosys_map data[DRM_FORMAT_MAX_PLANES]; struct iosys_map dst_map = IOSYS_MAP_INIT_VADDR(dst); - void *src; int ret; ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); @@ -216,7 +215,6 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, ret = drm_gem_fb_vmap(fb, map, data); if (ret) goto out_drm_gem_fb_end_cpu_access; - src = data[0].vaddr; /* TODO: Use mapping abstraction properly */ switch (fb->format->format) { case DRM_FORMAT_RGB565: @@ -226,7 +224,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, drm_fb_memcpy(&dst_map, NULL, data, fb, clip); break; case DRM_FORMAT_XRGB8888: - drm_fb_xrgb8888_to_rgb565(dst, 0, src, fb, clip, swap); + drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, data, fb, clip, swap); break; default: drm_err_once(fb->dev, "Format is not supported: %p4cc\n", diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 426a3ae6cc50..a43eb6645352 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -198,7 +198,8 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, } else if (format->format == DRM_FORMAT_RGB332) { drm_fb_xrgb8888_to_rgb332(&dst, NULL, map_data, fb, rect); } else if (format->format == DRM_FORMAT_RGB565) { - drm_fb_xrgb8888_to_rgb565(buf, 0, vaddr, fb, rect, gud_is_big_endian()); + drm_fb_xrgb8888_to_rgb565(&dst, NULL, map_data, fb, rect, + gud_is_big_endian()); } else if (format->format == DRM_FORMAT_RGB888) { drm_fb_xrgb8888_to_rgb888(buf, 0, vaddr, fb, rect); } else { diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c index 7b14694ead59..828487071796 100644 --- a/drivers/gpu/drm/tests/drm_format_helper_test.c +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c @@ -227,8 +227,9 @@ static void xrgb8888_to_rgb565_test(struct kunit *test) const struct convert_xrgb8888_case *params = test->param_value; const struct convert_to_rgb565_result *result = ¶ms->rgb565_result; size_t dst_size; - __u16 *dst = NULL; - __u32 *src = NULL; + __u16 *buf = NULL; + __u32 *xrgb8888 = NULL; + struct iosys_map dst, src; struct drm_framebuffer fb = { .format = drm_format_info(DRM_FORMAT_XRGB8888), @@ -239,19 +240,19 @@ static void xrgb8888_to_rgb565_test(struct kunit *test) ¶ms->clip); KUNIT_ASSERT_GT(test, dst_size, 0); - dst = kunit_kzalloc(test, dst_size, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst); + buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); + iosys_map_set_vaddr(&dst, buf); - src = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, src); + xrgb8888 = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); + iosys_map_set_vaddr(&src, xrgb8888); - drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, src, &fb, - ¶ms->clip, false); - KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0); + drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, false); + KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0); - drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, src, &fb, - ¶ms->clip, true); - KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected_swab, dst_size), 0); + drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, true); + KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected_swab, dst_size), 0); } static struct kunit_case drm_format_helper_test_cases[] = { diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 73fb9f63d227..9cd398e4700b 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -335,8 +335,7 @@ static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, } else if (fb->format->cpp[0] == 4 && cirrus->cpp == 2) { iosys_map_incr(&dst, drm_fb_clip_offset(cirrus->pitch, fb->format, rect)); - drm_fb_xrgb8888_to_rgb565_toio(dst.vaddr_iomem, cirrus->pitch, vaddr, fb, rect, - false); + drm_fb_xrgb8888_to_rgb565(&dst, &cirrus->pitch, vmap, fb, rect, false); } else if (fb->format->cpp[0] == 4 && cirrus->cpp == 3) { iosys_map_incr(&dst, drm_fb_clip_offset(cirrus->pitch, fb->format, rect)); diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 3c28f099e3ed..9f1d45d7ce84 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -23,12 +23,9 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip); -void drm_fb_xrgb8888_to_rgb565(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip, - bool swab); -void drm_fb_xrgb8888_to_rgb565_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip, bool swab); +void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool swab); void drm_fb_xrgb8888_to_rgb888(void *dst, unsigned int dst_pitch, const void *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); void drm_fb_xrgb8888_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch, -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:53 UTC
[PATCH v2 07/14] drm/format-helper: Rework XRGB8888-to-RGB888 conversion
Update XRGB8888-to-RGB888 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 59 +++++++++++++++-------------- drivers/gpu/drm/gud/gud_pipe.c | 2 +- drivers/gpu/drm/tiny/cirrus.c | 3 +- include/drm/drm_format_helper.h | 8 ++-- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index a77291d2f9b9..3ee57dc8bcc5 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -420,41 +420,45 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne /** * drm_fb_xrgb8888_to_rgb888 - Convert XRGB8888 to RGB888 clip buffer - * @dst: RGB888 destination buffer - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @src: XRGB8888 source buffer + * @dst: Array of RGB888 destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * - * Drivers can use this function for RGB888 devices that don't natively - * support XRGB8888. - */ -void drm_fb_xrgb8888_to_rgb888(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, const struct drm_rect *clip) -{ - drm_fb_xfrm(dst, dst_pitch, 3, src, fb, clip, false, drm_fb_xrgb8888_to_rgb888_line); -} -EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); - -/** - * drm_fb_xrgb8888_to_rgb888_toio - Convert XRGB8888 to RGB888 clip buffer - * @dst: RGB565 destination buffer (iomem) - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: XRGB8888 source buffer - * @fb: DRM framebuffer - * @clip: Clip rectangle area to copy + * This function copies parts of a framebuffer to display memory and converts the + * color format during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. + * + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). * * Drivers can use this function for RGB888 devices that don't natively * support XRGB8888. */ -void drm_fb_xrgb8888_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip) +void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - drm_fb_xfrm_toio(dst, dst_pitch, 3, vaddr, fb, clip, false, - drm_fb_xrgb8888_to_rgb888_line); + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 3, vmap[0].vaddr, fb, + clip, false, drm_fb_xrgb8888_to_rgb888_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 3, vmap[0].vaddr, fb, + clip, false, drm_fb_xrgb8888_to_rgb888_line); } -EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888_toio); +EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); static void drm_fb_rgb565_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigned int pixels) { @@ -638,8 +642,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d } } else if (dst_format == DRM_FORMAT_RGB888) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_rgb888_toio(dst[0].vaddr_iomem, dst_pitch[0], - vmap[0].vaddr, fb, clip); + drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, vmap, fb, clip); return 0; } } else if (dst_format == DRM_FORMAT_XRGB8888) { diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index a43eb6645352..0caa228f736d 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -201,7 +201,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, drm_fb_xrgb8888_to_rgb565(&dst, NULL, map_data, fb, rect, gud_is_big_endian()); } else if (format->format == DRM_FORMAT_RGB888) { - drm_fb_xrgb8888_to_rgb888(buf, 0, vaddr, fb, rect); + drm_fb_xrgb8888_to_rgb888(&dst, NULL, map_data, fb, rect); } else { len = gud_xrgb8888_to_color(buf, format, vaddr, fb, rect); } diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 9cd398e4700b..354d5e854a6f 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -321,7 +321,6 @@ static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, { struct cirrus_device *cirrus = to_cirrus(fb->dev); struct iosys_map dst; - void *vaddr = vmap->vaddr; /* TODO: Use mapping abstraction properly */ int idx; if (!drm_dev_enter(&cirrus->dev, &idx)) @@ -339,7 +338,7 @@ static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, } else if (fb->format->cpp[0] == 4 && cirrus->cpp == 3) { iosys_map_incr(&dst, drm_fb_clip_offset(cirrus->pitch, fb->format, rect)); - drm_fb_xrgb8888_to_rgb888_toio(dst.vaddr_iomem, cirrus->pitch, vaddr, fb, rect); + drm_fb_xrgb8888_to_rgb888(&dst, &cirrus->pitch, vmap, fb, rect); } else { WARN_ON_ONCE("cpp mismatch"); diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 9f1d45d7ce84..8c633dbab5d6 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -26,11 +26,9 @@ void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pi void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab); -void drm_fb_xrgb8888_to_rgb888(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, const struct drm_rect *clip); -void drm_fb_xrgb8888_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip); +void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip); void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 08/14] drm/format-helper: Rework RGB565-to-XRGB8888 conversion
Update RGB565-to-XRGB8888 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 3ee57dc8bcc5..b390d529afeb 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -478,12 +478,25 @@ static void drm_fb_rgb565_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigne } } -static void drm_fb_rgb565_to_xrgb8888_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip) +static void drm_fb_rgb565_to_xrgb8888(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, + const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false, - drm_fb_rgb565_to_xrgb8888_line); + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, vmap[0].vaddr, fb, + clip, false, drm_fb_rgb565_to_xrgb8888_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb, + clip, false, drm_fb_rgb565_to_xrgb8888_line); } static void drm_fb_rgb888_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -651,8 +664,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d vmap[0].vaddr, fb, clip); return 0; } else if (fb_format == DRM_FORMAT_RGB565) { - drm_fb_rgb565_to_xrgb8888_toio(dst[0].vaddr_iomem, dst_pitch[0], - vmap[0].vaddr, fb, clip); + drm_fb_rgb565_to_xrgb8888(dst, dst_pitch, vmap, fb, clip); return 0; } } else if (dst_format == DRM_FORMAT_XRGB2101010) { -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 09/14] drm/format-helper: Rework RGB888-to-XRGB8888 conversion
Update RGB888-to-XRGB8888 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index b390d529afeb..8083f5b85b3a 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -514,12 +514,25 @@ static void drm_fb_rgb888_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigne } } -static void drm_fb_rgb888_to_xrgb8888_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip) +static void drm_fb_rgb888_to_xrgb8888(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, + const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false, - drm_fb_rgb888_to_xrgb8888_line); + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, vmap[0].vaddr, fb, + clip, false, drm_fb_rgb888_to_xrgb8888_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb, + clip, false, drm_fb_rgb888_to_xrgb8888_line); } static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -660,8 +673,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d } } else if (dst_format == DRM_FORMAT_XRGB8888) { if (fb_format == DRM_FORMAT_RGB888) { - drm_fb_rgb888_to_xrgb8888_toio(dst[0].vaddr_iomem, dst_pitch[0], - vmap[0].vaddr, fb, clip); + drm_fb_rgb888_to_xrgb8888(dst, dst_pitch, vmap, fb, clip); return 0; } else if (fb_format == DRM_FORMAT_RGB565) { drm_fb_rgb565_to_xrgb8888(dst, dst_pitch, vmap, fb, clip); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 10/14] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion
Update XRGB8888-to-XRGB2101010 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 50 ++++++++++++++++++++--------- include/drm/drm_format_helper.h | 6 ++-- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 8083f5b85b3a..795d845c7e53 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -554,26 +554,45 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un } /** - * drm_fb_xrgb8888_to_xrgb2101010_toio - Convert XRGB8888 to XRGB2101010 clip - * buffer - * @dst: XRGB2101010 destination buffer (iomem) - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: XRGB8888 source buffer + * drm_fb_xrgb8888_to_xrgb2101010 - Convert XRGB8888 to XRGB2101010 clip buffer + * @dst: Array of XRGB2101010 destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * - * Drivers can use this function for XRGB2101010 devices that don't natively - * support XRGB8888. + * This function copies parts of a framebuffer to display memory and converts the + * color format during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. + * + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). + * + * Drivers can use this function for XRGB2101010 devices that don't support XRGB8888 + * natively. */ -void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, - unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, - const struct drm_rect *clip) +void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false, - drm_fb_xrgb8888_to_xrgb2101010_line); + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, vmap[0].vaddr, fb, + clip, false, drm_fb_xrgb8888_to_xrgb2101010_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb, + clip, false, drm_fb_xrgb8888_to_xrgb2101010_line); } -EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010_toio); static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels) { @@ -681,8 +700,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d } } else if (dst_format == DRM_FORMAT_XRGB2101010) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_xrgb2101010_toio(dst[0].vaddr_iomem, dst_pitch[0], - vmap[0].vaddr, fb, clip); + drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, vmap, fb, clip); return 0; } } diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 8c633dbab5d6..6807440ce29c 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -29,9 +29,9 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip); -void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, unsigned int dst_pitch, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip); +void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip); void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 11/14] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion
Update XRGB8888-to-GRAY8 conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * update documentation (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 46 +++++++++++++++++++++-------- drivers/gpu/drm/gud/gud_pipe.c | 7 +++-- drivers/gpu/drm/tiny/st7586.c | 5 +++- include/drm/drm_format_helper.h | 5 ++-- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 795d845c7e53..890370c0424f 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -613,25 +613,47 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned /** * drm_fb_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale - * @dst: 8-bit grayscale destination buffer - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: XRGB8888 source buffer + * @dst: Array of 8-bit grayscale destination buffers + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * - * Drm doesn't have native monochrome or grayscale support. - * Such drivers can announce the commonly supported XR24 format to userspace - * and use this function to convert to the native format. + * This function copies parts of a framebuffer to display memory and converts the + * color format during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. * - * Monochrome drivers will use the most significant bit, - * where 1 means foreground color and 0 background color. + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). * - * ITU BT.601 is used for the RGB -> luma (brightness) conversion. + * DRM doesn't have native monochrome or grayscale support. Drivers can use this + * function for grayscale devices that don't support XRGB8888 natively.Such + * drivers can announce the commonly supported XR24 format to userspace and use + * this function to convert to the native format. Monochrome drivers will use the + * most significant bit, where 1 means foreground color and 0 background color. + * ITU BT.601 is being used for the RGB -> luma (brightness) conversion. */ -void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip) +void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { - drm_fb_xfrm(dst, dst_pitch, 1, vaddr, fb, clip, false, drm_fb_xrgb8888_to_gray8_line); + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 1, vmap[0].vaddr, fb, + clip, false, drm_fb_xrgb8888_to_gray8_line); + else + drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 1, vmap[0].vaddr, fb, + clip, false, drm_fb_xrgb8888_to_gray8_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 0caa228f736d..7c6dc2bcd14a 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -59,6 +59,7 @@ static size_t gud_xrgb8888_to_r124(u8 *dst, const struct drm_format_info *format unsigned int bits_per_pixel = 8 / block_width; unsigned int x, y, width, height; u8 pix, *pix8, *block = dst; /* Assign to silence compiler warning */ + struct iosys_map dst_map, vmap; size_t len; void *buf; @@ -74,7 +75,9 @@ static size_t gud_xrgb8888_to_r124(u8 *dst, const struct drm_format_info *format if (!buf) return 0; - drm_fb_xrgb8888_to_gray8(buf, 0, src, fb, rect); + iosys_map_set_vaddr(&dst_map, buf); + iosys_map_set_vaddr(&vmap, src); + drm_fb_xrgb8888_to_gray8(&dst_map, NULL, &vmap, fb, rect); pix8 = buf; for (y = 0; y < height; y++) { @@ -194,7 +197,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, goto end_cpu_access; } } else if (format->format == DRM_FORMAT_R8) { - drm_fb_xrgb8888_to_gray8(buf, 0, vaddr, fb, rect); + drm_fb_xrgb8888_to_gray8(&dst, NULL, map_data, fb, rect); } else if (format->format == DRM_FORMAT_RGB332) { drm_fb_xrgb8888_to_rgb332(&dst, NULL, map_data, fb, rect); } else if (format->format == DRM_FORMAT_RGB565) { diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c index 94f55fac4295..b6f620b902e6 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/tiny/st7586.c @@ -69,12 +69,15 @@ static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr, size_t len = (clip->x2 - clip->x1) * (clip->y2 - clip->y1); unsigned int x, y; u8 *src, *buf, val; + struct iosys_map dst_map, vmap; buf = kmalloc(len, GFP_KERNEL); if (!buf) return; - drm_fb_xrgb8888_to_gray8(buf, 0, vaddr, fb, clip); + iosys_map_set_vaddr(&dst_map, buf); + iosys_map_set_vaddr(&vmap, vaddr); + drm_fb_xrgb8888_to_gray8(&dst_map, NULL, &vmap, fb, clip); src = buf; for (y = clip->y1; y < clip->y2; y++) { diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 6807440ce29c..68087c982497 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -32,8 +32,9 @@ void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pi void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip); -void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip); +void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip); int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, const struct iosys_map *vmap, const struct drm_framebuffer *fb, -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 12/14] drm/format-helper: Rework XRGB8888-to-MONO conversion
Update XRGB8888-to-MONO conversion to support struct iosys_map and convert all users. Although these are single-plane color formats, the new interface supports multi-plane formats for consistency with drm_fb_blit(). v2: * rebase after renaming CMA helpers to DMA helpers * update documentation (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Sam Ravnborg <sam at ravnborg.org> --- drivers/gpu/drm/drm_format_helper.c | 56 +++++++++++++++++++---------- drivers/gpu/drm/solomon/ssd130x.c | 7 ++-- drivers/gpu/drm/tiny/repaper.c | 6 +++- include/drm/drm_format_helper.h | 5 +-- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 890370c0424f..53a313f83dc2 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -753,46 +753,64 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int /** * drm_fb_xrgb8888_to_mono - Convert XRGB8888 to monochrome - * @dst: monochrome destination buffer (0=black, 1=white) - * @dst_pitch: Number of bytes between two consecutive scanlines within dst - * @vaddr: XRGB8888 source buffer + * @dst: Array of monochrome destination buffers (0=black, 1=white) + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines + * within @dst; can be NULL if scanlines are stored next to each other. + * @vmap: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * - * DRM doesn't have native monochrome support. - * Such drivers can announce the commonly supported XR24 format to userspace - * and use this function to convert to the native format. + * This function copies parts of a framebuffer to display memory and converts the + * color format during the process. Destination and framebuffer formats must match. The + * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * least as many entries as there are planes in @fb's format. Each entry stores the + * value for the format's respective color plane at the same index. + * + * This function does not apply clipping on @dst (i.e. the destination is at the + * top-left corner). The first pixel (upper left corner of the clip rectangle) will + * be converted and copied to the first bit (LSB) in the first byte of the monochrome + * destination buffer. If the caller requires that the first pixel in a byte must + * be located at an x-coordinate that is a multiple of 8, then the caller must take + * care itself of supplying a suitable clip rectangle. + * + * DRM doesn't have native monochrome support. Drivers can use this function for + * monochrome devices that don't support XRGB8888 natively. Such drivers can + * announce the commonly supported XR24 format to userspace and use this function + * to convert to the native format. * * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and * then the result is converted from grayscale to monochrome. - * - * The first pixel (upper left corner of the clip rectangle) will be converted - * and copied to the first bit (LSB) in the first byte of the monochrome - * destination buffer. - * If the caller requires that the first pixel in a byte must be located at an - * x-coordinate that is a multiple of 8, then the caller must take care itself - * of supplying a suitable clip rectangle. */ -void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip) +void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip) { + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; unsigned int linepixels = drm_rect_width(clip); unsigned int lines = drm_rect_height(clip); unsigned int cpp = fb->format->cpp[0]; unsigned int len_src32 = linepixels * cpp; struct drm_device *dev = fb->dev; + void *vaddr = vmap[0].vaddr; + unsigned int dst_pitch_0; unsigned int y; - u8 *mono = dst, *gray8; + u8 *mono = dst[0].vaddr, *gray8; u32 *src32; if (drm_WARN_ON(dev, fb->format->format != DRM_FORMAT_XRGB8888)) return; + if (!dst_pitch) + dst_pitch = default_dst_pitch; + dst_pitch_0 = dst_pitch[0]; + /* * The mono destination buffer contains 1 bit per pixel */ - if (!dst_pitch) - dst_pitch = DIV_ROUND_UP(linepixels, 8); + if (!dst_pitch_0) + dst_pitch_0 = DIV_ROUND_UP(linepixels, 8); /* * The dma memory is write-combined so reads are uncached. @@ -817,7 +835,7 @@ void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vadd drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels); drm_fb_gray8_to_mono_line(mono, gray8, linepixels); vaddr += fb->pitches[0]; - mono += dst_pitch; + mono += dst_pitch_0; } kfree(src32); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index e1ff683db12a..94d92b726c34 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -536,11 +536,11 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x) kfree(buf); } -static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *map, +static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *vmap, struct drm_rect *rect) { struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); - void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */ + struct iosys_map dst; unsigned int dst_pitch; int ret = 0; u8 *buf = NULL; @@ -554,7 +554,8 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m if (!buf) return -ENOMEM; - drm_fb_xrgb8888_to_mono(buf, dst_pitch, vmap, fb, rect); + iosys_map_set_vaddr(&dst, buf); + drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect); ssd130x_update_rect(ssd130x, buf, rect); diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 4cd24b54ac74..c4c1be3ac0b8 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -513,6 +513,8 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) { struct drm_gem_dma_object *dma_obj = drm_fb_dma_get_gem_obj(fb, 0); struct repaper_epd *epd = drm_to_epd(fb->dev); + unsigned int dst_pitch = 0; + struct iosys_map dst, vmap; struct drm_rect clip; int idx, ret = 0; u8 *buf = NULL; @@ -541,7 +543,9 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) if (ret) goto out_free; - drm_fb_xrgb8888_to_mono(buf, 0, dma_obj->vaddr, fb, &clip); + iosys_map_set_vaddr(&dst, buf); + iosys_map_set_vaddr(&vmap, dma_obj->vaddr); + drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, &vmap, fb, &clip); drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 68087c982497..1e1d8f356cc1 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -40,7 +40,8 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *rect); -void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, const struct drm_rect *clip); +void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip); #endif /* __LINUX_DRM_FORMAT_HELPER_H */ -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 13/14] drm/format-helper: Move destination-buffer handling into internal helper
The format-convertion helpers handle several cases for different values of destination buffer and pitch. Move that code into the internal helper drm_fb_xfrm() and avoid quite a bit of duplication. v2: * remove a duplicated blank line (Jose) * use drm_format_info_bpp() (Sam) * fix vaddr_cached_hint bug (Sam) * add TODO on vaddr location (Sam) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- drivers/gpu/drm/drm_format_helper.c | 174 ++++++++++------------------ 1 file changed, 63 insertions(+), 111 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 53a313f83dc2..0fec3b68db95 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -41,11 +41,11 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info } EXPORT_SYMBOL(drm_fb_clip_offset); -/* TODO: Make this functon work with multi-plane formats. */ -static int drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip, bool vaddr_cached_hint, - void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) +/* TODO: Make this function work with multi-plane formats. */ +static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize, + const void *vaddr, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool vaddr_cached_hint, + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) { unsigned long linepixels = drm_rect_width(clip); unsigned long lines = drm_rect_height(clip); @@ -84,11 +84,11 @@ static int drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pix return 0; } -/* TODO: Make this functon work with multi-plane formats. */ -static int drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned long dst_pixsize, - const void *vaddr, const struct drm_framebuffer *fb, - const struct drm_rect *clip, bool vaddr_cached_hint, - void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) +/* TODO: Make this function work with multi-plane formats. */ +static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned long dst_pixsize, + const void *vaddr, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool vaddr_cached_hint, + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) { unsigned long linepixels = drm_rect_width(clip); unsigned long lines = drm_rect_height(clip); @@ -129,6 +129,29 @@ static int drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned return 0; } +/* TODO: Make this function work with multi-plane formats. */ +static int drm_fb_xfrm(struct iosys_map *dst, + const unsigned int *dst_pitch, const u8 *dst_pixsize, + const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool vaddr_cached_hint, + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) +{ + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { + 0, 0, 0, 0 + }; + + if (!dst_pitch) + dst_pitch = default_dst_pitch; + + /* TODO: handle vmap in I/O memory here */ + if (dst[0].is_iomem) + return __drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], dst_pixsize[0], + vmap[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); + else + return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0], + vmap[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); +} + /** * drm_fb_memcpy - Copy clip buffer * @dst: Array of destination buffers @@ -228,9 +251,6 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 - }; const struct drm_format_info *format = fb->format; u8 cpp = DIV_ROUND_UP(drm_format_info_bpp(format, 0), 8); void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels); @@ -245,22 +265,10 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, default: drm_warn_once(fb->dev, "Format %p4cc has unsupported pixel size.\n", &format->format); - swab_line = NULL; - break; - } - if (!swab_line) return; + } - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst->is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], cpp, - vmap[0].vaddr, fb, clip, cached, swab_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], cpp, vmap[0].vaddr, fb, - clip, cached, swab_line); + drm_fb_xfrm(dst, dst_pitch, &cpp, vmap, fb, clip, cached, swab_line); } EXPORT_SYMBOL(drm_fb_swab); @@ -303,20 +311,12 @@ void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pi const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 1, }; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 1, vmap[0].vaddr, fb, clip, - false, drm_fb_xrgb8888_to_rgb332_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 1, vmap[0].vaddr, fb, clip, - false, drm_fb_xrgb8888_to_rgb332_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xrgb8888_to_rgb332_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); @@ -380,9 +380,10 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 2, }; + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels); if (swab) @@ -390,16 +391,7 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi else xfrm_line = drm_fb_xrgb8888_to_rgb565_line; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 2, vmap[0].vaddr, fb, clip, - false, xfrm_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 2, vmap[0].vaddr, fb, clip, - false, xfrm_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, xfrm_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); @@ -443,20 +435,12 @@ void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pi const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 3, }; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 3, vmap[0].vaddr, fb, - clip, false, drm_fb_xrgb8888_to_rgb888_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 3, vmap[0].vaddr, fb, - clip, false, drm_fb_xrgb8888_to_rgb888_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xrgb8888_to_rgb888_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); @@ -483,20 +467,12 @@ static void drm_fb_rgb565_to_xrgb8888(struct iosys_map *dst, const unsigned int const struct drm_framebuffer *fb, const struct drm_rect *clip) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 4, }; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, vmap[0].vaddr, fb, - clip, false, drm_fb_rgb565_to_xrgb8888_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb, - clip, false, drm_fb_rgb565_to_xrgb8888_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_rgb565_to_xrgb8888_line); } static void drm_fb_rgb888_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -519,20 +495,12 @@ static void drm_fb_rgb888_to_xrgb8888(struct iosys_map *dst, const unsigned int const struct drm_framebuffer *fb, const struct drm_rect *clip) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 4, }; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, vmap[0].vaddr, fb, - clip, false, drm_fb_rgb888_to_xrgb8888_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb, - clip, false, drm_fb_rgb888_to_xrgb8888_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_rgb888_to_xrgb8888_line); } static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -578,20 +546,12 @@ void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *d const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 4, }; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, vmap[0].vaddr, fb, - clip, false, drm_fb_xrgb8888_to_xrgb2101010_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb, - clip, false, drm_fb_xrgb8888_to_xrgb2101010_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xrgb8888_to_xrgb2101010_line); } static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -640,20 +600,12 @@ void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pit const struct iosys_map *vmap, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { - 0, 0, 0, 0 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 1, }; - if (!dst_pitch) - dst_pitch = default_dst_pitch; - - /* TODO: handle vmap in I/O memory here */ - if (dst[0].is_iomem) - drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 1, vmap[0].vaddr, fb, - clip, false, drm_fb_xrgb8888_to_gray8_line); - else - drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 1, vmap[0].vaddr, fb, - clip, false, drm_fb_xrgb8888_to_gray8_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xrgb8888_to_gray8_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); -- 2.37.1
Thomas Zimmermann
2022-Aug-08 12:54 UTC
[PATCH v2 14/14] drm/format-helper: Rename parameter vmap to src
The name the parameter vmap to src in all functions. The parameter contains the locations of the source data and the new name says that. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- drivers/gpu/drm/drm_format_helper.c | 106 ++++++++++++++-------------- include/drm/drm_format_helper.h | 18 ++--- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 0fec3b68db95..56642816fdff 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -132,7 +132,7 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign /* TODO: Make this function work with multi-plane formats. */ static int drm_fb_xfrm(struct iosys_map *dst, const unsigned int *dst_pitch, const u8 *dst_pixsize, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool vaddr_cached_hint, void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) { @@ -143,13 +143,13 @@ static int drm_fb_xfrm(struct iosys_map *dst, if (!dst_pitch) dst_pitch = default_dst_pitch; - /* TODO: handle vmap in I/O memory here */ + /* TODO: handle src in I/O memory here */ if (dst[0].is_iomem) return __drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], dst_pixsize[0], - vmap[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); + src[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); else return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0], - vmap[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); + src[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); } /** @@ -157,13 +157,13 @@ static int drm_fb_xfrm(struct iosys_map *dst, * @dst: Array of destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of source buffers + * @src: Array of source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory. Destination and * framebuffer formats must match. No conversion takes place. The parameters @dst, - * @dst_pitch and @vmap refer to arrays. Each array must have at least as many entries + * @dst_pitch and @src refer to arrays. Each array must have at least as many entries * as there are planes in @fb's format. Each entry stores the value for the format's * respective color plane at the same index. * @@ -171,7 +171,7 @@ static int drm_fb_xfrm(struct iosys_map *dst, * top-left corner). */ void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { @@ -190,16 +190,16 @@ void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, size_t len_i = DIV_ROUND_UP(drm_rect_width(clip) * bpp_i, 8); unsigned int dst_pitch_i = dst_pitch[i]; struct iosys_map dst_i = dst[i]; - struct iosys_map vmap_i = vmap[i]; + struct iosys_map src_i = src[i]; if (!dst_pitch_i) dst_pitch_i = len_i; - iosys_map_incr(&vmap_i, clip_offset(clip, fb->pitches[i], cpp_i)); + iosys_map_incr(&src_i, clip_offset(clip, fb->pitches[i], cpp_i)); for (y = 0; y < lines; y++) { - /* TODO: handle vmap_i in I/O memory here */ - iosys_map_memcpy_to(&dst_i, 0, vmap_i.vaddr, len_i); - iosys_map_incr(&vmap_i, fb->pitches[i]); + /* TODO: handle src_i in I/O memory here */ + iosys_map_memcpy_to(&dst_i, 0, src_i.vaddr, len_i); + iosys_map_incr(&src_i, fb->pitches[i]); iosys_map_incr(&dst_i, dst_pitch_i); } } @@ -231,14 +231,14 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels * @dst: Array of destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of source buffers + * @src: Array of source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * @cached: Source buffer is mapped cached (eg. not write-combined) * * This function copies parts of a framebuffer to display memory and swaps per-pixel * bytes during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. If @cached is * false a temporary buffer is used to cache one pixel line at a time to speed up @@ -248,7 +248,7 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels * top-left corner). */ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached) { const struct drm_format_info *format = fb->format; @@ -268,7 +268,7 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, return; } - drm_fb_xfrm(dst, dst_pitch, &cpp, vmap, fb, clip, cached, swab_line); + drm_fb_xfrm(dst, dst_pitch, &cpp, src, fb, clip, cached, swab_line); } EXPORT_SYMBOL(drm_fb_swab); @@ -292,13 +292,13 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne * @dst: Array of RGB332 destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of XRGB8888 source buffers + * @src: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory and converts the * color format during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -308,14 +308,14 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne * Drivers can use this function for RGB332 devices that don't support XRGB8888 natively. */ void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 1, }; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_xrgb8888_to_rgb332_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); @@ -360,14 +360,14 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf, * @dst: Array of RGB565 destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of XRGB8888 source buffer + * @src: Array of XRGB8888 source buffer * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * @swab: Swap bytes * * This function copies parts of a framebuffer to display memory and converts the * color format during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -377,7 +377,7 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf, * Drivers can use this function for RGB565 devices that don't support XRGB8888 natively. */ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab) { static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { @@ -391,7 +391,7 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi else xfrm_line = drm_fb_xrgb8888_to_rgb565_line; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, xfrm_line); + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, xfrm_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); @@ -415,13 +415,13 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne * @dst: Array of RGB888 destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of XRGB8888 source buffers + * @src: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory and converts the * color format during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -432,14 +432,14 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne * support XRGB8888. */ void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 3, }; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_xrgb8888_to_rgb888_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); @@ -463,7 +463,7 @@ static void drm_fb_rgb565_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigne } static void drm_fb_rgb565_to_xrgb8888(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { @@ -471,7 +471,7 @@ static void drm_fb_rgb565_to_xrgb8888(struct iosys_map *dst, const unsigned int 4, }; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_rgb565_to_xrgb8888_line); } @@ -491,7 +491,7 @@ static void drm_fb_rgb888_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigne } static void drm_fb_rgb888_to_xrgb8888(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { @@ -499,7 +499,7 @@ static void drm_fb_rgb888_to_xrgb8888(struct iosys_map *dst, const unsigned int 4, }; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_rgb888_to_xrgb8888_line); } @@ -526,13 +526,13 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un * @dst: Array of XRGB2101010 destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of XRGB8888 source buffers + * @src: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory and converts the * color format during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -543,14 +543,14 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un * natively. */ void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 4, }; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_xrgb8888_to_xrgb2101010_line); } @@ -576,13 +576,13 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned * @dst: Array of 8-bit grayscale destination buffers * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of XRGB8888 source buffers + * @src: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory and converts the * color format during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -597,14 +597,14 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned * ITU BT.601 is being used for the RGB -> luma (brightness) conversion. */ void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 1, }; - drm_fb_xfrm(dst, dst_pitch, dst_pixsize, vmap, fb, clip, false, + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_xrgb8888_to_gray8_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); @@ -615,14 +615,14 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. * @dst_format: FOURCC code of the display's color format - * @vmap: The framebuffer memory to copy from + * @src: The framebuffer memory to copy from * @fb: The framebuffer to copy from * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory. If the * formats of the display and the framebuffer mismatch, the blit function * will attempt to convert between them during the process. The parameters @dst, - * @dst_pitch and @vmap refer to arrays. Each array must have at least as many + * @dst_pitch and @src refer to arrays. Each array must have at least as many * entries as there are planes in @dst_format's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -635,7 +635,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); * a negative error code otherwise. */ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { uint32_t fb_format = fb->format->format; @@ -651,30 +651,30 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d dst_format = DRM_FORMAT_XRGB2101010; if (dst_format == fb_format) { - drm_fb_memcpy(dst, dst_pitch, vmap, fb, clip); + drm_fb_memcpy(dst, dst_pitch, src, fb, clip); return 0; } else if (dst_format == DRM_FORMAT_RGB565) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, vmap, fb, clip, false); + drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, false); return 0; } } else if (dst_format == DRM_FORMAT_RGB888) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, vmap, fb, clip); + drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip); return 0; } } else if (dst_format == DRM_FORMAT_XRGB8888) { if (fb_format == DRM_FORMAT_RGB888) { - drm_fb_rgb888_to_xrgb8888(dst, dst_pitch, vmap, fb, clip); + drm_fb_rgb888_to_xrgb8888(dst, dst_pitch, src, fb, clip); return 0; } else if (fb_format == DRM_FORMAT_RGB565) { - drm_fb_rgb565_to_xrgb8888(dst, dst_pitch, vmap, fb, clip); + drm_fb_rgb565_to_xrgb8888(dst, dst_pitch, src, fb, clip); return 0; } } else if (dst_format == DRM_FORMAT_XRGB2101010) { if (fb_format == DRM_FORMAT_XRGB8888) { - drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, vmap, fb, clip); + drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip); return 0; } } @@ -708,13 +708,13 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int * @dst: Array of monochrome destination buffers (0=black, 1=white) * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines * within @dst; can be NULL if scanlines are stored next to each other. - * @vmap: Array of XRGB8888 source buffers + * @src: Array of XRGB8888 source buffers * @fb: DRM framebuffer * @clip: Clip rectangle area to copy * * This function copies parts of a framebuffer to display memory and converts the * color format during the process. Destination and framebuffer formats must match. The - * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at + * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at * least as many entries as there are planes in @fb's format. Each entry stores the * value for the format's respective color plane at the same index. * @@ -734,7 +734,7 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int * then the result is converted from grayscale to monochrome. */ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { @@ -745,7 +745,7 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc unsigned int cpp = fb->format->cpp[0]; unsigned int len_src32 = linepixels * cpp; struct drm_device *dev = fb->dev; - void *vaddr = vmap[0].vaddr; + void *vaddr = src[0].vaddr; unsigned int dst_pitch_0; unsigned int y; u8 *mono = dst[0].vaddr, *gray8; diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 1e1d8f356cc1..caa181194335 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -15,33 +15,33 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info const struct drm_rect *clip); void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached); void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab); void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *rect); void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, - const struct iosys_map *vmap, const struct drm_framebuffer *fb, + const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip); #endif /* __LINUX_DRM_FORMAT_HELPER_H */ -- 2.37.1
Sam Ravnborg
2022-Aug-08 18:51 UTC
[PATCH v2 00/14] drm/format-helper: Move to struct iosys_map
Hi Thomas, On Mon, Aug 08, 2022 at 02:53:52PM +0200, Thomas Zimmermann wrote:> Change format-conversion helpers to use struct iosys_map for source > and destination buffers. Update all users. Also prepare interface for > multi-plane color formats. > > The format-conversion helpers mostly used to convert to I/O memory > or system memory. To actual memory type depended on the usecase. We > now have drivers upcomming that do the conversion entirely in system > memory. It's a good opportunity to stream-line the interface of the > conversion helpers to use struct iosys_map. Source and destination > buffers can now be either in system or in I/O memory. Note that the > implementation still only supports source buffers in system memory. > > This patchset also changes the interface to support multi-plane > color formats, where the values for each component are stored in > distinct memory locations. Converting from RGBRGBRGB to RRRGGGBBB > would require a single source buffer with RGB values and 3 destination > buffers for the R, G and B values. Conversion-helper interfaces now > support this. > > v2: > * add IOSYS_MAP_INIT_VADDR_IOMEM (Sam) > * use drm_format_info_bpp() (Sam) > * update documentation (Sam) > * rename 'vmap' to 'src' (Sam) > * many smaller cleanups and fixes (Sam, Jose)Thanks for the quick respin - I reviewed the remaining patches and looks good. Nice cleanup of the API and it makes is easier to add more conversions. Sam
Noralf Trønnes
2022-Aug-08 20:00 UTC
[PATCH v2 00/14] drm/format-helper: Move to struct iosys_map
Den 08.08.2022 14.53, skrev Thomas Zimmermann:> Change format-conversion helpers to use struct iosys_map for source > and destination buffers. Update all users. Also prepare interface for > multi-plane color formats. > > The format-conversion helpers mostly used to convert to I/O memory > or system memory. To actual memory type depended on the usecase. We > now have drivers upcomming that do the conversion entirely in system > memory. It's a good opportunity to stream-line the interface of the > conversion helpers to use struct iosys_map. Source and destination > buffers can now be either in system or in I/O memory. Note that the > implementation still only supports source buffers in system memory. > > This patchset also changes the interface to support multi-plane > color formats, where the values for each component are stored in > distinct memory locations. Converting from RGBRGBRGB to RRRGGGBBB > would require a single source buffer with RGB values and 3 destination > buffers for the R, G and B values. Conversion-helper interfaces now > support this. > > v2: > * add IOSYS_MAP_INIT_VADDR_IOMEM (Sam) > * use drm_format_info_bpp() (Sam) > * update documentation (Sam) > * rename 'vmap' to 'src' (Sam) > * many smaller cleanups and fixes (Sam, Jose) > > Thomas Zimmermann (14): > iosys-map: Add IOSYS_MAP_INIT_VADDR_IOMEM() > drm/format-helper: Provide drm_fb_blit() > drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() > drm/format-helper: Convert drm_fb_swab() to struct iosys_map > drm/format-helper: Rework XRGB8888-to-RGBG332 conversion > drm/format-helper: Rework XRGB8888-to-RGBG565 conversion > drm/format-helper: Rework XRGB8888-to-RGB888 conversion > drm/format-helper: Rework RGB565-to-XRGB8888 conversion > drm/format-helper: Rework RGB888-to-XRGB8888 conversion > drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion > drm/format-helper: Rework XRGB8888-to-GRAY8 conversion > drm/format-helper: Rework XRGB8888-to-MONO conversion > drm/format-helper: Move destination-buffer handling into internal > helper > drm/format-helper: Rename parameter vmap to src >Tested-by: Noralf Tr?nnes <noralf at tronnes.org> * gud: XRGB8888-to-{MONO,GRAY8,RGB332,RGB565} * mi0283qt (drm_mipi_dbi): XRGB8888-to-RGB565 with swap=true, drm_fb_memcpy, drm_fb_swab> drivers/gpu/drm/drm_format_helper.c | 509 ++++++++++-------- > drivers/gpu/drm/drm_mipi_dbi.c | 9 +- > drivers/gpu/drm/gud/gud_pipe.c | 20 +- > drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 9 +- > drivers/gpu/drm/mgag200/mgag200_mode.c | 9 +- > drivers/gpu/drm/solomon/ssd130x.c | 7 +- > .../gpu/drm/tests/drm_format_helper_test.c | 45 +- > drivers/gpu/drm/tiny/cirrus.c | 19 +- > drivers/gpu/drm/tiny/repaper.c | 6 +- > drivers/gpu/drm/tiny/simpledrm.c | 8 +- > drivers/gpu/drm/tiny/st7586.c | 5 +- > include/drm/drm_format_helper.h | 56 +- > include/linux/iosys-map.h | 15 +- > 13 files changed, 416 insertions(+), 301 deletions(-) > > > base-commit: 2bdae66c9988dd0f07633629c0a85383cfc05940 > prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d > prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24 > prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6
Thomas Zimmermann
2022-Aug-10 07:07 UTC
[PATCH v2 00/14] drm/format-helper: Move to struct iosys_map
Thanks everyone for reviewing and testing. Am 08.08.22 um 14:53 schrieb Thomas Zimmermann:> Change format-conversion helpers to use struct iosys_map for source > and destination buffers. Update all users. Also prepare interface for > multi-plane color formats. > > The format-conversion helpers mostly used to convert to I/O memory > or system memory. To actual memory type depended on the usecase. We > now have drivers upcomming that do the conversion entirely in system > memory. It's a good opportunity to stream-line the interface of the > conversion helpers to use struct iosys_map. Source and destination > buffers can now be either in system or in I/O memory. Note that the > implementation still only supports source buffers in system memory. > > This patchset also changes the interface to support multi-plane > color formats, where the values for each component are stored in > distinct memory locations. Converting from RGBRGBRGB to RRRGGGBBB > would require a single source buffer with RGB values and 3 destination > buffers for the R, G and B values. Conversion-helper interfaces now > support this. > > v2: > * add IOSYS_MAP_INIT_VADDR_IOMEM (Sam) > * use drm_format_info_bpp() (Sam) > * update documentation (Sam) > * rename 'vmap' to 'src' (Sam) > * many smaller cleanups and fixes (Sam, Jose) > > Thomas Zimmermann (14): > iosys-map: Add IOSYS_MAP_INIT_VADDR_IOMEM() > drm/format-helper: Provide drm_fb_blit() > drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() > drm/format-helper: Convert drm_fb_swab() to struct iosys_map > drm/format-helper: Rework XRGB8888-to-RGBG332 conversion > drm/format-helper: Rework XRGB8888-to-RGBG565 conversion > drm/format-helper: Rework XRGB8888-to-RGB888 conversion > drm/format-helper: Rework RGB565-to-XRGB8888 conversion > drm/format-helper: Rework RGB888-to-XRGB8888 conversion > drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion > drm/format-helper: Rework XRGB8888-to-GRAY8 conversion > drm/format-helper: Rework XRGB8888-to-MONO conversion > drm/format-helper: Move destination-buffer handling into internal > helper > drm/format-helper: Rename parameter vmap to src > > drivers/gpu/drm/drm_format_helper.c | 509 ++++++++++-------- > drivers/gpu/drm/drm_mipi_dbi.c | 9 +- > drivers/gpu/drm/gud/gud_pipe.c | 20 +- > drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 9 +- > drivers/gpu/drm/mgag200/mgag200_mode.c | 9 +- > drivers/gpu/drm/solomon/ssd130x.c | 7 +- > .../gpu/drm/tests/drm_format_helper_test.c | 45 +- > drivers/gpu/drm/tiny/cirrus.c | 19 +- > drivers/gpu/drm/tiny/repaper.c | 6 +- > drivers/gpu/drm/tiny/simpledrm.c | 8 +- > drivers/gpu/drm/tiny/st7586.c | 5 +- > include/drm/drm_format_helper.h | 56 +- > include/linux/iosys-map.h | 15 +- > 13 files changed, 416 insertions(+), 301 deletions(-) > > > base-commit: 2bdae66c9988dd0f07633629c0a85383cfc05940 > prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d > prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24 > prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 N?rnberg, Germany (HRB 36809, AG N?rnberg) Gesch?ftsf?hrer: Ivo Totev -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: <http://lists.linuxfoundation.org/pipermail/virtualization/attachments/20220810/afc47f89/attachment.sig>