summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-plane.c31
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchdecode.c28
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetcheco.c6
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchlayer.c6
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchwarp.c5
-rw-r--r--include/video/dpu.h5
6 files changed, 63 insertions, 18 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c
index 8f2d21fe932e..c0237a268e11 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-plane.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-plane.c
@@ -16,6 +16,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
+#include <drm/drm_color_mgmt.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_cma_helper.h>
@@ -88,6 +89,8 @@ static void dpu_plane_reset(struct drm_plane *plane)
__drm_atomic_helper_plane_reset(plane, &state->base);
plane->state->zpos = dpu_plane_get_default_zpos(plane->type);
+ plane->state->color_encoding = DRM_COLOR_YCBCR_BT601;
+ plane->state->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
}
static struct drm_plane_state *
@@ -223,6 +226,12 @@ drm_plane_state_to_uvbaseaddr(struct drm_plane_state *state, bool aux_source)
fb->format->cpp[1] * x;
}
+static inline bool dpu_plane_fb_format_is_yuv(u32 fmt)
+{
+ return fmt == DRM_FORMAT_YUYV || fmt == DRM_FORMAT_UYVY ||
+ fmt == DRM_FORMAT_NV12 || fmt == DRM_FORMAT_NV21;
+}
+
static int dpu_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
@@ -384,6 +393,12 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
break;
}
+ /* do not support BT709 full range */
+ if (dpu_plane_fb_format_is_yuv(fb->format->format) &&
+ state->color_encoding == DRM_COLOR_YCBCR_BT709 &&
+ state->color_range == DRM_COLOR_YCBCR_FULL_RANGE)
+ return -EINVAL;
+
again:
fu = source_to_fu(res,
check_aux_source ? dpstate->aux_source : dpstate->source);
@@ -749,7 +764,8 @@ again:
fu->ops->set_src_buf_dimensions(fu, src_w, src_h, 0, fb_is_interlaced);
fu->ops->set_pixel_blend_mode(fu, state->pixel_blend_mode,
state->alpha, fb->format->format);
- fu->ops->set_fmt(fu, fb->format->format, fb_is_interlaced);
+ fu->ops->set_fmt(fu, fb->format->format, state->color_encoding,
+ state->color_range, fb_is_interlaced);
fu->ops->enable_src_buf(fu);
fu->ops->set_framedimensions(fu, src_w, src_h, fb_is_interlaced);
fu->ops->set_baseaddress(fu, src_w, src_x, src_y, mt_w, mt_h, bpp,
@@ -780,7 +796,8 @@ again:
fe->ops->set_src_stride(fe, src_w, src_x, mt_w, bpp,
fb->pitches[1],
uv_baseaddr, use_prefetch);
- fe->ops->set_fmt(fe, fb->format->format, fb_is_interlaced);
+ fe->ops->set_fmt(fe, fb->format->format, state->color_encoding,
+ state->color_range, fb_is_interlaced);
fe->ops->set_src_buf_dimensions(fe, src_w, src_h,
fb->format->format,
fb_is_interlaced);
@@ -977,6 +994,16 @@ struct dpu_plane *dpu_plane_create(struct drm_device *drm,
if (ret)
goto err;
+ ret = drm_plane_create_color_properties(plane,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709),
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ DRM_COLOR_YCBCR_BT601,
+ DRM_COLOR_YCBCR_FULL_RANGE);
+ if (ret)
+ goto err;
+
return dpu_plane;
err:
diff --git a/drivers/gpu/imx/dpu/dpu-fetchdecode.c b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
index e1582a3a7bd0..fa9076c1be37 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchdecode.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
@@ -180,8 +180,11 @@ fetchdecode_set_src_buf_dimensions(struct dpu_fetchunit *fu,
mutex_unlock(&fu->mutex);
}
-static void
-fetchdecode_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool deinterlace)
+static void fetchdecode_set_fmt(struct dpu_fetchunit *fu,
+ u32 fmt,
+ enum drm_color_encoding color_encoding,
+ enum drm_color_range color_range,
+ bool deinterlace)
{
u32 val, bits, shift;
bool is_planar_yuv = false, is_rastermode_yuv422 = false;
@@ -242,17 +245,18 @@ fetchdecode_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool deinterlace)
val = dpu_fu_read(fu, LAYERPROPERTY0);
val &= ~YUVCONVERSIONMODE_MASK;
- if (need_csc)
- /*
- * assuming fetchdecode always ouputs RGB pixel formats
- *
- * FIXME:
- * determine correct standard here - ITU601 or ITU601_FR
- * or ITU709
- */
- val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__ITU601_FR);
- else
+ if (need_csc) {
+ /* assuming fetchdecode always ouputs RGB pixel formats */
+ if (color_encoding == DRM_COLOR_YCBCR_BT709)
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__ITU709);
+ else if (color_encoding == DRM_COLOR_YCBCR_BT601 &&
+ color_range == DRM_COLOR_YCBCR_FULL_RANGE)
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__ITU601_FR);
+ else
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__ITU601);
+ } else {
val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__OFF);
+ }
dpu_fu_write(fu, LAYERPROPERTY0, val);
mutex_unlock(&fu->mutex);
diff --git a/drivers/gpu/imx/dpu/dpu-fetcheco.c b/drivers/gpu/imx/dpu/dpu-fetcheco.c
index 9555ad229038..870e680f5cfb 100644
--- a/drivers/gpu/imx/dpu/dpu-fetcheco.c
+++ b/drivers/gpu/imx/dpu/dpu-fetcheco.c
@@ -79,7 +79,11 @@ fetcheco_set_src_buf_dimensions(struct dpu_fetchunit *fu,
mutex_unlock(&fu->mutex);
}
-static void fetcheco_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool unused)
+static void fetcheco_set_fmt(struct dpu_fetchunit *fu,
+ u32 fmt,
+ enum drm_color_encoding unused1,
+ enum drm_color_range unused2,
+ bool unused3)
{
u32 val, bits, shift;
int i, hsub, vsub;
diff --git a/drivers/gpu/imx/dpu/dpu-fetchlayer.c b/drivers/gpu/imx/dpu/dpu-fetchlayer.c
index 9e2d851b56e9..984679ec54d1 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchlayer.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchlayer.c
@@ -63,7 +63,11 @@ fetchlayer_set_src_buf_dimensions(struct dpu_fetchunit *fu,
mutex_unlock(&fu->mutex);
}
-static void fetchlayer_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool unused)
+static void fetchlayer_set_fmt(struct dpu_fetchunit *fu,
+ u32 fmt,
+ enum drm_color_encoding color_encoding,
+ enum drm_color_range color_range,
+ bool unused)
{
u32 val, bits, shift;
int i, sub_id = fu->sub_id;
diff --git a/drivers/gpu/imx/dpu/dpu-fetchwarp.c b/drivers/gpu/imx/dpu/dpu-fetchwarp.c
index a78d671aaa1b..aea9b9beb131 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchwarp.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchwarp.c
@@ -69,7 +69,10 @@ fetchwarp_set_src_buf_dimensions(struct dpu_fetchunit *fu,
}
static void fetchwarp_set_fmt(struct dpu_fetchunit *fu,
- u32 fmt, bool unused)
+ u32 fmt,
+ enum drm_color_encoding color_encoding,
+ enum drm_color_range color_range,
+ bool unused)
{
u32 val, bits, shift;
int i, sub_id = fu->sub_id;
diff --git a/include/video/dpu.h b/include/video/dpu.h
index 745676efe21a..b541d07513ef 100644
--- a/include/video/dpu.h
+++ b/include/video/dpu.h
@@ -348,7 +348,10 @@ struct dpu_fetchunit_ops {
unsigned int w, unsigned int h, u32 fmt,
bool deinterlace);
- void (*set_fmt)(struct dpu_fetchunit *fu, u32 fmt, bool deinterlace);
+ void (*set_fmt)(struct dpu_fetchunit *fu, u32 fmt,
+ enum drm_color_encoding color_encoding,
+ enum drm_color_range color_range,
+ bool deinterlace);
void (*set_pixel_blend_mode)(struct dpu_fetchunit *fu,
unsigned int pixel_blend_mode, u16 alpha,