diff mbox series

[RFC,13/16] drm/rockchip: ebc: Add a panel reflection option

Message ID 20220413221916.50995-14-samuel@sholland.org (mailing list archive)
State New, archived
Headers show
Series drm/rockchip: Rockchip EBC ("E-Book Controller") display driver | expand

Commit Message

Samuel Holland April 13, 2022, 10:19 p.m. UTC
Some panels, like the one in the PineNote, are reflected. Since the
driver already has to copy pixels, the driver can handle this with
little additional overhead.

Currently, there is no devicetree binding for this situation, so control
the behavior via a module parameter.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

 drivers/gpu/drm/rockchip/rockchip_ebc.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc.c b/drivers/gpu/drm/rockchip/rockchip_ebc.c
index 93d689ff0933..9d0b2cdc5fdc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_ebc.c
+++ b/drivers/gpu/drm/rockchip/rockchip_ebc.c
@@ -166,6 +166,10 @@  static bool direct_mode = true;
 module_param(direct_mode, bool, 0444);
 MODULE_PARM_DESC(direct_mode, "compute waveforms in software (software LUT)");
 
+static bool panel_reflection = true;
+module_param(panel_reflection, bool, 0644);
+MODULE_PARM_DESC(panel_reflection, "reflect the image horizontally");
+
 static bool skip_reset;
 module_param(skip_reset, bool, 0444);
 MODULE_PARM_DESC(skip_reset, "skip the initial display reset");
@@ -1046,23 +1050,29 @@  static bool rockchip_ebc_blit_fb(const struct rockchip_ebc_ctx *ctx,
 {
 	unsigned int dst_pitch = ctx->gray4_pitch;
 	unsigned int src_pitch = fb->pitches[0];
-	unsigned int x, y;
+	unsigned int start_x, x, y;
 	const void *src;
 	u8 changed = 0;
+	int delta_x;
 	void *dst;
 
+	delta_x = panel_reflection ? -1 : 1;
+	start_x = panel_reflection ? src_clip->x2 - 1 : src_clip->x1;
+
 	dst = ctx->final + dst_clip->y1 * dst_pitch + dst_clip->x1 / 2;
-	src = vaddr + src_clip->y1 * src_pitch + src_clip->x1 * fb->format->cpp[0];
+	src = vaddr + src_clip->y1 * src_pitch + start_x * fb->format->cpp[0];
 
 	for (y = src_clip->y1; y < src_clip->y2; y++) {
 		const u32 *sbuf = src;
 		u8 *dbuf = dst;
 
 		for (x = src_clip->x1; x < src_clip->x2; x += 2) {
-			u32 rgb0 = *sbuf++;
-			u32 rgb1 = *sbuf++;
+			u32 rgb0, rgb1;
 			u8 gray;
 
+			rgb0 = *sbuf; sbuf += delta_x;
+			rgb1 = *sbuf; sbuf += delta_x;
+
 			/* Truncate the RGB values to 5 bits each. */
 			rgb0 &= 0x00f8f8f8U; rgb1 &= 0x00f8f8f8U;
 			/* Put the sum 2R+5G+B in bits 24-31. */
@@ -1136,6 +1146,13 @@  static void rockchip_ebc_plane_atomic_update(struct drm_plane *plane,
 		dst_clip->x2 += adjust;
 		src_clip.x2  += adjust;
 
+		if (panel_reflection) {
+			int x1 = dst_clip->x1, x2 = dst_clip->x2;
+
+			dst_clip->x1 = plane_state->dst.x2 - x2;
+			dst_clip->x2 = plane_state->dst.x2 - x1;
+		}
+
 		if (!rockchip_ebc_blit_fb(ctx, dst_clip, vaddr,
 					  plane_state->fb, &src_clip)) {
 			/* Drop the area if the FB didn't actually change. */