Thomas Zimmermann
2022-Jul-27  11:33 UTC
[PATCH 00/12] 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.
Thomas Zimmermann (12):
  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
 drivers/gpu/drm/drm_format_helper.c           | 379 +++++++++---------
 drivers/gpu/drm/drm_mipi_dbi.c                |   9 +-
 drivers/gpu/drm/gud/gud_pipe.c                |  20 +-
 drivers/gpu/drm/hyperv/hyperv_drm_modeset.c   |  11 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c        |  11 +-
 drivers/gpu/drm/solomon/ssd130x.c             |   7 +-
 .../gpu/drm/tests/drm_format_helper_test.c    |  14 +-
 drivers/gpu/drm/tiny/cirrus.c                 |  19 +-
 drivers/gpu/drm/tiny/repaper.c                |   6 +-
 drivers/gpu/drm/tiny/simpledrm.c              |  18 +-
 drivers/gpu/drm/tiny/st7586.c                 |   5 +-
 include/drm/drm_format_helper.h               |  56 ++-
 12 files changed, 294 insertions(+), 261 deletions(-)
base-commit: 15fbed4f822211fbb7653c2b8591594d92de9551
prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6
-- 
2.37.1
Thomas Zimmermann
2022-Jul-27  11:33 UTC
[PATCH 01/12] 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. The new function's interface works with multi-plane
color formats, although the implementation only supports a single
plane for now.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 39 ++++++++++++++++++-----------
 drivers/gpu/drm/tiny/simpledrm.c    | 18 +++++++------
 include/drm/drm_format_helper.h     |  7 +++---
 3 files changed, 38 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index c6182b5de78b..4d74d46ab155 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,9 @@ 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 two consecutive scanlines
within dst
  * @dst_format:	FOURCC code of the display's color format
  * @vmap:	The framebuffer memory to copy from
  * @fb:		The framebuffer to copy from
@@ -557,14 +558,18 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8);
  * formats of the display and the framebuffer mismatch, the blit function
  * will attempt to convert between them.
  *
+ * 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.
+ *
  * 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 +584,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 +622,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 5422363690e7..1ec73bec0513 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -652,9 +652,8 @@ simpledrm_simple_display_pipe_enable(struct
drm_simple_display_pipe *pipe,
 	struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
 	struct drm_shadow_plane_state *shadow_plane_state =
to_drm_shadow_plane_state(plane_state);
 	struct drm_framebuffer *fb = plane_state->fb;
-	void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping
abstraction */
 	struct drm_device *dev = &sdev->dev;
-	void __iomem *dst = sdev->screen_base;
+	struct iosys_map dst;
 	struct drm_rect src_clip, dst_clip;
 	int idx;
 
@@ -670,8 +669,10 @@ simpledrm_simple_display_pipe_enable(struct
drm_simple_display_pipe *pipe,
 	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_set_vaddr_iomem(&dst, sdev->screen_base);
+	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);
 }
@@ -699,10 +700,9 @@ simpledrm_simple_display_pipe_update(struct
drm_simple_display_pipe *pipe,
 	struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
 	struct drm_plane_state *plane_state = pipe->plane.state;
 	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 = &sdev->dev;
-	void __iomem *dst = sdev->screen_base;
+	struct iosys_map dst;
 	struct drm_rect src_clip, dst_clip;
 	int idx;
 
@@ -719,8 +719,10 @@ simpledrm_simple_display_pipe_update(struct
drm_simple_display_pipe *pipe,
 	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_set_vaddr_iomem(&dst, sdev->screen_base);
+	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-Jul-27  11:33 UTC
[PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
Merge drm_fb_memcpy() and drm_fb_memcpy() into 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.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c         | 77 +++++++++------------
 drivers/gpu/drm/drm_mipi_dbi.c              |  3 +-
 drivers/gpu/drm/gud/gud_pipe.c              |  4 +-
 drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 11 +--
 drivers/gpu/drm/mgag200/mgag200_mode.c      | 11 +--
 drivers/gpu/drm/tiny/cirrus.c               | 21 +++---
 include/drm/drm_format_helper.h             |  7 +-
 7 files changed, 63 insertions(+), 71 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 4d74d46ab155..49589b442f18 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -131,63 +131,48 @@ 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 two consecutive scanlines
within dst
+ * @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)
+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;
-
-	if (!dst_pitch)
-		dst_pitch = len;
+	static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+		0, 0, 0, 0
+	};
 
-	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 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)
-{
-	unsigned int cpp = fb->format->cpp[0];
-	size_t len = (clip->x2 - clip->x1) * cpp;
-	unsigned int y, lines = clip->y2 - clip->y1;
+	const struct drm_format_info *format = fb->format;
+	unsigned int i, y, lines = drm_rect_height(clip);
 
 	if (!dst_pitch)
-		dst_pitch = len;
-
-	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;
+		dst_pitch = default_dst_pitch;
+
+	for (i = 0; i < format->num_planes; ++i) {
+		unsigned int cpp_i = format->cpp[i];
+		size_t len_i = drm_rect_width(clip) * cpp_i;
+		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++) {
+			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)
 {
@@ -584,7 +569,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 2f61f53d472f..22451806fb5c 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..26e63148e226 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
@@ -21,19 +21,20 @@
 #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;
 	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_set_vaddr_iomem(&dst, hv->vram);
+	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 a02f599cb9cf..a79a0ee3a50d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -755,13 +755,14 @@ mgag200_simple_display_pipe_mode_valid(struct
drm_simple_display_pipe *pipe,
 
 static void
 mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb,
-		      struct drm_rect *clip, const struct iosys_map *map)
+		      struct drm_rect *clip, const struct iosys_map *vmap)
 {
-	void __iomem *dst = mdev->vram;
-	void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */
+	struct iosys_map dst;
 
-	dst += drm_fb_clip_offset(fb->pitches[0], fb->format, clip);
-	drm_fb_memcpy_toio(dst, fb->pitches[0], vmap, fb, clip);
+	iosys_map_set_vaddr_iomem(&dst, mdev->vram);
+	iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format,
clip));
+
+	drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip);
 }
 
 static void
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-Jul-27  11:33 UTC
[PATCH 03/12] 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.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 38 +++++++++++++++++++++--------
 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, 33 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 49589b442f18..fa22d3cb11e8 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -196,9 +196,9 @@ 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 two consecutive scanlines
within dst
+ * @vmap: Array of source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  * @cached: Source buffer is mapped cached (eg. not write-combined)
@@ -209,24 +209,42 @@ static void drm_fb_swab32_line(void *dbuf, const void
*sbuf, unsigned int pixels
  * 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 = format->cpp[0];
+	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;
+
+	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 22451806fb5c..973a75585cad 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-Jul-27  11:33 UTC
[PATCH 04/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c           | 25 ++++++++++++++-----
 drivers/gpu/drm/gud/gud_pipe.c                |  2 +-
 .../gpu/drm/tests/drm_format_helper_test.c    | 14 ++++++-----
 include/drm/drm_format_helper.h               |  5 ++--
 4 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index fa22d3cb11e8..2b5c3746ff4a 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -265,18 +265,31 @@ 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 two consecutive scanlines
within dst
+ * @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.
  */
-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;
+
+	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 98583bf56044..b74dba06f704 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -124,7 +124,8 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
 {
 	const struct xrgb8888_to_rgb332_case *params = test->param_value;
 	size_t dst_size;
-	__u8 *dst = NULL;
+	struct iosys_map dst, xrgb8888;
+	__u8 *buf = NULL;
 
 	struct drm_framebuffer fb = {
 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
@@ -135,12 +136,13 @@ 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);
 
-	drm_fb_xrgb8888_to_rgb332(dst, params->dst_pitch, params->xrgb8888,
-				  &fb, ¶ms->clip);
-	KUNIT_EXPECT_EQ(test, memcmp(dst, params->expected, dst_size), 0);
+	iosys_map_set_vaddr(&dst, buf);
+	iosys_map_set_vaddr(&xrgb8888, (void __force *)params->xrgb8888);
+	drm_fb_xrgb8888_to_rgb332(&dst, ¶ms->dst_pitch, &xrgb8888,
&fb, ¶ms->clip);
+	KUNIT_EXPECT_EQ(test, memcmp(buf, params->expected, dst_size), 0);
 }
 
 static struct kunit_case drm_format_helper_test_cases[] = {
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-Jul-27  11:33 UTC
[PATCH 05/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 59 +++++++++++------------------
 drivers/gpu/drm/drm_mipi_dbi.c      |  4 +-
 drivers/gpu/drm/gud/gud_pipe.c      |  3 +-
 drivers/gpu/drm/tiny/cirrus.c       |  3 +-
 include/drm/drm_format_helper.h     |  9 ++---
 5 files changed, 30 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 2b5c3746ff4a..8bf5655f5ce0 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -330,9 +330,9 @@ 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 two consecutive scanlines
within dst
+ * @vmap: Array of XRGB8888 source buffer
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  * @swab: Swap bytes
@@ -340,43 +340,31 @@ 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 natively
  * support XRGB8888.
  */
-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;
+
+	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)
 {
@@ -605,8 +593,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 973a75585cad..d0bdbcb96705 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/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-Jul-27  11:33 UTC
[PATCH 06/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 48 ++++++++++++-----------------
 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, 25 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 8bf5655f5ce0..4edab44336d8 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -383,41 +383,34 @@ 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 two consecutive scanlines
within dst
+ * @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)
+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(dst, dst_pitch, 3, src, fb, clip, false,
drm_fb_xrgb8888_to_rgb888_line);
-}
-EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888);
+	static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+		0, 0, 0, 0
+	};
 
-/**
- * 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
- *
- * 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)
-{
-	drm_fb_xfrm_toio(dst, dst_pitch, 3, vaddr, fb, clip, false,
-			 drm_fb_xrgb8888_to_rgb888_line);
+	if (!dst_pitch)
+		dst_pitch = default_dst_pitch;
+
+	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)
 {
@@ -598,8 +591,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-Jul-27  11:33 UTC
[PATCH 07/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 4edab44336d8..5ef06f696657 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -430,12 +430,24 @@ 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;
+
+	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)
@@ -600,8 +612,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-Jul-27  11:33 UTC
[PATCH 08/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 5ef06f696657..155827eebe99 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -465,12 +465,24 @@ 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;
+
+	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)
@@ -608,8 +620,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-Jul-27  11:33 UTC
[PATCH 09/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 35 +++++++++++++++++------------
 include/drm/drm_format_helper.h     |  6 ++---
 2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 155827eebe99..209f63b66c5f 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -504,26 +504,34 @@ 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 two consecutive scanlines
within dst
+ * @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.
  */
-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;
+
+	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)
 {
@@ -628,8 +636,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-Jul-27  11:33 UTC
[PATCH 10/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 25 +++++++++++++++++++------
 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, 31 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 209f63b66c5f..521932fac491 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -552,9 +552,9 @@ 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 number of bytes between two consecutive scanlines
within dst
+ * @vmap: Array of XRGB8888 source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
@@ -567,10 +567,23 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf,
const void *sbuf, unsigned
  *
  * ITU BT.601 is 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;
+
+	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 8eddb020c43e..702350d0f8bc 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-Jul-27  11:33 UTC
[PATCH 11/12] 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().
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 28 +++++++++++++++++++---------
 drivers/gpu/drm/solomon/ssd130x.c   |  7 ++++---
 drivers/gpu/drm/tiny/repaper.c      |  6 +++++-
 include/drm/drm_format_helper.h     |  5 +++--
 4 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index 521932fac491..d296d181659d 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -680,9 +680,9 @@ 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 two consecutive scanlines
within dst
+ * @vmap: Array of XRGB8888 source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
@@ -700,26 +700,36 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const
void *sbuf, unsigned int
  * 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 cma memory is write-combined so reads are uncached.
@@ -744,7 +754,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 5a3e3b78cd9e..aa7329a65c98 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -537,11 +537,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;
@@ -555,7 +555,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 013790c45d0a..0cdf6ab8fcc5 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_cma_object *cma_obj = drm_fb_cma_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, cma_obj->vaddr, fb, &clip);
+	iosys_map_set_vaddr(&dst, buf);
+	iosys_map_set_vaddr(&vmap, cma_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-Jul-27  11:33 UTC
[PATCH 12/12] 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 duplucation.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_format_helper.c | 169 +++++++++++-----------------
 1 file changed, 64 insertions(+), 105 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c
b/drivers/gpu/drm/drm_format_helper.c
index d296d181659d..35aebdb90165 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;
+
+	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, false, xfrm_line);
+	else
+		return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0],
+				     vmap[0].vaddr, fb, clip, false, xfrm_line);
+}
+
+
 /**
  * drm_fb_memcpy - Copy clip buffer
  * @dst: Array of destination buffers
@@ -213,14 +236,10 @@ 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 = format->cpp[0];
 	void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels);
 
-	switch (cpp) {
+	switch (format->cpp[0]) {
 	case 4:
 		swab_line = drm_fb_swab32_line;
 		break;
@@ -230,21 +249,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;
-
-	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, format->cpp, vmap, fb, clip, cached,
swab_line);
 }
 EXPORT_SYMBOL(drm_fb_swab);
 
@@ -277,19 +285,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;
-
-	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);
 
@@ -344,9 +345,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)
@@ -354,15 +356,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;
-
-	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);
 
@@ -396,19 +390,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;
-
-	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);
 
@@ -435,19 +422,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;
-
-	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)
@@ -470,19 +450,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;
-
-	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)
@@ -518,19 +491,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;
-
-	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)
@@ -571,19 +537,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;
-
-	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
Hi Thomas, On Wed, Jul 27, 2022 at 01:33:01PM +0200, Thomas Zimmermann wrote:> 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. The new function's interface works with multi-plane > color formats, although the implementation only supports a single > plane for now. > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > --- > drivers/gpu/drm/drm_format_helper.c | 39 ++++++++++++++++++----------- > drivers/gpu/drm/tiny/simpledrm.c | 18 +++++++------ > include/drm/drm_format_helper.h | 7 +++--- > 3 files changed, 38 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index c6182b5de78b..4d74d46ab155 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,9 @@ 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 two consecutive scanlines within dstThe rename confused me since this function continue to operate only on io memory, but I see that this is all fixed up in later patches. It would be nice to have this mentioned in the changelog, just in case someone else takes a deeper look at it. With the changelog updated: Reviewed-by: Sam Ravnborg <sam at ravnborg.org> See also comments below.> * @dst_format: FOURCC code of the display's color format > * @vmap: The framebuffer memory to copy from > * @fb: The framebuffer to copy from > @@ -557,14 +558,18 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); > * formats of the display and the framebuffer mismatch, the blit function > * will attempt to convert between them. > * > + * 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. > + * > * 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 +584,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 +622,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 5422363690e7..1ec73bec0513 100644 > --- a/drivers/gpu/drm/tiny/simpledrm.c > +++ b/drivers/gpu/drm/tiny/simpledrm.c > @@ -652,9 +652,8 @@ simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, > struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); > struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); > struct drm_framebuffer *fb = plane_state->fb; > - void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */ > struct drm_device *dev = &sdev->dev; > - void __iomem *dst = sdev->screen_base; > + struct iosys_map dst;Maybe struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base);> struct drm_rect src_clip, dst_clip; > int idx; > > @@ -670,8 +669,10 @@ simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, > 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_set_vaddr_iomem(&dst, sdev->screen_base); > + 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); > } > @@ -699,10 +700,9 @@ simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, > struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); > struct drm_plane_state *plane_state = pipe->plane.state; > 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 = &sdev->dev; > - void __iomem *dst = sdev->screen_base; > + struct iosys_map dst;Likewise: struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base);> struct drm_rect src_clip, dst_clip; > int idx; > > @@ -719,8 +719,10 @@ simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, > 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_set_vaddr_iomem(&dst, sdev->screen_base); > + 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
Sam Ravnborg
2022-Aug-04  19:52 UTC
[PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
Hi Thomas, On Wed, Jul 27, 2022 at 01:33:02PM +0200, Thomas Zimmermann wrote:> Merge drm_fb_memcpy() and drm_fb_memcpy() into drm_fb_memcpy() thatOne of these is drm_fb_memcpy_toio()> uses struct iosys_map for buffers. The new function also supports > multi-plane color formats. Convert all users of the original helpers.A few comments in the patch below. Sam> > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > --- > drivers/gpu/drm/drm_format_helper.c | 77 +++++++++------------ > drivers/gpu/drm/drm_mipi_dbi.c | 3 +- > drivers/gpu/drm/gud/gud_pipe.c | 4 +- > drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 11 +-- > drivers/gpu/drm/mgag200/mgag200_mode.c | 11 +-- > drivers/gpu/drm/tiny/cirrus.c | 21 +++--- > include/drm/drm_format_helper.h | 7 +- > 7 files changed, 63 insertions(+), 71 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 4d74d46ab155..49589b442f18 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -131,63 +131,48 @@ 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 two consecutive scanlines within dstDocument that this may be NULL, in which case the distance is considered 0.> + * @vmap: Array of source buffersIt would have helped my understanding if this argument was named src, so it is a little more obvious that we copy from src to dst. Maybe document that data is copied from src based on the pitch info in the framebuffer, and likewise the format_info in the framebuffer.> * @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) > +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; > - > - if (!dst_pitch) > - dst_pitch = len; > + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { > + 0, 0, 0, 0 > + };This is used in several places in this series. What I read is that a static variable is declared where the first element in the array is set to all zeroes. But the other elements in the array are ignored - but since it is static they are also set to 0 so we are good here. In some cases I see it removed again, I did not check the end result if we end up dropping them all again.> > - 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 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) > -{ > - unsigned int cpp = fb->format->cpp[0]; > - size_t len = (clip->x2 - clip->x1) * cpp; > - unsigned int y, lines = clip->y2 - clip->y1; > + const struct drm_format_info *format = fb->format; > + unsigned int i, y, lines = drm_rect_height(clip); > > if (!dst_pitch) > - dst_pitch = len; > - > - 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; > + dst_pitch = default_dst_pitch; > + > + for (i = 0; i < format->num_planes; ++i) { > + unsigned int cpp_i = format->cpp[i];unsigned int cpp_i = drm_format_info_bpp(format, i) / 8; This avoid adding more uses of the deprecated cpp[] array.> + size_t len_i = drm_rect_width(clip) * cpp_i; > + unsigned int dst_pitch_i = dst_pitch[i]; > + struct iosys_map dst_i = dst[i]; > + struct iosys_map vmap_i = vmap[i];WARN_ON_ONCE(dst_i == NULL)? WARN_ON_ONCE(vmap_i == NULL)? Or something else so we error out somehow if we do not have enough planes in dst or src (vmap).> + > + if (!dst_pitch_i) > + dst_pitch_i = len_i;If there can be NULL in the dst_pitch array, this should be documented above I think. I do not like the current dst pitch workaround, but I failed to come up with something better.> + > + iosys_map_incr(&vmap_i, clip_offset(clip, fb->pitches[i], cpp_i)); > + for (y = 0; y < lines; y++) { > + iosys_map_memcpy_to(&dst_i, 0, vmap_i.vaddr, len_i);This hardcodes (vmap_i.vaddr) that vmap (src) is system memory. From a quick look this is not fixed in a later patch. At minimum add a TODO entry here.> + 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) > { > @@ -584,7 +569,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 2f61f53d472f..22451806fb5c 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..26e63148e226 100644 > --- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c > +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c > @@ -21,19 +21,20 @@ > #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; > 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_set_vaddr_iomem(&dst, hv->vram); > + 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 a02f599cb9cf..a79a0ee3a50d 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_mode.c > +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c > @@ -755,13 +755,14 @@ mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe, > > static void > mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb, > - struct drm_rect *clip, const struct iosys_map *map) > + struct drm_rect *clip, const struct iosys_map *vmap) > { > - void __iomem *dst = mdev->vram; > - void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */ > + struct iosys_map dst;Or use struct iosys_map dst = IOSYS_MAP_INIT_VADDR(mdev->vram); There is no drm_dev_enter() here we need to pass first, like in hyperv_drm_modeset.c above.> > - dst += drm_fb_clip_offset(fb->pitches[0], fb->format, clip); > - drm_fb_memcpy_toio(dst, fb->pitches[0], vmap, fb, clip); > + iosys_map_set_vaddr_iomem(&dst, mdev->vram); > + iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip)); > + > + drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip); > } > > static void > 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
Sam Ravnborg
2022-Aug-04  20:08 UTC
[PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map
Hi Thomas, On Wed, Jul 27, 2022 at 01:33:03PM +0200, Thomas Zimmermann wrote:> Convert drm_fb_swab() to use struct iosys_map() and convert users. The > new interface supports multi-plane color formats.It swabs only plane[0], sbut this is maybe enough to say so. A few comments in the following. Sam> > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > --- > drivers/gpu/drm/drm_format_helper.c | 38 +++++++++++++++++++++-------- > 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, 33 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 49589b442f18..fa22d3cb11e8 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -196,9 +196,9 @@ 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 two consecutive scanlines within dstDocument that it may be NULL?> + * @vmap: Array of source buffersPrefer that the source is named src, and vmap smells like system (virtual) memory to me. Also vmap must be system memory - but this is maybe fixed later.> * @fb: DRM framebuffer > * @clip: Clip rectangle area to copy > * @cached: Source buffer is mapped cached (eg. not write-combined) > @@ -209,24 +209,42 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels > * 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 = format->cpp[0];u8 cpp = 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; > + > + 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);Here vmap is assumes system memory, not IO. I assume this is fixed later.> } > EXPORT_SYMBOL(drm_fb_swab); > > diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c > index 22451806fb5c..973a75585cad 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
Sam Ravnborg
2022-Aug-04  20:10 UTC
[PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
Hi Thomas, On Wed, Jul 27, 2022 at 01:33:04PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>I am not going to repeat my naming rant here, so Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> --- > drivers/gpu/drm/drm_format_helper.c | 25 ++++++++++++++----- > drivers/gpu/drm/gud/gud_pipe.c | 2 +- > .../gpu/drm/tests/drm_format_helper_test.c | 14 ++++++----- > include/drm/drm_format_helper.h | 5 ++-- > 4 files changed, 31 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index fa22d3cb11e8..2b5c3746ff4a 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -265,18 +265,31 @@ 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 two consecutive scanlines within dst > + * @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. > */ > -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; > + > + 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 98583bf56044..b74dba06f704 100644 > --- a/drivers/gpu/drm/tests/drm_format_helper_test.c > +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c > @@ -124,7 +124,8 @@ static void xrgb8888_to_rgb332_test(struct kunit *test) > { > const struct xrgb8888_to_rgb332_case *params = test->param_value; > size_t dst_size; > - __u8 *dst = NULL; > + struct iosys_map dst, xrgb8888; > + __u8 *buf = NULL; > > struct drm_framebuffer fb = { > .format = drm_format_info(DRM_FORMAT_XRGB8888), > @@ -135,12 +136,13 @@ 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); > > - drm_fb_xrgb8888_to_rgb332(dst, params->dst_pitch, params->xrgb8888, > - &fb, ¶ms->clip); > - KUNIT_EXPECT_EQ(test, memcmp(dst, params->expected, dst_size), 0); > + iosys_map_set_vaddr(&dst, buf); > + iosys_map_set_vaddr(&xrgb8888, (void __force *)params->xrgb8888); > + drm_fb_xrgb8888_to_rgb332(&dst, ¶ms->dst_pitch, &xrgb8888, &fb, ¶ms->clip); > + KUNIT_EXPECT_EQ(test, memcmp(buf, params->expected, dst_size), 0); > } > > static struct kunit_case drm_format_helper_test_cases[] = { > 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
Sam Ravnborg
2022-Aug-04  20:12 UTC
[PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion
On Wed, Jul 27, 2022 at 01:33:05PM +0200, Thomas Zimmermann wrote:> 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(). > > 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/drm_mipi_dbi.c | 4 +- > drivers/gpu/drm/gud/gud_pipe.c | 3 +- > drivers/gpu/drm/tiny/cirrus.c | 3 +- > include/drm/drm_format_helper.h | 9 ++--- > 5 files changed, 30 insertions(+), 48 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 2b5c3746ff4a..8bf5655f5ce0 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -330,9 +330,9 @@ 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 two consecutive scanlines within dst > + * @vmap: Array of XRGB8888 source buffer > * @fb: DRM framebuffer > * @clip: Clip rectangle area to copy > * @swab: Swap bytes > @@ -340,43 +340,31 @@ 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 natively > * support XRGB8888. > */ > -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; > + > + 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) > { > @@ -605,8 +593,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 973a75585cad..d0bdbcb96705 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/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
Sam Ravnborg
2022-Aug-04  20:14 UTC
[PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion
On Wed, Jul 27, 2022 at 01:33:06PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> --- > drivers/gpu/drm/drm_format_helper.c | 48 ++++++++++++----------------- > 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, 25 insertions(+), 36 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 8bf5655f5ce0..4edab44336d8 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -383,41 +383,34 @@ 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 two consecutive scanlines within dst > + * @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) > +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(dst, dst_pitch, 3, src, fb, clip, false, drm_fb_xrgb8888_to_rgb888_line); > -} > -EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); > + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { > + 0, 0, 0, 0 > + }; > > -/** > - * 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 > - * > - * 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) > -{ > - drm_fb_xfrm_toio(dst, dst_pitch, 3, vaddr, fb, clip, false, > - drm_fb_xrgb8888_to_rgb888_line); > + if (!dst_pitch) > + dst_pitch = default_dst_pitch; > + > + 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) > { > @@ -598,8 +591,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
Sam Ravnborg
2022-Aug-04  20:15 UTC
[PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion
On Wed, Jul 27, 2022 at 01:33:07PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> --- > drivers/gpu/drm/drm_format_helper.c | 25 ++++++++++++++++++------- > 1 file changed, 18 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 4edab44336d8..5ef06f696657 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -430,12 +430,24 @@ 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; > + > + 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) > @@ -600,8 +612,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
Sam Ravnborg
2022-Aug-04  20:16 UTC
[PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion
On Wed, Jul 27, 2022 at 01:33:08PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> --- > drivers/gpu/drm/drm_format_helper.c | 25 ++++++++++++++++++------- > 1 file changed, 18 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 5ef06f696657..155827eebe99 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -465,12 +465,24 @@ 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; > + > + 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) > @@ -608,8 +620,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
Sam Ravnborg
2022-Aug-04  20:17 UTC
[PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion
On Wed, Jul 27, 2022 at 01:33:09PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > ---Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> drivers/gpu/drm/drm_format_helper.c | 35 +++++++++++++++++------------ > include/drm/drm_format_helper.h | 6 ++--- > 2 files changed, 24 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 155827eebe99..209f63b66c5f 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -504,26 +504,34 @@ 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 two consecutive scanlines within dst > + * @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. > */ > -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; > + > + 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) > { > @@ -628,8 +636,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
Sam Ravnborg
2022-Aug-04  20:19 UTC
[PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion
On Wed, Jul 27, 2022 at 01:33:10PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> --- > drivers/gpu/drm/drm_format_helper.c | 25 +++++++++++++++++++------ > 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, 31 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 209f63b66c5f..521932fac491 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -552,9 +552,9 @@ 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 number of bytes between two consecutive scanlines within dst > + * @vmap: Array of XRGB8888 source buffers > * @fb: DRM framebuffer > * @clip: Clip rectangle area to copy > * > @@ -567,10 +567,23 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned > * > * ITU BT.601 is 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; > + > + 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 8eddb020c43e..702350d0f8bc 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
Sam Ravnborg
2022-Aug-04  20:21 UTC
[PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion
On Wed, Jul 27, 2022 at 01:33:11PM +0200, Thomas Zimmermann wrote:> 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(). > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>Reviewed-by: Sam Ravnborg <sam at ravnborg.org>> --- > drivers/gpu/drm/drm_format_helper.c | 28 +++++++++++++++++++--------- > drivers/gpu/drm/solomon/ssd130x.c | 7 ++++--- > drivers/gpu/drm/tiny/repaper.c | 6 +++++- > include/drm/drm_format_helper.h | 5 +++-- > 4 files changed, 31 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index 521932fac491..d296d181659d 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -680,9 +680,9 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int > > /** > * drm_fb_xrgb8888_to_mono - Convert XRGB8888 to monochromeIt should be documented that this only supports system memory (no io memory support). Sam> - * @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 two consecutive scanlines within dst > + * @vmap: Array of XRGB8888 source buffers > * @fb: DRM framebuffer > * @clip: Clip rectangle area to copy > * > @@ -700,26 +700,36 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int > * 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 cma memory is write-combined so reads are uncached. > @@ -744,7 +754,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 5a3e3b78cd9e..aa7329a65c98 100644 > --- a/drivers/gpu/drm/solomon/ssd130x.c > +++ b/drivers/gpu/drm/solomon/ssd130x.c > @@ -537,11 +537,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; > @@ -555,7 +555,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 013790c45d0a..0cdf6ab8fcc5 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_cma_object *cma_obj = drm_fb_cma_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, cma_obj->vaddr, fb, &clip); > + iosys_map_set_vaddr(&dst, buf); > + iosys_map_set_vaddr(&vmap, cma_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
Sam Ravnborg
2022-Aug-05  17:52 UTC
[PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
Hi Thomas, On Wed, Jul 27, 2022 at 01:33:12PM +0200, Thomas Zimmermann wrote:> 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 duplucation.This is very nice patch that should come before all the conversion patches - but then you have had to come up with another name. So I think this is fine. A few comments below, mostly in the same area as the comments from Jos?. Sam> > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > --- > drivers/gpu/drm/drm_format_helper.c | 169 +++++++++++----------------- > 1 file changed, 64 insertions(+), 105 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index d296d181659d..35aebdb90165 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)) > +{Just to repeat myself a little, this assumes src (vmap) is always system memory (not io).> + static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { > + 0, 0, 0, 0 > + }; > + > + if (!dst_pitch) > + dst_pitch = default_dst_pitch; > + > + 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, false, xfrm_line); > + else > + return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0], > + vmap[0].vaddr, fb, clip, false, xfrm_line);It looks like vaddr_cached_hint is always false, so can we remove it?> +} > + > + > /** > * drm_fb_memcpy - Copy clip buffer > * @dst: Array of destination buffers > @@ -213,14 +236,10 @@ 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 = format->cpp[0]; > void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels); > > - switch (cpp) { > + switch (format->cpp[0]) { > case 4: > swab_line = drm_fb_swab32_line; > break; > @@ -230,21 +249,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; > - > - 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, format->cpp, vmap, fb, clip, cached, swab_line);In this case we pass fb->format-cpp as dst_pitch - so we could retreive is via the fb pointer.> } > EXPORT_SYMBOL(drm_fb_swab); > > @@ -277,19 +285,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; > - > - 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);Here we construct the dst_pixsize. What is needed to make us trust fb->format->cpp so we can just fetch the info from format_info and drop dst_pixsize? I do not see any lookup being necessary here or in the functions below. If we use cpp (or even better using a helper function that avoid the deprecated cpp), then adding support for planes is simpler. For now dst_pixsize only pass the size for the first plane and there are a lot of updates required to support additional planes. Maybe I miss something obvious?!?> } > EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); > > @@ -344,9 +345,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) > @@ -354,15 +356,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; > - > - 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); > > @@ -396,19 +390,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; > - > - 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); > > @@ -435,19 +422,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; > - > - 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) > @@ -470,19 +450,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; > - > - 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) > @@ -518,19 +491,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; > - > - 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) > @@ -571,19 +537,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; > - > - 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
Sam Ravnborg
2022-Aug-05  17:59 UTC
[PATCH 00/12] drm/format-helper: Move to struct iosys_map
Hi Thomas, On Wed, Jul 27, 2022 at 01:33:00PM +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.Thanks for looking into this - I like how we hide the memory details in the helpers (system vs io). And unifying the system and io variants makes the API simpler - also good.> Note that the > implementation still only supports source buffers in system memory.Yeah, I noted this in my feedback but realized only now that it is written here. I left a few comments (details only) in some of the patches, most are reviewed without comments. There is a few general things - mostly bikeshedding about naming and such. As usual ignore what you think is irrelevant. Sam