1
0
Fork 0

MLK-18560 drm/imx: lcdif: refine bus format sanity check for plane

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>
pull/10/head
Fancy Fang 2018-06-11 15:57:48 +08:00 committed by Jason Liu
parent 2e8b0ad6d4
commit 1919b00fd5
3 changed files with 63 additions and 14 deletions

View 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;
@ -67,23 +70,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;
}
clip.x2 = mode->hdisplay;
clip.y2 = mode->vdisplay;

View 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;

View 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);