ge2d: add custom matrix support [1/1]

PD#SWPL-25894

Problem:
GE2D Support color space convert

Solution:
add this support

Verify:
w400

Change-Id: I0d47c3bb7734fcc6246d7e01cf8b6902ff2a5c15
Signed-off-by: Cao Jian <jian.cao@amlogic.com>
This commit is contained in:
Cao Jian
2020-05-18 17:19:54 +08:00
committed by Chris
parent 8576733d66
commit db2dba6960
4 changed files with 193 additions and 123 deletions

View File

@@ -504,8 +504,10 @@ void ge2d_set_src2_dst_gen(struct ge2d_src2_dst_gen_s *cfg)
ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->dst_pic_struct, 14, 2);
}
void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg)
void ge2d_set_dp_gen(struct ge2d_config_s *config)
{
struct ge2d_dp_gen_s *cfg = &config->dp_gen;
unsigned int antiflick_color_filter_n1[] = {0, 8, 16, 32};
unsigned int antiflick_color_filter_n2[] = {128, 112, 96, 64};
unsigned int antiflick_color_filter_n3[] = {0, 8, 16, 32};
@@ -595,7 +597,6 @@ void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg)
((cfg->antiflick_color_filter_n1[3] & 0xff) << 0)
);
ge2d_reg_write(GE2D_ANTIFLICK_ALPHA_FILT0,
((cfg->antiflick_alpha_filter_th[0] & 0xff) << 24) |
((cfg->antiflick_alpha_filter_n3[0] & 0xff) << 16) |
@@ -624,107 +625,135 @@ void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg)
);
} else
ge2d_reg_set_bits(GE2D_ANTIFLICK_CTRL0, 0, 31, 1);
if (cfg->use_matrix_default & MATRIX_YCC_TO_RGB) {
/* ycbcr(16-235) to rgb(0-255) */
cfg->matrix_coef[0] = 0x4a8;
cfg->matrix_coef[1] = 0;
cfg->matrix_coef[2] = 0x662;
cfg->matrix_coef[3] = 0x4a8;
cfg->matrix_coef[4] = 0x1e6f;
cfg->matrix_coef[5] = 0x1cbf;
cfg->matrix_coef[6] = 0x4a8;
cfg->matrix_coef[7] = 0x811;
cfg->matrix_coef[8] = 0x0;
cfg->matrix_offset[0] = 0;
cfg->matrix_offset[1] = 0;
cfg->matrix_offset[2] = 0;
cfg->matrix_sat_in_en = 1;
cfg->matrix_minus_16_ctrl = 0x4;
cfg->matrix_sign_ctrl = 0x3;
} else if (cfg->use_matrix_default & MATRIX_RGB_TO_YCC) {
if (cfg->use_matrix_default & MATRIX_BT_709) {
/* VDIN_MATRIX_RGB_YUV709 */
/* 0 0.183 0.614 0.062 16 */
/* 0 -0.101 -0.338 0.439 128 */
/* 0 0.439 -0.399 -0.04 128 */
cfg->matrix_coef[0] = 0xbb;
cfg->matrix_coef[1] = 0x275;
cfg->matrix_coef[2] = 0x3f;
cfg->matrix_coef[3] = 0x1f99;
cfg->matrix_coef[4] = 0x1ea6;
cfg->matrix_coef[5] = 0x1c2;
cfg->matrix_coef[6] = 0x1c2;
cfg->matrix_coef[7] = 0x1e67;
cfg->matrix_coef[8] = 0x1fd7;
} else {
/* rgb(0-255) to ycbcr(16-235) */
/* 0.257 0.504 0.098 */
/* -0.148 -0.291 0.439 */
/* 0.439 -0.368 -0.071 */
cfg->matrix_coef[0] = 0x107;
cfg->matrix_coef[1] = 0x204;
cfg->matrix_coef[2] = 0x64;
cfg->matrix_coef[3] = 0x1f68;
cfg->matrix_coef[4] = 0x1ed6;
cfg->matrix_coef[5] = 0x1c2;
cfg->matrix_coef[6] = 0x1c2;
cfg->matrix_coef[7] = 0x1e87;
cfg->matrix_coef[8] = 0x1fb7;
if (cfg->use_matrix_default & MATRIX_CUSTOM) {
struct ge2d_matrix_s *matrix = &config->matrix_custom;
ge2d_log_dbg("using matrix_custom\n");
cfg->matrix_coef[0] = matrix->coef0;
cfg->matrix_coef[1] = matrix->coef1;
cfg->matrix_coef[2] = matrix->coef2;
cfg->matrix_coef[3] = matrix->coef3;
cfg->matrix_coef[4] = matrix->coef4;
cfg->matrix_coef[5] = matrix->coef5;
cfg->matrix_coef[6] = matrix->coef6;
cfg->matrix_coef[7] = matrix->coef7;
cfg->matrix_coef[8] = matrix->coef8;
cfg->matrix_offset[0] = matrix->offset0;
cfg->matrix_offset[1] = matrix->offset1;
cfg->matrix_offset[2] = matrix->offset2;
cfg->matrix_sat_in_en = matrix->sat_in_en;
ge2d_reg_write(GE2D_MATRIX_PRE_OFFSET,
(matrix->pre_offset0 << 20) |
(matrix->pre_offset1 << 10) |
matrix->pre_offset2);
} else {
if (cfg->use_matrix_default & MATRIX_YCC_TO_RGB) {
/* ycbcr(16-235) to rgb(0-255) */
cfg->matrix_coef[0] = 0x4a8;
cfg->matrix_coef[1] = 0;
cfg->matrix_coef[2] = 0x662;
cfg->matrix_coef[3] = 0x4a8;
cfg->matrix_coef[4] = 0x1e6f;
cfg->matrix_coef[5] = 0x1cbf;
cfg->matrix_coef[6] = 0x4a8;
cfg->matrix_coef[7] = 0x811;
cfg->matrix_coef[8] = 0x0;
cfg->matrix_offset[0] = 0;
cfg->matrix_offset[1] = 0;
cfg->matrix_offset[2] = 0;
cfg->matrix_sat_in_en = 1;
cfg->matrix_minus_16_ctrl = 0x4;
cfg->matrix_sign_ctrl = 0x3;
} else if (cfg->use_matrix_default & MATRIX_RGB_TO_YCC) {
if (cfg->use_matrix_default & MATRIX_BT_709) {
/* VDIN_MATRIX_RGB_YUV709 */
/* 0 0.183 0.614 0.062 16 */
/* 0 -0.101 -0.338 0.439 128 */
/* 0 0.439 -0.399 -0.04 128 */
cfg->matrix_coef[0] = 0xbb;
cfg->matrix_coef[1] = 0x275;
cfg->matrix_coef[2] = 0x3f;
cfg->matrix_coef[3] = 0x1f99;
cfg->matrix_coef[4] = 0x1ea6;
cfg->matrix_coef[5] = 0x1c2;
cfg->matrix_coef[6] = 0x1c2;
cfg->matrix_coef[7] = 0x1e67;
cfg->matrix_coef[8] = 0x1fd7;
} else {
/* rgb(0-255) to ycbcr(16-235) */
/* 0.257 0.504 0.098 */
/* -0.148 -0.291 0.439 */
/* 0.439 -0.368 -0.071 */
cfg->matrix_coef[0] = 0x107;
cfg->matrix_coef[1] = 0x204;
cfg->matrix_coef[2] = 0x64;
cfg->matrix_coef[3] = 0x1f68;
cfg->matrix_coef[4] = 0x1ed6;
cfg->matrix_coef[5] = 0x1c2;
cfg->matrix_coef[6] = 0x1c2;
cfg->matrix_coef[7] = 0x1e87;
cfg->matrix_coef[8] = 0x1fb7;
}
cfg->matrix_offset[0] = 16;
cfg->matrix_offset[1] = 128;
cfg->matrix_offset[2] = 128;
cfg->matrix_sat_in_en = 0;
cfg->matrix_minus_16_ctrl = 0;
cfg->matrix_sign_ctrl = 0;
} else if (cfg->use_matrix_default &
MATRIX_FULL_RANGE_YCC_TO_RGB) {
/* ycbcr (0-255) to rgb(0-255) */
/* 1, 0, 1.402 */
/* 1, -0.34414, -0.71414 */
/* 1, 1.772 0 */
cfg->matrix_coef[0] = 0x400;
cfg->matrix_coef[1] = 0;
cfg->matrix_coef[2] = 0x59c;
cfg->matrix_coef[3] = 0x400;
cfg->matrix_coef[4] = 0x1ea0;
cfg->matrix_coef[5] = 0x1d25;
cfg->matrix_coef[6] = 0x400;
cfg->matrix_coef[7] = 0x717;
cfg->matrix_coef[8] = 0;
cfg->matrix_offset[0] = 0;
cfg->matrix_offset[1] = 0;
cfg->matrix_offset[2] = 0;
cfg->matrix_sat_in_en = 0;
cfg->matrix_minus_16_ctrl = 0;
cfg->matrix_sign_ctrl = 0x3;
} else if (cfg->use_matrix_default &
MATRIX_RGB_TO_FULL_RANGE_YCC) {
cfg->matrix_coef[0] = 0x132;
cfg->matrix_coef[1] = 0x259;
cfg->matrix_coef[2] = 0x75;
cfg->matrix_coef[3] = 0x1f53;
cfg->matrix_coef[4] = 0x1ead;
cfg->matrix_coef[5] = 0x200;
cfg->matrix_coef[6] = 0x200;
cfg->matrix_coef[7] = 0x1e53;
cfg->matrix_coef[8] = 0x1fad;
cfg->matrix_offset[0] = 0;
cfg->matrix_offset[1] = 128;
cfg->matrix_offset[2] = 128;
cfg->matrix_sat_in_en = 0;
cfg->matrix_minus_16_ctrl = 0;
cfg->matrix_sign_ctrl = 0;
}
cfg->matrix_offset[0] = 16;
cfg->matrix_offset[1] = 128;
cfg->matrix_offset[2] = 128;
cfg->matrix_sat_in_en = 0;
cfg->matrix_minus_16_ctrl = 0;
cfg->matrix_sign_ctrl = 0;
} else if (cfg->use_matrix_default & MATRIX_FULL_RANGE_YCC_TO_RGB) {
/* ycbcr (0-255) to rgb(0-255) */
/* 1, 0, 1.402 */
/* 1, -0.34414, -0.71414 */
/* 1, 1.772 0 */
cfg->matrix_coef[0] = 0x400;
cfg->matrix_coef[1] = 0;
cfg->matrix_coef[2] = 0x59c;
cfg->matrix_coef[3] = 0x400;
cfg->matrix_coef[4] = 0x1ea0;
cfg->matrix_coef[5] = 0x1d25;
cfg->matrix_coef[6] = 0x400;
cfg->matrix_coef[7] = 0x717;
cfg->matrix_coef[8] = 0;
cfg->matrix_offset[0] = 0;
cfg->matrix_offset[1] = 0;
cfg->matrix_offset[2] = 0;
cfg->matrix_sat_in_en = 0;
cfg->matrix_minus_16_ctrl = 0;
cfg->matrix_sign_ctrl = 0x3;
} else if (cfg->use_matrix_default & MATRIX_RGB_TO_FULL_RANGE_YCC) {
cfg->matrix_coef[0] = 0x132;
cfg->matrix_coef[1] = 0x259;
cfg->matrix_coef[2] = 0x75;
cfg->matrix_coef[3] = 0x1f53;
cfg->matrix_coef[4] = 0x1ead;
cfg->matrix_coef[5] = 0x200;
cfg->matrix_coef[6] = 0x200;
cfg->matrix_coef[7] = 0x1e53;
cfg->matrix_coef[8] = 0x1fad;
cfg->matrix_offset[0] = 0;
cfg->matrix_offset[1] = 128;
cfg->matrix_offset[2] = 128;
cfg->matrix_sat_in_en = 0;
cfg->matrix_minus_16_ctrl = 0;
cfg->matrix_sign_ctrl = 0;
if (cfg->matrix_minus_16_ctrl)
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0x1f0, 20, 9);
else
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0, 20, 9);
if (cfg->matrix_sign_ctrl & 3)
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET,
((0x180 << 10) | 0x180), 0, 20);
else
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0, 0, 20);
}
if (cfg->matrix_minus_16_ctrl)
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0x1f0, 20, 9);
else
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0, 20, 9);
if (cfg->matrix_sign_ctrl & 3)
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET,
((0x180 << 10) | 0x180), 0, 20);
else
ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0, 0, 20);
ge2d_reg_write(GE2D_MATRIX_COEF00_01,
(cfg->matrix_coef[0] << 16) |
(cfg->matrix_coef[1] << 0)
@@ -761,7 +790,6 @@ void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg)
(cfg->matrix_offset[2] << 0)
);
ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->src1_gb_alpha, 0, 8);
ge2d_reg_set_bits(GE2D_GEN_CTRL2,
cfg->src1_gb_alpha_en, 29, 1);

View File

@@ -437,7 +437,7 @@ static int ge2d_process_work_queue(struct ge2d_context_s *wq)
ge2d_set_src2_dst_gen(&cfg->src2_dst_gen);
break;
case UPDATE_DP_GEN:
ge2d_set_dp_gen(&cfg->dp_gen);
ge2d_set_dp_gen(cfg);
break;
case UPDATE_SCALE_COEF:
ge2d_set_src1_scale_coef(cfg->v_scale_coef_type,
@@ -2478,6 +2478,8 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context,
/* context->config.src1_data.ddr_burst_size_cb = 3; */
/* context->config.src1_data.ddr_burst_size_cr = 3; */
/* context->config.src2_dst_data.ddr_burst_size= 3; */
memcpy(&context->config.matrix_custom, &ge2d_config_mem->matrix_custom,
sizeof(struct ge2d_matrix_s));
return 0;
}

View File

@@ -46,6 +46,13 @@ static inline void _set_src1_format(struct ge2d_src1_data_s *src1_data_cfg,
else
src1_data_cfg->deep_color = 0;
if ((format_src & GE2D_MATRIX_CUSTOM) ||
(format_dst & GE2D_MATRIX_CUSTOM)) {
dp_gen_cfg->use_matrix_default = MATRIX_CUSTOM;
dp_gen_cfg->conv_matrix_en = 1;
return;
}
if ((format_src & GE2D_FORMAT_YUV) &&
((format_dst & GE2D_FORMAT_YUV) == 0)) {
dp_gen_cfg->use_matrix_default =
@@ -102,24 +109,6 @@ static inline void _set_dst_format(
src2_dst_data_cfg->dst_mode_8b_sel = (format_dst >> 6) & 3;
src2_dst_gen_cfg->dst_pic_struct = (format_dst >> 3) & 3;
if ((format_src & GE2D_FORMAT_YUV) &&
((format_dst & GE2D_FORMAT_YUV) == 0)) {
dp_gen_cfg->use_matrix_default =
(format_src & GE2D_FORMAT_FULL_RANGE) ?
MATRIX_FULL_RANGE_YCC_TO_RGB : MATRIX_YCC_TO_RGB;
dp_gen_cfg->conv_matrix_en = 1;
} else if (((format_src & GE2D_FORMAT_YUV) == 0) &&
(format_dst & GE2D_FORMAT_YUV)) {
dp_gen_cfg->use_matrix_default =
(format_dst & GE2D_FORMAT_FULL_RANGE) ?
MATRIX_RGB_TO_FULL_RANGE_YCC : MATRIX_RGB_TO_YCC;
dp_gen_cfg->use_matrix_default |=
((format_dst & GE2D_FORMAT_BT_STANDARD) ?
MATRIX_BT_709 : MATRIX_BT_601);
dp_gen_cfg->conv_matrix_en = 1;
} else
dp_gen_cfg->conv_matrix_en = 0;
y_yc_ratio = (format_dst >> 0) & 1;
/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
@@ -139,6 +128,31 @@ static inline void _set_dst_format(
} else
src2_dst_data_cfg->dst2_enable = 0;
/* #endif */
if ((format_src & GE2D_MATRIX_CUSTOM) ||
(format_dst & GE2D_MATRIX_CUSTOM)) {
dp_gen_cfg->use_matrix_default = MATRIX_CUSTOM;
dp_gen_cfg->conv_matrix_en = 1;
return;
}
if ((format_src & GE2D_FORMAT_YUV) &&
((format_dst & GE2D_FORMAT_YUV) == 0)) {
dp_gen_cfg->use_matrix_default =
(format_src & GE2D_FORMAT_FULL_RANGE) ?
MATRIX_FULL_RANGE_YCC_TO_RGB : MATRIX_YCC_TO_RGB;
dp_gen_cfg->conv_matrix_en = 1;
} else if (((format_src & GE2D_FORMAT_YUV) == 0) &&
(format_dst & GE2D_FORMAT_YUV)) {
dp_gen_cfg->use_matrix_default =
(format_dst & GE2D_FORMAT_FULL_RANGE) ?
MATRIX_RGB_TO_FULL_RANGE_YCC : MATRIX_RGB_TO_YCC;
dp_gen_cfg->use_matrix_default |=
((format_dst & GE2D_FORMAT_BT_STANDARD) ?
MATRIX_BT_709 : MATRIX_BT_601);
dp_gen_cfg->conv_matrix_en = 1;
} else
dp_gen_cfg->conv_matrix_en = 0;
}
void ge2dgen_src(struct ge2d_context_s *wq,

View File

@@ -135,11 +135,12 @@ enum ge2d_memtype_s {
#define MATRIX_BT_STANDARD (1 << 4)
#define MATRIX_BT_601 (0 << 4)
#define MATRIX_BT_709 (1 << 4)
#define MATRIX_CUSTOM BIT(5)
#define GE2D_FORMAT_BT_STANDARD (1 << 28)
#define GE2D_FORMAT_BT601 (0 << 28)
#define GE2D_FORMAT_BT709 (1 << 28)
#define GE2D_MATRIX_CUSTOM BIT(29)
#define GE2D_ENDIAN_SHIFT 24
#define GE2D_ENDIAN_MASK (0x1 << GE2D_ENDIAN_SHIFT)
@@ -641,6 +642,26 @@ struct ge2d_dma_cfg_s {
void *dma_cfg;
};
struct ge2d_matrix_s {
unsigned int pre_offset0;
unsigned int pre_offset1;
unsigned int pre_offset2;
unsigned int coef0;
unsigned int coef1;
unsigned int coef2;
unsigned int coef3;
unsigned int coef4;
unsigned int coef5;
unsigned int coef6;
unsigned int coef7;
unsigned int coef8;
unsigned int offset0;
unsigned int offset1;
unsigned int offset2;
/* input y/cb/cr saturation enable */
unsigned char sat_in_en;
};
struct ge2d_config_s {
struct ge2d_gen_s gen;
struct ge2d_src1_data_s src1_data;
@@ -657,6 +678,7 @@ struct ge2d_config_s {
struct ge2d_dma_cfg_s src_dma_cfg[MAX_PLANE];
struct ge2d_dma_cfg_s src2_dma_cfg[MAX_PLANE];
struct ge2d_dma_cfg_s dst_dma_cfg[MAX_PLANE];
struct ge2d_matrix_s matrix_custom;
};
struct ge2d_dma_buf_s {
@@ -1019,10 +1041,12 @@ struct compat_config_para_ex_ion_s {
struct config_para_ex_memtype_s {
int ge2d_magic;
struct config_para_ex_ion_s _ge2d_config_ex;
/* memtype*/
/* memtype */
unsigned int src1_mem_alloc_type;
unsigned int src2_mem_alloc_type;
unsigned int dst_mem_alloc_type;
/* for customized matrix */
struct ge2d_matrix_s matrix_custom;
};
struct config_ge2d_para_ex_s {
@@ -1041,6 +1065,8 @@ struct compat_config_para_ex_memtype_s {
unsigned int src1_mem_alloc_type;
unsigned int src2_mem_alloc_type;
unsigned int dst_mem_alloc_type;
/* for customized matrix */
struct ge2d_matrix_s matrix_custom;
};
struct compat_config_ge2d_para_ex_s {
@@ -1152,7 +1178,7 @@ extern void ge2d_set_src1_data(struct ge2d_src1_data_s *cfg);
extern void ge2d_set_src1_gen(struct ge2d_src1_gen_s *cfg);
extern void ge2d_set_src2_dst_data(struct ge2d_src2_dst_data_s *cfg);
extern void ge2d_set_src2_dst_gen(struct ge2d_src2_dst_gen_s *cfg);
extern void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg);
void ge2d_set_dp_gen(struct ge2d_config_s *config);
extern void ge2d_set_cmd(struct ge2d_cmd_s *cfg);
extern void ge2d_wait_done(void);
extern void ge2d_set_src1_scale_coef(unsigned int v_filt_type,