drm/rockchip: rk3399 vop: add support win csc
support rgb2yuv for yuv output, the csc matrix maybe bt601,bt601l,bt709 and bt2020, depend on connect output color space. Change-Id: Ibd8defc9a2519f850d8f3af7ee350022e5ee2ee4 Signed-off-by: Sandy Huang <hjc@rock-chips.com>
This commit is contained in:
parent
543c0e7848
commit
b7618fd33c
|
|
@ -82,6 +82,7 @@ struct crtc_state {
|
|||
int crtc_y;
|
||||
int crtc_w;
|
||||
int crtc_h;
|
||||
bool yuv_overlay;
|
||||
struct rockchip_mcu_timing mcu_timing;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -236,6 +236,8 @@ static int rockchip_vop_init(struct display_state *state)
|
|||
|
||||
vop->grf_ctrl = vop_data->grf_ctrl;
|
||||
vop->line_flag = vop_data->line_flag;
|
||||
vop->csc_table = vop_data->csc_table;
|
||||
vop->win_csc = vop_data->win_csc;
|
||||
vop->version = vop_data->version;
|
||||
vop->max_output = vop_data->max_output;
|
||||
|
||||
|
|
@ -388,6 +390,7 @@ static int rockchip_vop_init(struct display_state *state)
|
|||
post_r2y_en = true;
|
||||
}
|
||||
|
||||
crtc_state->yuv_overlay = yuv_overlay;
|
||||
post_csc_mode = to_vop_csc_mode(conn_state->color_space);
|
||||
VOP_CTRL_SET(vop, bcsh_r2y_en, post_r2y_en);
|
||||
VOP_CTRL_SET(vop, bcsh_y2r_en, post_y2r_en);
|
||||
|
|
@ -584,6 +587,54 @@ static void scl_vop_cal_scl_fac(struct vop *vop,
|
|||
}
|
||||
}
|
||||
|
||||
static void vop_load_csc_table(struct vop *vop, u32 offset, const u32 *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* so far the csc offset is not 0 and in the feature the csc offset
|
||||
* impossible be 0, so when the offset is 0, should return here.
|
||||
*/
|
||||
if (!table || offset == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
vop_writel(vop, offset + i * 4, table[i]);
|
||||
}
|
||||
|
||||
static int rockchip_vop_setup_csc_table(struct display_state *state)
|
||||
{
|
||||
struct crtc_state *crtc_state = &state->crtc_state;
|
||||
struct connector_state *conn_state = &state->conn_state;
|
||||
struct vop *vop = crtc_state->private;
|
||||
const uint32_t *csc_table = NULL;
|
||||
|
||||
if (!vop->csc_table || !crtc_state->yuv_overlay)
|
||||
return 0;
|
||||
/* todo: only implement r2y*/
|
||||
switch (conn_state->color_space) {
|
||||
case V4L2_COLORSPACE_SMPTE170M:
|
||||
csc_table = vop->csc_table->r2y_bt601_12_235;
|
||||
break;
|
||||
case V4L2_COLORSPACE_REC709:
|
||||
case V4L2_COLORSPACE_DEFAULT:
|
||||
case V4L2_COLORSPACE_JPEG:
|
||||
csc_table = vop->csc_table->r2y_bt709;
|
||||
break;
|
||||
case V4L2_COLORSPACE_BT2020:
|
||||
csc_table = vop->csc_table->r2y_bt2020;
|
||||
break;
|
||||
default:
|
||||
csc_table = vop->csc_table->r2y_bt601;
|
||||
break;
|
||||
}
|
||||
|
||||
vop_load_csc_table(vop, vop->win_csc->r2y_offset, csc_table);
|
||||
VOP_WIN_CSC_SET(vop, r2y_en, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_vop_set_plane(struct display_state *state)
|
||||
{
|
||||
struct crtc_state *crtc_state = &state->crtc_state;
|
||||
|
|
@ -630,6 +681,7 @@ static int rockchip_vop_set_plane(struct display_state *state)
|
|||
|
||||
VOP_WIN_SET(vop, src_alpha_ctl, 0);
|
||||
|
||||
rockchip_vop_setup_csc_table(state);
|
||||
VOP_WIN_SET(vop, enable, 1);
|
||||
vop_cfg_done(vop);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
REG_SET(x, name, 0, (x)->ctrl->name, v)
|
||||
#define VOP_LINE_FLAG_SET(x, name, v) \
|
||||
REG_SET(x, name, 0, (x)->line_flag->name, v)
|
||||
#define VOP_WIN_CSC_SET(x, name, v) \
|
||||
REG_SET(x, name, 0, (x)->win_csc->name, v)
|
||||
|
||||
#define VOP_CTRL_GET(x, name) \
|
||||
vop_read_reg(x, 0, &vop->ctrl->name)
|
||||
|
|
@ -429,6 +431,23 @@ struct vop_rect {
|
|||
int height;
|
||||
};
|
||||
|
||||
struct vop_csc_table {
|
||||
const uint32_t *r2y_bt601;
|
||||
const uint32_t *r2y_bt601_12_235;
|
||||
const uint32_t *r2y_bt709;
|
||||
const uint32_t *r2y_bt2020;
|
||||
};
|
||||
|
||||
struct vop_csc {
|
||||
struct vop_reg y2r_en;
|
||||
struct vop_reg r2r_en;
|
||||
struct vop_reg r2y_en;
|
||||
|
||||
uint32_t y2r_offset;
|
||||
uint32_t r2r_offset;
|
||||
uint32_t r2y_offset;
|
||||
};
|
||||
|
||||
#define VOP_FEATURE_OUTPUT_10BIT BIT(0)
|
||||
|
||||
struct vop_data {
|
||||
|
|
@ -437,6 +456,8 @@ struct vop_data {
|
|||
const struct vop_win *win;
|
||||
const struct vop_line_flag *line_flag;
|
||||
const struct vop_grf_ctrl *grf_ctrl;
|
||||
const struct vop_csc_table *csc_table;
|
||||
const struct vop_csc *win_csc;
|
||||
int win_offset;
|
||||
int reg_len;
|
||||
u64 feature;
|
||||
|
|
@ -453,6 +474,8 @@ struct vop {
|
|||
const struct vop_win *win;
|
||||
const struct vop_line_flag *line_flag;
|
||||
const struct vop_grf_ctrl *grf_ctrl;
|
||||
const struct vop_csc_table *csc_table;
|
||||
const struct vop_csc *win_csc;
|
||||
int win_offset;
|
||||
struct vop_rect max_output;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -235,6 +235,42 @@ const struct vop_data rk3366_vop = {
|
|||
.reg_len = RK3366_DSP_VACT_ST_END_F1 * 4,
|
||||
};
|
||||
|
||||
static const uint32_t vop_csc_r2y_bt601[] = {
|
||||
0x02590132, 0xff530075, 0x0200fead, 0xfe530200,
|
||||
0x0000ffad, 0x00000200, 0x00080200, 0x00080200,
|
||||
};
|
||||
|
||||
static const uint32_t vop_csc_r2y_bt601_12_235[] = {
|
||||
0x02040107, 0xff680064, 0x01c2fed6, 0xffb7fe87,
|
||||
0x0000ffb7, 0x00010200, 0x00080200, 0x00080200,
|
||||
};
|
||||
|
||||
static const uint32_t vop_csc_r2y_bt709[] = {
|
||||
0x027500bb, 0xff99003f, 0x01c2fea5, 0xfe6801c2,
|
||||
0x0000ffd7, 0x00010200, 0x00080200, 0x00080200,
|
||||
};
|
||||
|
||||
static const uint32_t vop_csc_r2y_bt2020[] = {
|
||||
0x025300e6, 0xff830034, 0x01c1febd, 0xfe6401c1,
|
||||
0x0000ffdc, 0x00010200, 0x00080200, 0x00080200,
|
||||
};
|
||||
|
||||
static const struct vop_csc_table rk3399_csc_table = {
|
||||
.r2y_bt601 = vop_csc_r2y_bt601,
|
||||
.r2y_bt601_12_235 = vop_csc_r2y_bt601_12_235,
|
||||
.r2y_bt709 = vop_csc_r2y_bt709,
|
||||
.r2y_bt2020 = vop_csc_r2y_bt2020,
|
||||
};
|
||||
|
||||
static const struct vop_csc rk3399_win0_csc = {
|
||||
.r2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 0),
|
||||
.y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1),
|
||||
.r2y_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 2),
|
||||
.y2r_offset = RK3399_WIN0_YUV2YUV_Y2R,
|
||||
.r2r_offset = RK3399_WIN0_YUV2YUV_3X3,
|
||||
.r2y_offset = RK3399_WIN0_YUV2YUV_R2Y,
|
||||
};
|
||||
|
||||
const struct vop_data rk3399_vop_big = {
|
||||
.version = VOP_VERSION(3, 5),
|
||||
.max_output = {4096, 2160},
|
||||
|
|
@ -242,6 +278,8 @@ const struct vop_data rk3399_vop_big = {
|
|||
.ctrl = &rk3288_ctrl_data,
|
||||
.win = &rk3288_win01_data,
|
||||
.line_flag = &rk3366_vop_line_flag,
|
||||
.csc_table = &rk3399_csc_table,
|
||||
.win_csc = &rk3399_win0_csc,
|
||||
.reg_len = RK3399_DSP_VACT_ST_END_F1 * 4,
|
||||
};
|
||||
|
||||
|
|
@ -251,6 +289,8 @@ const struct vop_data rk3399_vop_lit = {
|
|||
.ctrl = &rk3288_ctrl_data,
|
||||
.win = &rk3288_win01_data,
|
||||
.line_flag = &rk3366_vop_line_flag,
|
||||
.csc_table = &rk3399_csc_table,
|
||||
.win_csc = &rk3399_win0_csc,
|
||||
.reg_len = RK3399_DSP_VACT_ST_END_F1 * 4,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue