[PATCH v3 2/8] drm: lcdif: don't clear unrelated bits in CTRLDESCL0_5 when setting up format

Lucas Stach l.stach at pengutronix.de
Thu Sep 28 04:36:23 PDT 2023


The CTRLDESCL0_5 register also holds other bits that are not related to the
format, which should not be overwritten when the format is set up. Use a
proper RMW access in lcdif_set_formats().

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
v3: no changes
v2: new patch
---
 drivers/gpu/drm/mxsfb/lcdif_kms.c | 40 +++++++++++++++----------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c
index 07e343e01f3e..e277592e5fa5 100644
--- a/drivers/gpu/drm/mxsfb/lcdif_kms.c
+++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c
@@ -166,6 +166,7 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
 	const u32 format = plane_state->fb->format->format;
 	bool in_yuv = false;
 	bool out_yuv = false;
+	u32 ctrl_desc_5;
 
 	switch (bus_format) {
 	case MEDIA_BUS_FMT_RGB565_1X16:
@@ -186,52 +187,49 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
 		break;
 	}
 
+	ctrl_desc_5 = readl(lcdif->base + LCDC_V8_CTRLDESCL0_5) &
+		      ~(CTRLDESCL0_5_BPP_MASK | CTRLDESCL0_5_YUV_FORMAT_MASK);
+
 	switch (format) {
 	/* RGB Formats */
 	case DRM_FORMAT_RGB565:
-		writel(CTRLDESCL0_5_BPP_16_RGB565,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_16_RGB565;
 		break;
 	case DRM_FORMAT_RGB888:
-		writel(CTRLDESCL0_5_BPP_24_RGB888,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_24_RGB888;
 		break;
 	case DRM_FORMAT_XRGB1555:
-		writel(CTRLDESCL0_5_BPP_16_ARGB1555,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_16_ARGB1555;
 		break;
 	case DRM_FORMAT_XRGB4444:
-		writel(CTRLDESCL0_5_BPP_16_ARGB4444,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_16_ARGB4444;
 		break;
 	case DRM_FORMAT_XBGR8888:
-		writel(CTRLDESCL0_5_BPP_32_ABGR8888,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_32_ABGR8888;
 		break;
 	case DRM_FORMAT_XRGB8888:
-		writel(CTRLDESCL0_5_BPP_32_ARGB8888,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_32_ARGB8888;
 		break;
 
 	/* YUV Formats */
 	case DRM_FORMAT_YUYV:
-		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_VY2UY1,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_YCbCr422 |
+			       CTRLDESCL0_5_YUV_FORMAT_VY2UY1;
 		in_yuv = true;
 		break;
 	case DRM_FORMAT_YVYU:
-		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_UY2VY1,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_YCbCr422 |
+			       CTRLDESCL0_5_YUV_FORMAT_UY2VY1;
 		in_yuv = true;
 		break;
 	case DRM_FORMAT_UYVY:
-		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_Y2VY1U,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_YCbCr422 |
+			       CTRLDESCL0_5_YUV_FORMAT_Y2VY1U;
 		in_yuv = true;
 		break;
 	case DRM_FORMAT_VYUY:
-		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_Y2UY1V,
-		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
+		ctrl_desc_5 |= CTRLDESCL0_5_BPP_YCbCr422 |
+			       CTRLDESCL0_5_YUV_FORMAT_Y2UY1V;
 		in_yuv = true;
 		break;
 
@@ -240,6 +238,8 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
 		break;
 	}
 
+	writel(ctrl_desc_5, lcdif->base + LCDC_V8_CTRLDESCL0_5);
+
 	/*
 	 * The CSC differentiates between "YCbCr" and "YUV", but the reference
 	 * manual doesn't detail how they differ. Experiments showed that the
-- 
2.39.2




More information about the linux-arm-kernel mailing list