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;
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,
#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>
}
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;
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);