Commit 4618cb79 authored by Philipp Zabel's avatar Philipp Zabel

gpu: ipu-v3: Add Rec.709 limited range support to DP

Add YCbCr encoding and quantization range parameters to
ipu_dp_setup_channel() and configure the CSC DP matrix
accordingly.
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent 17b9a946
...@@ -651,10 +651,13 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, ...@@ -651,10 +651,13 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ics = ipu_drm_fourcc_to_colorspace(fb->format->format); ics = ipu_drm_fourcc_to_colorspace(fb->format->format);
switch (ipu_plane->dp_flow) { switch (ipu_plane->dp_flow) {
case IPU_DP_FLOW_SYNC_BG: case IPU_DP_FLOW_SYNC_BG:
ipu_dp_setup_channel(ipu_plane->dp, ics, IPUV3_COLORSPACE_RGB); ipu_dp_setup_channel(ipu_plane->dp, DRM_COLOR_YCBCR_BT601,
DRM_COLOR_YCBCR_LIMITED_RANGE, ics,
IPUV3_COLORSPACE_RGB);
break; break;
case IPU_DP_FLOW_SYNC_FG: case IPU_DP_FLOW_SYNC_FG:
ipu_dp_setup_channel(ipu_plane->dp, ics, ipu_dp_setup_channel(ipu_plane->dp, DRM_COLOR_YCBCR_BT601,
DRM_COLOR_YCBCR_LIMITED_RANGE, ics,
IPUV3_COLORSPACE_UNKNOWN); IPUV3_COLORSPACE_UNKNOWN);
break; break;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/err.h> #include <linux/err.h>
#include <drm/drm_color_mgmt.h>
#include <video/imx-ipu-v3.h> #include <video/imx-ipu-v3.h>
#include "ipu-prv.h" #include "ipu-prv.h"
...@@ -125,6 +126,8 @@ int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos) ...@@ -125,6 +126,8 @@ int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos)
EXPORT_SYMBOL_GPL(ipu_dp_set_window_pos); EXPORT_SYMBOL_GPL(ipu_dp_set_window_pos);
static void ipu_dp_csc_init(struct ipu_flow *flow, static void ipu_dp_csc_init(struct ipu_flow *flow,
enum drm_color_encoding ycbcr_enc,
enum drm_color_range range,
enum ipu_color_space in, enum ipu_color_space in,
enum ipu_color_space out, enum ipu_color_space out,
u32 place) u32 place)
...@@ -148,7 +151,18 @@ static void ipu_dp_csc_init(struct ipu_flow *flow, ...@@ -148,7 +151,18 @@ static void ipu_dp_csc_init(struct ipu_flow *flow,
flow->base + DP_CSC_0); flow->base + DP_CSC_0);
writel(0x200 | (2 << 14) | (0x200 << 16) | (2 << 30), writel(0x200 | (2 << 14) | (0x200 << 16) | (2 << 30),
flow->base + DP_CSC_1); flow->base + DP_CSC_1);
} else if (ycbcr_enc == DRM_COLOR_YCBCR_BT709) {
/* Rec.709 limited range */
writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0);
writel(0x0e5 | (0x095 << 16), flow->base + DP_CSC_A_1);
writel(0x3e5 | (0x3bc << 16), flow->base + DP_CSC_A_2);
writel(0x095 | (0x10e << 16), flow->base + DP_CSC_A_3);
writel(0x000 | (0x3e10 << 16) | (1 << 30),
flow->base + DP_CSC_0);
writel(0x09a | (1 << 14) | (0x3dbe << 16) | (1 << 30),
flow->base + DP_CSC_1);
} else { } else {
/* BT.601 limited range */
writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0); writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0);
writel(0x0cc | (0x095 << 16), flow->base + DP_CSC_A_1); writel(0x0cc | (0x095 << 16), flow->base + DP_CSC_A_1);
writel(0x3ce | (0x398 << 16), flow->base + DP_CSC_A_2); writel(0x3ce | (0x398 << 16), flow->base + DP_CSC_A_2);
...@@ -165,6 +179,8 @@ static void ipu_dp_csc_init(struct ipu_flow *flow, ...@@ -165,6 +179,8 @@ static void ipu_dp_csc_init(struct ipu_flow *flow,
} }
int ipu_dp_setup_channel(struct ipu_dp *dp, int ipu_dp_setup_channel(struct ipu_dp *dp,
enum drm_color_encoding ycbcr_enc,
enum drm_color_range range,
enum ipu_color_space in, enum ipu_color_space in,
enum ipu_color_space out) enum ipu_color_space out)
{ {
...@@ -183,7 +199,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, ...@@ -183,7 +199,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp,
* foreground and background are of same colorspace, put * foreground and background are of same colorspace, put
* colorspace converter after combining unit. * colorspace converter after combining unit.
*/ */
ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs, ipu_dp_csc_init(flow, ycbcr_enc, range,
flow->foreground.in_cs, flow->out_cs,
DP_COM_CONF_CSC_DEF_BOTH); DP_COM_CONF_CSC_DEF_BOTH);
} else { } else {
if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN || if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN ||
...@@ -192,10 +209,12 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, ...@@ -192,10 +209,12 @@ int ipu_dp_setup_channel(struct ipu_dp *dp,
* foreground identical to output, apply color * foreground identical to output, apply color
* conversion on background * conversion on background
*/ */
ipu_dp_csc_init(flow, flow->background.in_cs, ipu_dp_csc_init(flow, ycbcr_enc, range,
flow->background.in_cs,
flow->out_cs, DP_COM_CONF_CSC_DEF_BG); flow->out_cs, DP_COM_CONF_CSC_DEF_BG);
else else
ipu_dp_csc_init(flow, flow->foreground.in_cs, ipu_dp_csc_init(flow, ycbcr_enc, range,
flow->foreground.in_cs,
flow->out_cs, DP_COM_CONF_CSC_DEF_FG); flow->out_cs, DP_COM_CONF_CSC_DEF_FG);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/of.h> #include <linux/of.h>
#include <drm/drm_color_mgmt.h>
#include <media/v4l2-mediabus.h> #include <media/v4l2-mediabus.h>
#include <video/videomode.h> #include <video/videomode.h>
...@@ -330,6 +331,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp); ...@@ -330,6 +331,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp);
void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync); void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync);
void ipu_dp_disable(struct ipu_soc *ipu); void ipu_dp_disable(struct ipu_soc *ipu);
int ipu_dp_setup_channel(struct ipu_dp *dp, int ipu_dp_setup_channel(struct ipu_dp *dp,
enum drm_color_encoding ycbcr_enc, enum drm_color_range range,
enum ipu_color_space in, enum ipu_color_space out); enum ipu_color_space in, enum ipu_color_space out);
int ipu_dp_set_window_pos(struct ipu_dp *, u16 x_pos, u16 y_pos); int ipu_dp_set_window_pos(struct ipu_dp *, u16 x_pos, u16 y_pos);
int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha, int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment