diff options
-rw-r--r-- | drivers/gpu/drm/imx/dpu/dpu-plane.c | 31 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-fetchdecode.c | 28 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-fetcheco.c | 6 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-fetchlayer.c | 6 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-fetchwarp.c | 5 | ||||
-rw-r--r-- | include/video/dpu.h | 5 |
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, |