[PATCH 1/3] drm/mxsfb: use bus_format to determine pixel RGB component order

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The LCDIF controller v4, like the one included in the i.MX6UL,
can be configured to accept other RGB pixel formats. Extend
the driver to configure the controller to do so.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
 drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 41 +++++++++++++++++++++++++-----
 drivers/gpu/drm/mxsfb/mxsfb_drv.h  |  6 +++++
 drivers/gpu/drm/mxsfb/mxsfb_regs.h | 17 +++++++++++++
 3 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
index 24b1f0c1432e..1b5b1fddd691 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
@@ -97,29 +97,56 @@ static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb)
 	struct drm_crtc *crtc = &mxsfb->pipe.crtc;
 	struct drm_device *drm = crtc->dev;
 	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
-	u32 reg;
+	u32 ctrl, pattern;
 
-	reg = readl(mxsfb->base + LCDC_CTRL);
+	ctrl = readl(mxsfb->base + LCDC_CTRL);
 
 	if (mxsfb->connector.display_info.num_bus_formats)
 		bus_format = mxsfb->connector.display_info.bus_formats[0];
 
-	reg &= ~CTRL_BUS_WIDTH_MASK;
+	ctrl &= ~CTRL_BUS_WIDTH_MASK;
 	switch (bus_format) {
 	case MEDIA_BUS_FMT_RGB565_1X16:
-		reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
+		ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
+		pattern = CTRL2_PATTERN_RGB;
 		break;
 	case MEDIA_BUS_FMT_RGB666_1X18:
-		reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
+		ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
+		pattern = CTRL2_PATTERN_RGB;
 		break;
 	case MEDIA_BUS_FMT_RGB888_1X24:
-		reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+		ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+		pattern = CTRL2_PATTERN_RGB;
+		break;
+	case MEDIA_BUS_FMT_BGR888_1X24:
+		ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+		pattern = CTRL2_PATTERN_BGR;
+		break;
+	case MEDIA_BUS_FMT_RBG888_1X24:
+		ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+		pattern = CTRL2_PATTERN_RBG;
+		break;
+	case MEDIA_BUS_FMT_GBR888_1X24:
+		ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+		pattern = CTRL2_PATTERN_GBR;
 		break;
 	default:
+		pattern = CTRL2_PATTERN_RGB;
 		dev_err(drm->dev, "Unknown media bus format %d\n", bus_format);
 		break;
 	}
-	writel(reg, mxsfb->base + LCDC_CTRL);
+	writel(ctrl, mxsfb->base + LCDC_CTRL);
+
+	if (mxsfb_is_v4(mxsfb)) {
+		u32 ctrl2 = readl(mxsfb->base + LCDC_V4_CTRL2);
+		ctrl2 &= ~CTRL2_PATTERN_MASK;
+		ctrl2 |= CTRL2_SET_PATTERN(pattern);
+		writel(ctrl2, mxsfb->base + LCDC_V4_CTRL2);
+	} else if (pattern != CTRL2_PATTERN_RGB) {
+		/* RGB is default, so only warn for other patterns */
+		dev_err(drm->dev, "Unsupported media bus format %d\n",
+			bus_format);
+	}
 }
 
 static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 5d0883fc805b..89fa2076acaf 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -16,6 +16,8 @@
 #ifndef __MXSFB_DRV_H__
 #define __MXSFB_DRV_H__
 
+#include <linux/types.h>
+
 struct mxsfb_devdata {
 	unsigned int	 transfer_count;
 	unsigned int	 cur_buf;
@@ -50,5 +52,9 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb);
 void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb);
 void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
 			       struct drm_plane_state *state);
+static inline bool mxsfb_is_v4(const struct mxsfb_drm_private *mxsfb)
+{
+	return mxsfb->devdata->ipversion == 4;
+}
 
 #endif /* __MXSFB_DRV_H__ */
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_regs.h b/drivers/gpu/drm/mxsfb/mxsfb_regs.h
index 66a6ba9ec533..c5f4dea80093 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_regs.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_regs.h
@@ -22,6 +22,7 @@
 
 #define LCDC_CTRL			0x00
 #define LCDC_CTRL1			0x10
+#define LCDC_V4_CTRL2			0x20
 #define LCDC_V3_TRANSFER_COUNT		0x20
 #define LCDC_V4_TRANSFER_COUNT		0x30
 #define LCDC_V4_CUR_BUF			0x40
@@ -59,6 +60,15 @@
 #define CTRL1_CUR_FRAME_DONE_IRQ_EN	(1 << 13)
 #define CTRL1_CUR_FRAME_DONE_IRQ	(1 << 9)
 
+#define CTRL2_EVEN_LINE_PATTERN_MASK	(0x7 << 12)
+#define CTRL2_ODD_LINE_PATTERN_MASK	(0x7 << 16)
+#define CTRL2_PATTERN_MASK		(CTRL2_ODD_LINE_PATTERN_MASK |\
+					 CTRL2_EVEN_LINE_PATTERN_MASK)
+#define CTRL2_SET_EVEN_LINE_PATTERN(x)	(((x) & 0x7) << 12)
+#define CTRL2_SET_ODD_LINE_PATTERN(x)	(((x) & 0x7) << 16)
+#define CTRL2_SET_PATTERN(x)		(CTRL2_SET_EVEN_LINE_PATTERN(x) |\
+					 CTRL2_SET_ODD_LINE_PATTERN(x))
+
 #define TRANSFER_COUNT_SET_VCOUNT(x)	(((x) & 0xffff) << 16)
 #define TRANSFER_COUNT_GET_VCOUNT(x)	(((x) >> 16) & 0xffff)
 #define TRANSFER_COUNT_SET_HCOUNT(x)	((x) & 0xffff)
@@ -112,4 +122,11 @@
 #define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT	(1 << 6)
 #define MXSFB_SYNC_DOTCLK_FALLING_ACT	(1 << 7) /* negative edge sampling */
 
+#define CTRL2_PATTERN_RGB		0x0
+#define CTRL2_PATTERN_RBG		0x1
+#define CTRL2_PATTERN_GBR		0x2
+#define CTRL2_PATTERN_GRB		0x3
+#define CTRL2_PATTERN_BRG		0x4
+#define CTRL2_PATTERN_BGR		0x5
+
 #endif /* __MXSFB_REGS_H__ */
-- 
2.19.1

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux