mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
amvecm: fix LC super white/black pattern issue [1/2]
PD#SWPL-12142 Problem: signal level of 107% block of super white/black pattern diff via enable/disable LC Solution: it is special limit range pattern but some pixels value > 235, use full range matrix to avoid clipping, this is per VLSI'e suggestion Verify: tl1 Change-Id: I82d26105a2404218b0c575a578874f88ae75d6c9 Signed-off-by: Xihai Zhu <xihai.zhu@amlogic.com>
This commit is contained in:
@@ -6338,6 +6338,20 @@ static ssize_t amvecm_lc_store(struct class *cls,
|
||||
goto free_buf;
|
||||
tune_curve_en = val;
|
||||
pr_info("tune_curve_en = %d\n", tune_curve_en);
|
||||
} else if (!strcmp(parm[0], "detect_signal_range_en")) {
|
||||
if (kstrtoul(parm[1], 10, &val) < 0)
|
||||
goto free_buf;
|
||||
amlc_debug = 0xe;
|
||||
detect_signal_range_en = val;
|
||||
pr_info("detect_signal_range_en = %d\n",
|
||||
detect_signal_range_en);
|
||||
} else if (!strcmp(parm[0], "detect_signal_range_threshold")) {
|
||||
if (kstrtoul(parm[1], 10, &val) < 0)
|
||||
goto free_buf;
|
||||
amlc_debug = 0xe;
|
||||
detect_signal_range_threshold = val;
|
||||
pr_info("detect_signal_range_threshold = %d\n",
|
||||
detect_signal_range_threshold);
|
||||
} else
|
||||
pr_info("unsupprt cmd!\n");
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ static unsigned int lc_satur_off[63] = {
|
||||
/*};*/
|
||||
|
||||
int tune_curve_en = 2;
|
||||
int detect_signal_range_en = 2;
|
||||
int detect_signal_range_threshold = 1000;
|
||||
|
||||
/*local contrast begin*/
|
||||
static void lc_mtx_set(enum lc_mtx_sel_e mtx_sel,
|
||||
@@ -290,6 +292,58 @@ static void lc_mtx_set(enum lc_mtx_sel_e mtx_sel,
|
||||
WRITE_VPP_REG(matrix_pre_offset2, 0x00000600);
|
||||
}
|
||||
break;
|
||||
case LC_MTX_RGB_YUV709:
|
||||
if (mtx_sel & (INP_MTX | OUTP_MTX)) {
|
||||
WRITE_VPP_REG(matrix_coef00_01, 0x00da02dc);
|
||||
WRITE_VPP_REG(matrix_coef02_10, 0x004a1f8a);
|
||||
WRITE_VPP_REG(matrix_coef11_12, 0x1e760200);
|
||||
WRITE_VPP_REG(matrix_coef20_21, 0x02001e2f);
|
||||
WRITE_VPP_REG(matrix_coef22, 0x00001fd1);
|
||||
if (bitdepth == 10) {
|
||||
WRITE_VPP_REG(matrix_offset0_1, 0x200);
|
||||
WRITE_VPP_REG(matrix_clip, 0x3ff);
|
||||
} else {
|
||||
WRITE_VPP_REG(matrix_offset0_1, 0x800);
|
||||
WRITE_VPP_REG(matrix_clip, 0xfff);
|
||||
}
|
||||
} else if (mtx_sel & STAT_MTX) {
|
||||
WRITE_VPP_REG(matrix_coef00_01, 0x00bb0275);
|
||||
WRITE_VPP_REG(matrix_coef02_10, 0x003f1f99);
|
||||
WRITE_VPP_REG(matrix_coef11_12, 0x1ea601c2);
|
||||
WRITE_VPP_REG(matrix_coef20_21, 0x01c21e67);
|
||||
WRITE_VPP_REG(matrix_coef22, 0x00001fd7);
|
||||
WRITE_VPP_REG(matrix_offset0_1, 0x00400200);
|
||||
WRITE_VPP_REG(matrix_offset2, 0x00000200);
|
||||
WRITE_VPP_REG(matrix_pre_offset0_1, 0x0);
|
||||
WRITE_VPP_REG(matrix_pre_offset2, 0x0);
|
||||
}
|
||||
break;
|
||||
case LC_MTX_YUV709_RGB:
|
||||
if (mtx_sel & (INP_MTX | OUTP_MTX)) {
|
||||
WRITE_VPP_REG(matrix_coef00_01, 0x01000000);
|
||||
WRITE_VPP_REG(matrix_coef02_10, 0x01930100);
|
||||
WRITE_VPP_REG(matrix_coef11_12, 0x1fd01f88);
|
||||
WRITE_VPP_REG(matrix_coef20_21, 0x010001db);
|
||||
WRITE_VPP_REG(matrix_coef22, 0x0);
|
||||
if (bitdepth == 10) {
|
||||
WRITE_VPP_REG(matrix_pre_offset0_1, 0x200);
|
||||
WRITE_VPP_REG(matrix_clip, 0x3ff);
|
||||
} else {
|
||||
WRITE_VPP_REG(matrix_pre_offset0_1, 0x800);
|
||||
WRITE_VPP_REG(matrix_clip, 0xfff);
|
||||
}
|
||||
} else if (mtx_sel & STAT_MTX) {
|
||||
WRITE_VPP_REG(matrix_coef00_01, 0x04000000);
|
||||
WRITE_VPP_REG(matrix_coef02_10, 0x064d0400);
|
||||
WRITE_VPP_REG(matrix_coef11_12, 0x1f411e21);
|
||||
WRITE_VPP_REG(matrix_coef20_21, 0x0400076d);
|
||||
WRITE_VPP_REG(matrix_coef22, 0x0);
|
||||
WRITE_VPP_REG(matrix_offset0_1, 0x0);
|
||||
WRITE_VPP_REG(matrix_offset2, 0x0);
|
||||
WRITE_VPP_REG(matrix_pre_offset0_1, 0x00000600);
|
||||
WRITE_VPP_REG(matrix_pre_offset2, 0x00000600);
|
||||
}
|
||||
break;
|
||||
case LC_MTX_NULL:
|
||||
if (mtx_sel & (INP_MTX | OUTP_MTX)) {
|
||||
WRITE_VPP_REG(matrix_coef00_01, 0x04000000);
|
||||
@@ -392,7 +446,9 @@ static void lc_stts_en(int enable,
|
||||
int hist_mode,
|
||||
int lpf_en,
|
||||
int din_sel,
|
||||
int bitdepth)
|
||||
int bitdepth,
|
||||
int flag,
|
||||
int flag_full)
|
||||
{
|
||||
int data32;
|
||||
|
||||
@@ -405,7 +461,17 @@ static void lc_stts_en(int enable,
|
||||
data32 = data32 | ((lpf_en & 0x1) << 21);
|
||||
WRITE_VPP_REG(LC_STTS_HIST_REGION_IDX, data32);
|
||||
|
||||
lc_mtx_set(STAT_MTX, LC_MTX_YUV709L_RGB, enable, bitdepth);
|
||||
if (flag == 0x3)
|
||||
lc_mtx_set(STAT_MTX, LC_MTX_YUV601L_RGB,
|
||||
enable, bitdepth);
|
||||
else {
|
||||
if (flag_full == 1)
|
||||
lc_mtx_set(STAT_MTX, LC_MTX_YUV709_RGB,
|
||||
enable, bitdepth);
|
||||
else
|
||||
lc_mtx_set(STAT_MTX, LC_MTX_YUV709L_RGB,
|
||||
enable, bitdepth);
|
||||
}
|
||||
|
||||
WRITE_VPP_REG_BITS(LC_STTS_CTRL0, din_sel, 3, 3);
|
||||
/*lc hist stts enable*/
|
||||
@@ -495,7 +561,8 @@ static void lc_blk_bdry_config(unsigned int height, unsigned int width)
|
||||
}
|
||||
|
||||
static void lc_top_config(int enable, int h_num, int v_num,
|
||||
unsigned int height, unsigned int width, int bitdepth, int flag)
|
||||
unsigned int height, unsigned int width, int bitdepth,
|
||||
int flag, int flag_full)
|
||||
{
|
||||
/*lcinput_ysel*/
|
||||
WRITE_VPP_REG_BITS(SRSHARP1_LC_INPUT_MUX, 5, 4, 3);
|
||||
@@ -525,8 +592,14 @@ static void lc_top_config(int enable, int h_num, int v_num,
|
||||
} else {
|
||||
/* all other cases use 709 by default */
|
||||
/* to do, should we handle bg2020 separately? */
|
||||
lc_mtx_set(INP_MTX, LC_MTX_YUV709L_RGB, 1, bitdepth);
|
||||
lc_mtx_set(OUTP_MTX, LC_MTX_RGB_YUV709L, 1, bitdepth);
|
||||
/* for special signal, keep full range to avoid clipping */
|
||||
if (flag_full == 1) {
|
||||
lc_mtx_set(INP_MTX, LC_MTX_YUV709_RGB, 1, bitdepth);
|
||||
lc_mtx_set(OUTP_MTX, LC_MTX_RGB_YUV709, 1, bitdepth);
|
||||
} else {
|
||||
lc_mtx_set(INP_MTX, LC_MTX_YUV709L_RGB, 1, bitdepth);
|
||||
lc_mtx_set(OUTP_MTX, LC_MTX_RGB_YUV709L, 1, bitdepth);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -547,6 +620,29 @@ static void lc_disable(void)
|
||||
lc_en_chflg = 0x0;
|
||||
}
|
||||
|
||||
/* detect super white and super black currently */
|
||||
static int signal_detect(unsigned short *hist)
|
||||
{
|
||||
unsigned short bin0, bin1, bin62, bin63;
|
||||
|
||||
bin0 = hist[0];
|
||||
bin1 = hist[1];
|
||||
bin62 = hist[62];
|
||||
bin63 = hist[63];
|
||||
|
||||
if (amlc_debug == 0xe) {
|
||||
pr_info("bin0=%d bin1=%d bin62=%d bin63=%d\n",
|
||||
bin0, bin1, bin62, bin63);
|
||||
amlc_debug = 0x0;
|
||||
}
|
||||
|
||||
if (((bin0 + bin1) > detect_signal_range_threshold) ||
|
||||
((bin62 + bin63) > detect_signal_range_threshold))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lc_config(int enable,
|
||||
struct vframe_s *vf,
|
||||
unsigned int sps_h_en,
|
||||
@@ -557,8 +653,8 @@ static void lc_config(int enable,
|
||||
{
|
||||
int h_num, v_num;
|
||||
unsigned int height, width;
|
||||
static unsigned int vf_height, vf_width;
|
||||
unsigned int flag;
|
||||
static unsigned int vf_height, vf_width, flag_full_pre;
|
||||
unsigned int flag, flag_full;
|
||||
|
||||
h_num = 12;
|
||||
v_num = 8;
|
||||
@@ -569,20 +665,34 @@ static void lc_config(int enable,
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to detect out of spec signal level */
|
||||
flag_full = 0;
|
||||
if (detect_signal_range_en == 2)
|
||||
flag_full = signal_detect(vf->prop.hist.vpp_gamma);
|
||||
else
|
||||
flag_full = detect_signal_range_en;
|
||||
|
||||
if (flag_full != flag_full_pre) {
|
||||
pr_info("signal changed, flag_full:%d->%d\n",
|
||||
flag_full_pre, flag_full);
|
||||
}
|
||||
|
||||
if ((vf_height == vf->height) &&
|
||||
(vf_width == vf->width)) {
|
||||
if (!lc_en_chflg)
|
||||
lc_en_chflg = 0xff;
|
||||
else
|
||||
(vf_width == vf->width) &&
|
||||
(flag_full == flag_full_pre) &&
|
||||
lc_en_chflg) {
|
||||
return;
|
||||
}
|
||||
|
||||
flag_full_pre = flag_full;
|
||||
height = sps_h_in << sps_h_en;
|
||||
width = sps_w_in << sps_v_en;
|
||||
|
||||
vf_height = vf->height;
|
||||
vf_width = vf->width;
|
||||
|
||||
lc_en_chflg = 0xff;
|
||||
|
||||
/*
|
||||
* bit 29: present_flag
|
||||
* bit 23-16: color_primaries
|
||||
@@ -597,14 +707,16 @@ static void lc_config(int enable,
|
||||
/* signal_type is not present */
|
||||
/* use default value bt709 */
|
||||
flag = 0x1;
|
||||
lc_top_config(enable, h_num, v_num, height, width, bitdepth, flag);
|
||||
lc_top_config(enable, h_num, v_num, height,
|
||||
width, bitdepth, flag, flag_full);
|
||||
|
||||
width = sps_w_in;
|
||||
height = sps_h_in;
|
||||
|
||||
lc_curve_ctrl_config(enable, height, width);
|
||||
lc_stts_blk_config(enable, height, width);
|
||||
lc_stts_en(enable, height, width, 0, 0, 1, 1, 4, bitdepth);
|
||||
lc_stts_en(enable, height, width, 0, 0, 1, 1, 4,
|
||||
bitdepth, flag, flag_full);
|
||||
}
|
||||
|
||||
static void tune_nodes_patch(int *omap, int *ihistogram, int reg_lmtrat_sigbin)
|
||||
@@ -1453,7 +1565,7 @@ void lc_init(int bitdepth)
|
||||
if (!lc_en)
|
||||
return;
|
||||
|
||||
lc_top_config(0, h_num, v_num, height, width, bitdepth, 1);
|
||||
lc_top_config(0, h_num, v_num, height, width, bitdepth, 1, 0);
|
||||
WRITE_VPP_REG_BITS(LC_CURVE_RAM_CTRL, 0, 0, 1);
|
||||
|
||||
/*default LC low parameters*/
|
||||
@@ -1519,7 +1631,6 @@ void lc_process(struct vframe_s *vf,
|
||||
lc_disable();
|
||||
return;
|
||||
}
|
||||
|
||||
if (vf == NULL) {
|
||||
if (lc_flag == 0xff) {
|
||||
lc_disable();
|
||||
|
||||
@@ -39,6 +39,8 @@ enum lc_mtx_csc_e {
|
||||
LC_MTX_RGB_YUV709L = 0x2,
|
||||
LC_MTX_YUV601L_RGB = 0x3,
|
||||
LC_MTX_RGB_YUV601L = 0x4,
|
||||
LC_MTX_YUV709_RGB = 0x5,
|
||||
LC_MTX_RGB_YUV709 = 0x6,
|
||||
LC_MTX_MAX
|
||||
};
|
||||
|
||||
@@ -64,6 +66,8 @@ struct lc_alg_param_s {
|
||||
extern int amlc_debug;
|
||||
extern int lc_reg_lmtrat_sigbin;
|
||||
extern int tune_curve_en;
|
||||
extern int detect_signal_range_en;
|
||||
extern int detect_signal_range_threshold;
|
||||
extern int lc_en;
|
||||
extern int lc_demo_mode;
|
||||
extern unsigned int lc_hist_vs;
|
||||
|
||||
Reference in New Issue
Block a user