@@ -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)
@@ -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__ */
@@ -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__ */
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@pengutronix.de> --- 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(-)