dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] drm/format-helper: Move to struct iosys_map
@ 2022-07-27 11:33 Thomas Zimmermann
  2022-07-27 11:33 ` [PATCH 01/12] drm/format-helper: Provide drm_fb_blit() Thomas Zimmermann
                   ` (12 more replies)
  0 siblings, 13 replies; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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


^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH 01/12] drm/format-helper: Provide drm_fb_blit()
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 17:02   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() Thomas Zimmermann
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
  2022-07-27 11:33 ` [PATCH 01/12] drm/format-helper: Provide drm_fb_blit() Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 19:52   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map Thomas Zimmermann
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
  2022-07-27 11:33 ` [PATCH 01/12] drm/format-helper: Provide drm_fb_blit() Thomas Zimmermann
  2022-07-27 11:33 ` [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:08   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion Thomas Zimmermann
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (2 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-07-28  7:13   ` José Expósito
  2022-08-04 20:10   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion Thomas Zimmermann
                   ` (8 subsequent siblings)
  12 siblings, 2 replies; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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)
 				       &params->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, &params->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, &params->dst_pitch, &xrgb8888, &fb, &params->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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (3 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-07-30 12:27   ` José Expósito
  2022-08-04 20:12   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion Thomas Zimmermann
                   ` (7 subsequent siblings)
  12 siblings, 2 replies; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (4 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:14   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion Thomas Zimmermann
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (5 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:15   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion Thomas Zimmermann
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (6 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:16   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion Thomas Zimmermann
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (7 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:17   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion Thomas Zimmermann
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (8 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:19   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion Thomas Zimmermann
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (9 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-08-04 20:21   ` Sam Ravnborg
  2022-07-27 11:33 ` [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper Thomas Zimmermann
  2022-08-05 17:59 ` [PATCH 00/12] drm/format-helper: Move to struct iosys_map Sam Ravnborg
  12 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (10 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion Thomas Zimmermann
@ 2022-07-27 11:33 ` Thomas Zimmermann
  2022-07-28  7:26   ` José Expósito
  2022-08-05 17:52   ` Sam Ravnborg
  2022-08-05 17:59 ` [PATCH 00/12] drm/format-helper: Move to struct iosys_map Sam Ravnborg
  12 siblings, 2 replies; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-27 11:33 UTC (permalink / raw)
  To: sam, noralf, daniel, airlied, mripard, maarten.lankhorst,
	airlied, javierm, drawat.floss, kraxel, david, jose.exposito89
  Cc: linux-hyperv, Thomas Zimmermann, dri-devel, virtualization

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@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


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
  2022-07-27 11:33 ` [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion Thomas Zimmermann
@ 2022-07-28  7:13   ` José Expósito
  2022-07-28  7:27     ` Thomas Zimmermann
  2022-08-04 20:10   ` Sam Ravnborg
  1 sibling, 1 reply; 36+ messages in thread
From: José Expósito @ 2022-07-28  7:13 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam

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@suse.de>

Tested-by: José Expósito <jose.exposito89@gmail.com>
Reviewed-by: José Expósito <jose.exposito89@gmail.com>

I just ran the tests in x86_64 and UML and they work as expected.
I need to find some time to review all patches, but this one LGTM.

This series will cause conflicts with [1]. Depending on which patchset
gets merged earlier, we will have to resolve the conflicts in one
series or the other.

Best wishes,
Jose

[1] https://patchwork.kernel.org/project/dri-devel/list/?series=663266

> ---
>  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)
>  				       &params->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, &params->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, &params->dst_pitch, &xrgb8888, &fb, &params->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
> 

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-07-27 11:33 ` [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper Thomas Zimmermann
@ 2022-07-28  7:26   ` José Expósito
  2022-07-28  7:45     ` Thomas Zimmermann
  2022-08-05 17:52   ` Sam Ravnborg
  1 sibling, 1 reply; 36+ messages in thread
From: José Expósito @ 2022-07-28  7:26 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam

Hi!

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.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@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);
> +}
> +
> +

Nit: Extra blank 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,
>  	};

Could "dst_pixsize" be obtained from "drm_format_info->cpp"? (in all
conversion functions, not only in this one).

I think they are similar structures, so we might be able to reuse that
information.

>  
> -	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
> 

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
  2022-07-28  7:13   ` José Expósito
@ 2022-07-28  7:27     ` Thomas Zimmermann
  2022-07-28 17:47       ` José Expósito
  0 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-28  7:27 UTC (permalink / raw)
  To: José Expósito
  Cc: linux-hyperv, david, airlied, javierm, dri-devel, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam


[-- Attachment #1.1: Type: text/plain, Size: 7107 bytes --]

Hi

Am 28.07.22 um 09:13 schrieb José Expósito:
> 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@suse.de>
> 
> Tested-by: José Expósito <jose.exposito89@gmail.com>
> Reviewed-by: José Expósito <jose.exposito89@gmail.com>
> 
> I just ran the tests in x86_64 and UML and they work as expected.
> I need to find some time to review all patches, but this one LGTM.

Thanks a lot.

> 
> This series will cause conflicts with [1]. Depending on which patchset
> gets merged earlier, we will have to resolve the conflicts in one
> series or the other.

I've seen this. Go ahead and commit your patches if they are ready. I 
can easily rebase on top.

Best reards
Thomas

> 
> Best wishes,
> Jose
> 
> [1] https://patchwork.kernel.org/project/dri-devel/list/?series=663266
> 
>> ---
>>   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)
>>   				       &params->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, &params->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, &params->dst_pitch, &xrgb8888, &fb, &params->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
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-07-28  7:26   ` José Expósito
@ 2022-07-28  7:45     ` Thomas Zimmermann
  2022-07-28 18:23       ` José Expósito
  0 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-07-28  7:45 UTC (permalink / raw)
  To: José Expósito
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam


[-- Attachment #1.1: Type: text/plain, Size: 13634 bytes --]

Hi

Am 28.07.22 um 09:26 schrieb José Expósito:
> Hi!
> 
> 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.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@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);
>> +}
>> +
>> +
> 
> Nit: Extra blank line

Oh!

> 
>>   /**
>>    * 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,
>>   	};
> 
> Could "dst_pixsize" be obtained from "drm_format_info->cpp"? (in all
> conversion functions, not only in this one).

It could and I already considered it.  But it would require a pointer to 
the destination format's info, which we don't yet have here.  The info 
lookup is at [1], but it has linear complexity. So I was reluctant to 
use it.

The solution I have in mind is to pass in the dst format info from the 
calling driver. Drivers can look it up once and reuse it. But as that's 
a change to quite a few drivers, it's something for a separate patchset.

In general, we should make an effort to replace uses of 4CC codes with 
pointers to a format info.

Best regards
Thomas

[1] 
https://elixir.bootlin.com/linux/v5.18.14/source/drivers/gpu/drm/drm_fourcc.c#L132

> 
> I think they are similar structures, so we might be able to reuse that
> information.
> 
>>   
>> -	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
>>

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
  2022-07-28  7:27     ` Thomas Zimmermann
@ 2022-07-28 17:47       ` José Expósito
  0 siblings, 0 replies; 36+ messages in thread
From: José Expósito @ 2022-07-28 17:47 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, javierm, dri-devel, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam

On Thu, Jul 28, 2022 at 09:27:52AM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 28.07.22 um 09:13 schrieb José Expósito:
> > 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@suse.de>
> > 
> > Tested-by: José Expósito <jose.exposito89@gmail.com>
> > Reviewed-by: José Expósito <jose.exposito89@gmail.com>
> > 
> > I just ran the tests in x86_64 and UML and they work as expected.
> > I need to find some time to review all patches, but this one LGTM.
> 
> Thanks a lot.
> 
> > 
> > This series will cause conflicts with [1]. Depending on which patchset
> > gets merged earlier, we will have to resolve the conflicts in one
> > series or the other.
> 
> I've seen this. Go ahead and commit your patches if they are ready. I can
> easily rebase on top.
> 
> Best reards
> Thomas

OK, I just merged the series in drm-misc-next... With some conflicts in
drm-tip in unreleated files I'm trying to figure out on IRC.

But I think you should be able to rebase your series if you want to.

Jose

> > 
> > Best wishes,
> > Jose
> > 
> > [1] https://patchwork.kernel.org/project/dri-devel/list/?series=663266
> > 
> > > ---
> > >   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)
> > >   				       &params->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, &params->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, &params->dst_pitch, &xrgb8888, &fb, &params->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
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Ivo Totev




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-07-28  7:45     ` Thomas Zimmermann
@ 2022-07-28 18:23       ` José Expósito
  0 siblings, 0 replies; 36+ messages in thread
From: José Expósito @ 2022-07-28 18:23 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam

On Thu, Jul 28, 2022 at 09:45:27AM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 28.07.22 um 09:26 schrieb José Expósito:
> > Hi!
> > 
> > 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.
> > > 
> > > Signed-off-by: Thomas Zimmermann <tzimmermann@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);
> > > +}
> > > +
> > > +
> > 
> > Nit: Extra blank line
> 
> Oh!
> 
> > 
> > >   /**
> > >    * 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,
> > >   	};
> > 
> > Could "dst_pixsize" be obtained from "drm_format_info->cpp"? (in all
> > conversion functions, not only in this one).
> 
> It could and I already considered it.  But it would require a pointer to the
> destination format's info, which we don't yet have here.  The info lookup is
> at [1], but it has linear complexity. So I was reluctant to use it.
> 
> The solution I have in mind is to pass in the dst format info from the
> calling driver. Drivers can look it up once and reuse it. But as that's a
> change to quite a few drivers, it's something for a separate patchset.
> 
> In general, we should make an effort to replace uses of 4CC codes with
> pointers to a format info.

Cool, thanks for the explanation. I don't see an easy way to make
__drm_format_info O(1) without adding unnecessary complexity and
it is probably not worth it.

Jose


> Best regards
> Thomas
> 
> [1] https://elixir.bootlin.com/linux/v5.18.14/source/drivers/gpu/drm/drm_fourcc.c#L132
> 
> > 
> > I think they are similar structures, so we might be able to reuse that
> > information.
> > 
> > > -	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
> > > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Ivo Totev




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion
  2022-07-27 11:33 ` [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion Thomas Zimmermann
@ 2022-07-30 12:27   ` José Expósito
  2022-08-04 20:12   ` Sam Ravnborg
  1 sibling, 0 replies; 36+ messages in thread
From: José Expósito @ 2022-07-30 12:27 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, airlied, sam

Hi Thomas,

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@suse.de>

Tested-by: José Expósito <jose.exposito89@gmail.com>
Reviewed-by: José Expósito <jose.exposito89@gmail.com>

In order to continue working on the missing tests for drm_format_helper
I rebased your series on top of drm-misc-next and fixed the conflicts
in the tests [1]. It is an easy fix, but feel free to copy & paste the
code if you want to save a couple of minutes.

FWIW, I ran the existing test for RGB565 on little and big endian archs
and they are working as expected.

Jose

[1] https://github.com/JoseExposito/linux/commit/175af3a6b6b9b8013e9925c06b4951fffbbce15b

> ---
>  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
> 

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 01/12] drm/format-helper: Provide drm_fb_blit()
  2022-07-27 11:33 ` [PATCH 01/12] drm/format-helper: Provide drm_fb_blit() Thomas Zimmermann
@ 2022-08-04 17:02   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 17:02 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@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

The 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@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
  2022-07-27 11:33 ` [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() Thomas Zimmermann
@ 2022-08-04 19:52   ` Sam Ravnborg
  2022-08-08 12:07     ` Thomas Zimmermann
  0 siblings, 1 reply; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 19:52 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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() that
One 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@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
Document that this may be NULL, in which case the distance is considered
0.

> + * @vmap: Array of source buffers
It 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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map
  2022-07-27 11:33 ` [PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map Thomas Zimmermann
@ 2022-08-04 20:08   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:08 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@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
Document that it may be NULL?

> + * @vmap: Array of source buffers
Prefer 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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion
  2022-07-27 11:33 ` [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion Thomas Zimmermann
  2022-07-28  7:13   ` José Expósito
@ 2022-08-04 20:10   ` Sam Ravnborg
  1 sibling, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:10 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>

I am not going to repeat my naming rant here, so
Reviewed-by: Sam Ravnborg <sam@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)
>  				       &params->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, &params->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, &params->dst_pitch, &xrgb8888, &fb, &params->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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion
  2022-07-27 11:33 ` [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion Thomas Zimmermann
  2022-07-30 12:27   ` José Expósito
@ 2022-08-04 20:12   ` Sam Ravnborg
  1 sibling, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:12 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
Reviewed-by: Sam Ravnborg <sam@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion
  2022-07-27 11:33 ` [PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion Thomas Zimmermann
@ 2022-08-04 20:14   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:14 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
Reviewed-by: Sam Ravnborg <sam@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion
  2022-07-27 11:33 ` [PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion Thomas Zimmermann
@ 2022-08-04 20:15   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:15 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
Reviewed-by: Sam Ravnborg <sam@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion
  2022-07-27 11:33 ` [PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion Thomas Zimmermann
@ 2022-08-04 20:16   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:16 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
Reviewed-by: Sam Ravnborg <sam@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion
  2022-07-27 11:33 ` [PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion Thomas Zimmermann
@ 2022-08-04 20:17   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:17 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
> ---
Reviewed-by: Sam Ravnborg <sam@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion
  2022-07-27 11:33 ` [PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion Thomas Zimmermann
@ 2022-08-04 20:19   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:19 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
Reviewed-by: Sam Ravnborg <sam@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion
  2022-07-27 11:33 ` [PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion Thomas Zimmermann
@ 2022-08-04 20:21   ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-04 20:21 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@suse.de>
Reviewed-by: Sam Ravnborg <sam@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 monochrome
It 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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-07-27 11:33 ` [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper Thomas Zimmermann
  2022-07-28  7:26   ` José Expósito
@ 2022-08-05 17:52   ` Sam Ravnborg
  2022-08-08 11:40     ` Thomas Zimmermann
  1 sibling, 1 reply; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-05 17:52 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 00/12] drm/format-helper: Move to struct iosys_map
  2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
                   ` (11 preceding siblings ...)
  2022-07-27 11:33 ` [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper Thomas Zimmermann
@ 2022-08-05 17:59 ` Sam Ravnborg
  12 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-05 17:59 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-08-05 17:52   ` Sam Ravnborg
@ 2022-08-08 11:40     ` Thomas Zimmermann
  2022-08-08 18:25       ` Sam Ravnborg
  0 siblings, 1 reply; 36+ messages in thread
From: Thomas Zimmermann @ 2022-08-08 11:40 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: linux-hyperv, david, airlied, javierm, dri-devel, virtualization,
	drawat.floss, noralf, kraxel, airlied, jose.exposito89


[-- Attachment #1.1: Type: text/plain, Size: 14509 bytes --]

Hi Sam

Am 05.08.22 um 19:52 schrieb Sam Ravnborg:
> 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@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?

Always passing false is a bug. drm_fb_swab() uses vaddr_cached_hint and 
we should forward the value here.

> 
>> +}
>> +
>> +
>>   /**
>>    * 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.

I don't understand this comment. We're passing format->cpp as 
dst_pixsize. I've meanwhile updated the code to compute the value from 
drm_format_info_bpp().

> 
>>   }
>>   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?!?

I'm not sure what you're up to. As I said to Jose, we could pass the 
destination format around. But that would require an O(n) lookup of the 
format info, or changes to the calling drivers. Both are not really 
appropriate in this patchset.

For now, I store the pixsize here and that's it. We already had these 
constants in the code here, so at least it doesn't get worse.

Best regards
Thomas

> 
> 
>>   }
>>   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

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
  2022-08-04 19:52   ` Sam Ravnborg
@ 2022-08-08 12:07     ` Thomas Zimmermann
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Zimmermann @ 2022-08-08 12:07 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: linux-hyperv, david, airlied, dri-devel, javierm, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied


[-- Attachment #1.1: Type: text/plain, Size: 15472 bytes --]

Hi Sam,

thanks for reviewing the patchset.

Am 04.08.22 um 21:52 schrieb Sam Ravnborg:
> 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() that
> One of these is drm_fb_memcpy_toio()

I had to laugh when I re-read my mistake.

>> 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@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
> Document that this may be NULL, in which case the distance is considered
> 0.

Will be in the next iteration.

> 
>> + * @vmap: Array of source buffers
> It 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.

An additional note: I changed this in all the patches. The correct form is

   DIV_ROUND_UP(drm_format_info_bpp(), 8) // for pixels

or

   DIV_ROUND_UP(drm_format_info_bpp() * width, 8)   // for scanlines

just in case that we ever get non-aligned pixels.

> 
>> +		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).

I'll add a patch to rename vmap to src. The current name comes from 
'mapping in virtual memory'. It's not related to system memory. It was 
used because that's its name in many other places. But src is much 
better for the format helpers.

> 
>> +
>> +		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.

I'll add IOSYS_MAP_INIT_VADDR_IOMEM() to the next iteration. I'll also 
convert hyperv to the macro. We can init the address as long as we don't 
deref it.

Best regards
Thomas

> 
>>   
>> -	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
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper
  2022-08-08 11:40     ` Thomas Zimmermann
@ 2022-08-08 18:25       ` Sam Ravnborg
  0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2022-08-08 18:25 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: linux-hyperv, david, airlied, javierm, dri-devel, virtualization,
	drawat.floss, noralf, kraxel, jose.exposito89, airlied

Hi Thomas,

> > > -	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.
> 
> I don't understand this comment. We're passing format->cpp as dst_pixsize.
> I've meanwhile updated the code to compute the value from
> drm_format_info_bpp().

I wanted to ask if we could drop the format->cpp argument and in
drm_fb_xfrm() use fb->format to retrieve the char per pixel.
So we move this part down in drm_fb_xfrm(), rather than finding
the char per pixel in all callers.

Maybe some of the other callers do not allow this and then this comment
can be ignored.

I have not yet looked at the updated patch-set.

	Sam

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2022-08-08 18:25 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-27 11:33 [PATCH 00/12] drm/format-helper: Move to struct iosys_map Thomas Zimmermann
2022-07-27 11:33 ` [PATCH 01/12] drm/format-helper: Provide drm_fb_blit() Thomas Zimmermann
2022-08-04 17:02   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio() Thomas Zimmermann
2022-08-04 19:52   ` Sam Ravnborg
2022-08-08 12:07     ` Thomas Zimmermann
2022-07-27 11:33 ` [PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map Thomas Zimmermann
2022-08-04 20:08   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion Thomas Zimmermann
2022-07-28  7:13   ` José Expósito
2022-07-28  7:27     ` Thomas Zimmermann
2022-07-28 17:47       ` José Expósito
2022-08-04 20:10   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion Thomas Zimmermann
2022-07-30 12:27   ` José Expósito
2022-08-04 20:12   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion Thomas Zimmermann
2022-08-04 20:14   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion Thomas Zimmermann
2022-08-04 20:15   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion Thomas Zimmermann
2022-08-04 20:16   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion Thomas Zimmermann
2022-08-04 20:17   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion Thomas Zimmermann
2022-08-04 20:19   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion Thomas Zimmermann
2022-08-04 20:21   ` Sam Ravnborg
2022-07-27 11:33 ` [PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper Thomas Zimmermann
2022-07-28  7:26   ` José Expósito
2022-07-28  7:45     ` Thomas Zimmermann
2022-07-28 18:23       ` José Expósito
2022-08-05 17:52   ` Sam Ravnborg
2022-08-08 11:40     ` Thomas Zimmermann
2022-08-08 18:25       ` Sam Ravnborg
2022-08-05 17:59 ` [PATCH 00/12] drm/format-helper: Move to struct iosys_map Sam Ravnborg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).