summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLiu Ying <victor.liu@nxp.com>2019-09-20 13:12:14 +0800
committerLiu Ying <victor.liu@nxp.com>2019-09-21 16:13:04 +0800
commitf4093c09bf997781eb1c236b21fe27ba907430bb (patch)
treeedad9a458e554a130ad18b3c0d4d098659c82c22 /drivers/gpu
parente9aa21938cdaf64cc049fb8fabb5bdf4c007ca75 (diff)
MLK-22649 drm/imx: dpu: plane: Add color properties support
As DPU fetchunits support ITU601(limited range)/ITU601_FR(full range) and ITU709(limited range) YUV to RGB color space conversions, we may add color encoding and color range properties support for planes. Considering software backward compatibility, the default color encoding is set to ITU601 with full color range. Signed-off-by: Liu Ying <victor.liu@nxp.com> (cherry picked from commit f491e24e65cb360fb0b3ce56f74d04fd80da77ab)
Diffstat (limited to 'drivers/gpu')
-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
5 files changed, 59 insertions, 17 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c
index 421e695c9c76..769d5a54f1c6 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_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>
@@ -84,6 +85,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 *
@@ -219,6 +222,12 @@ drm_plane_state_to_uvbaseaddr(struct drm_plane_state *state, bool aux_source)
drm_format_plane_cpp(fb->format->format, 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)
{
@@ -339,6 +348,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);
@@ -656,7 +671,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,
@@ -687,7 +703,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);
@@ -885,6 +902,16 @@ struct dpu_plane *dpu_plane_init(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 911c6905540f..818908f230f2 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchdecode.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
@@ -256,8 +256,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;
@@ -318,17 +321,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, val, LAYERPROPERTY0);
mutex_unlock(&fu->mutex);
diff --git a/drivers/gpu/imx/dpu/dpu-fetcheco.c b/drivers/gpu/imx/dpu/dpu-fetcheco.c
index e1f3708a6b80..731a580bacc8 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 583262851336..e61dcb6a2590 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchlayer.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchlayer.c
@@ -68,7 +68,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 bdc33582c092..d96bce39f490 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;