MLK-19158-2 drm/imx: lcdif: improve output bus format config
authorFancy Fang <chen.fang@nxp.com>
Sun, 12 Aug 2018 00:58:43 +0000 (08:58 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
According to LCDIF specification, the input pixel data
width and the output pixel data width can be different,
and this conversion is done by LCDIF automatically. So
config the output data width according to the requested
bus format from the encoder, instead to be same with the
input pixel data width.

Signed-off-by: Fancy Fang <chen.fang@nxp.com>
(cherry picked from commit bfd27f6d71d86a7f2fc8314f082565db3682b925)
(cherry picked from commit a5940ee5db21adc76721d33c2171aa593d9a8ea8)

drivers/gpu/drm/imx/lcdif/lcdif-crtc.c
drivers/gpu/imx/lcdif/lcdif-common.c
include/video/imx-lcdif.h

index 91f09c7..e5c3b65 100644 (file)
@@ -140,6 +140,9 @@ static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc,
 
        lcdif_set_mode(lcdif, &vm);
 
+       /* config LCDIF output bus format */
+       lcdif_set_bus_fmt(lcdif, imx_crtc_state->bus_format);
+
        /* defer the lcdif controller enable to plane update,
         * since until then the lcdif config is complete to
         * enable the controller to run actually.
index af3ad16..f7b887c 100644 (file)
@@ -289,8 +289,7 @@ int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format)
 
        /* clear pixel format related bits */
        ctrl  &= ~(CTRL_SHIFT_NUM(0x3f)  | CTRL_INPUT_SWIZZLE(0x3) |
-                  CTRL_CSC_SWIZZLE(0x3) | CTRL_SET_BUS_WIDTH(0x3) |
-                  CTRL_SET_WORD_LENGTH(0x3));
+                  CTRL_CSC_SWIZZLE(0x3) | CTRL_SET_WORD_LENGTH(0x3));
 
        ctrl1 &= ~CTRL1_SET_BYTE_PACKAGING(0xf);
 
@@ -312,7 +311,6 @@ int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format)
                        format == DRM_FORMAT_BGR565) ?
                        (ctrl & ~CTRL_DF16) : (ctrl | CTRL_DF16);
 
-               ctrl |= CTRL_SET_BUS_WIDTH(0x0);
                ctrl |= CTRL_SET_WORD_LENGTH(0x0);
 
                /* Byte packing */
@@ -333,7 +331,6 @@ int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format)
        case DRM_FORMAT_RGBX8888:
                /*Data format */
                ctrl &= ~CTRL_DF24;
-               ctrl |= CTRL_SET_BUS_WIDTH(3);
                ctrl |= CTRL_SET_WORD_LENGTH(3);
 
                if (format == DRM_FORMAT_RGBA8888 ||
@@ -363,6 +360,30 @@ int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format)
 }
 EXPORT_SYMBOL(lcdif_set_pix_fmt);
 
+void lcdif_set_bus_fmt(struct lcdif_soc *lcdif, u32 bus_format)
+{
+       u32 bus_width;
+
+       switch (bus_format) {
+       case MEDIA_BUS_FMT_RGB565_1X16:
+               bus_width = CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
+               break;
+       case MEDIA_BUS_FMT_RGB666_1X18:
+               bus_width = CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
+               break;
+       case MEDIA_BUS_FMT_RGB888_1X24:
+               bus_width = CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+               break;
+       default:
+               dev_err(lcdif->dev, "unknown bus format: %#x\n", bus_format);
+               return;
+       }
+
+       writel(CTRL_SET_BUS_WIDTH(0x3), lcdif->base + LCDIF_CTRL + REG_CLR);
+       writel(bus_width, lcdif->base + LCDIF_CTRL + REG_SET);
+}
+EXPORT_SYMBOL(lcdif_set_bus_fmt);
+
 void lcdif_set_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr)
 {
        switch (id) {
index 6597e46..96b1248 100644 (file)
@@ -30,6 +30,7 @@ void lcdif_vblank_irq_clear(struct lcdif_soc *lcdif);
 int  lcdif_get_bus_fmt_from_pix_fmt(struct lcdif_soc *lcdif,
                                    uint32_t format);
 int  lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format);
+void lcdif_set_bus_fmt(struct lcdif_soc *lcdif, u32 bus_format);
 void lcdif_set_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr);
 void lcdif_set_mode(struct lcdif_soc *lcdif, struct videomode *vmode);
 void lcdif_set_fb_hcrop(struct lcdif_soc *lcdif, u32 src_w,