MLK-18560 drm/imx: lcdif: refine bus format sanity check for plane
authorFancy Fang <chen.fang@nxp.com>
Mon, 11 Jun 2018 07:57:48 +0000 (15:57 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
Add an function to get the LCDIF controller supported bus
formats according to the pixel format bpp. And change the
bus format sanity check in the plane's atomic check to see
if the bus format required by the peripheral attached to
LCDIF can be supported by LCDIF.

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

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

index bf8e949..e92fc61 100644 (file)
@@ -45,6 +45,9 @@ static int lcdif_plane_atomic_check(struct drm_plane *plane,
                                    struct drm_plane_state *plane_state)
 {
        int ret;
+       uint32_t bus_fmt;
+       struct lcdif_plane *lcdif_plane = to_lcdif_plane(plane);
+       struct lcdif_soc *lcdif = lcdif_plane->lcdif;
        struct drm_framebuffer *fb = plane_state->fb;
        struct drm_crtc_state *crtc_state;
        struct drm_display_mode *mode;
@@ -66,23 +69,14 @@ static int lcdif_plane_atomic_check(struct drm_plane *plane,
                                                        plane_state->crtc);
        mode = &crtc_state->adjusted_mode;
 
+       bus_fmt = lcdif_get_bus_fmt_from_pix_fmt(lcdif, fb->format->format);
+       if (bus_fmt < 0)
+               return -EINVAL;
+
        /* check fb pixel format matches bus format */
        flags = mode->private_flags & 0xffff;
-
-       switch (fb->format->format) {
-       case DRM_FORMAT_RGB565:
-               if (flags != MEDIA_BUS_FMT_RGB565_1X16)
-                       return -EINVAL;
-               break;
-       case DRM_FORMAT_ARGB8888:
-       case DRM_FORMAT_XRGB8888:
-               if (flags != MEDIA_BUS_FMT_RGB888_1X24)
-                       return -EINVAL;
-               break;
-       default:
-               /* TODO: add other formats support later */
+       if (flags != bus_fmt)
                return -EINVAL;
-       }
 
        ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
                                                  DRM_PLANE_HELPER_NO_SCALING,
index 252bb17..a680425 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/busfreq-imx.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
@@ -208,6 +209,58 @@ void lcdif_vblank_irq_clear(struct lcdif_soc *lcdif)
 }
 EXPORT_SYMBOL(lcdif_vblank_irq_clear);
 
+static uint32_t lcdif_get_bpp_from_fmt(uint32_t format)
+{
+       /* TODO: only support RGB for now */
+
+       switch (format) {
+       case DRM_FORMAT_RGB565:
+       case DRM_FORMAT_BGR565:
+       case DRM_FORMAT_ARGB1555:
+       case DRM_FORMAT_XRGB1555:
+       case DRM_FORMAT_ABGR1555:
+       case DRM_FORMAT_XBGR1555:
+               return 16;
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_RGBA8888:
+       case DRM_FORMAT_RGBX8888:
+               return 32;
+       default:
+               /* unsupported format */
+               return 0;
+       }
+}
+
+/*
+ * Get the bus format supported by LCDIF
+ * according to drm fourcc format
+ */
+int lcdif_get_bus_fmt_from_pix_fmt(struct lcdif_soc *lcdif,
+                                  uint32_t format)
+{
+       uint32_t bpp;
+
+       bpp = lcdif_get_bpp_from_fmt(format);
+       if (!bpp)
+               return -EINVAL;
+
+       switch (bpp) {
+       case 16:
+               return MEDIA_BUS_FMT_RGB565_1X16;
+       case 18:
+               return MEDIA_BUS_FMT_RGB666_1X18;
+       case 24:
+       case 32:
+               return MEDIA_BUS_FMT_RGB888_1X24;
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL(lcdif_get_bus_fmt_from_pix_fmt);
+
 int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format)
 {
        struct drm_format_name_buf format_name;
index 634a61e..ed43e80 100644 (file)
@@ -27,6 +27,8 @@ void lcdif_vblank_irq_enable(struct lcdif_soc *lcdif);
 void lcdif_vblank_irq_disable(struct lcdif_soc *lcdif);
 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_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr);
 void lcdif_set_mode(struct lcdif_soc *lcdif, struct videomode *vmode);