amvecm: fix contrast adj without uv shift [1/1]
authorMingLiang Dong <mingliang.dong@amlogic.com>
Wed, 25 Sep 2019 14:56:25 +0000 (10:56 -0400)
committerTao Zeng <tao.zeng@amlogic.com>
Thu, 10 Oct 2019 06:57:31 +0000 (23:57 -0700)
PD#SWPL-14629

Problem:
fix contrast adj without uv shift

Solution:
workaround with vd1 mtx, add uv shift the same gain with your

Verify:
verify on TL1

Change-Id: I5456b75463ff2c999a8e6d4b42129a909ecfd666
Signed-off-by: MingLiang Dong <mingliang.dong@amlogic.com>
drivers/amlogic/media/enhancement/amvecm/amve.c

index 3ba09d6..58d4790 100644 (file)
@@ -461,6 +461,19 @@ static int bypass_coeff[MATRIX_5x3_COEF_SIZE] = {
        0, 0, 0 /* mode, right_shift, clip_en */
 };
 
+#define MTX_RS 0
+#define MTX_ENABLE 1
+#define MATRIX_3x3_COEF_SIZE 17
+static int matrix_yuv_bypass_coef[MATRIX_3x3_COEF_SIZE] = {
+       -64, -512, -512,
+       COEFF_NORM(1.0), COEFF_NORM(0), COEFF_NORM(0),
+       COEFF_NORM(0), COEFF_NORM(1.0), COEFF_NORM(0),
+       COEFF_NORM(0), COEFF_NORM(0), COEFF_NORM(1.0),
+       64, 512, 512,
+       MTX_RS,
+       MTX_ENABLE
+};
+
 void vpp_set_rgb_ogo(struct tcon_rgb_ogo_s *p)
 {
        int m[24];
@@ -1062,15 +1075,99 @@ void vpp_vd1_mtx_rgb_contrast(signed int cont_val, struct vframe_s *vf)
        WRITE_VPP_REG(XVYCC_VD1_RGB_CTRST, vd1_contrast);
 }
 
+void vpp_contrast_adj_by_uv(int cont_u, int cont_v)
+{
+       unsigned int coef00 = 0;
+       unsigned int coef01 = 0;
+       unsigned int coef02 = 0;
+       unsigned int coef10 = 0;
+       unsigned int coef11 = 0;
+       unsigned int coef12 = 0;
+       unsigned int coef20 = 0;
+       unsigned int coef21 = 0;
+       unsigned int coef22 = 0;
+       unsigned int offst0 = 0;
+       unsigned int offst1 = 0;
+       unsigned int offst2 = 0;
+       unsigned int pre_offst0 = 0;
+       unsigned int pre_offst1 = 0;
+       unsigned int pre_offst2 = 0;
+       unsigned int rs = 0;
+       unsigned int en = 0;
+
+       coef00 = matrix_yuv_bypass_coef[3];
+       coef01 = matrix_yuv_bypass_coef[4];
+       coef02 = matrix_yuv_bypass_coef[5];
+       coef10 = matrix_yuv_bypass_coef[6];
+       coef11 = cont_u;
+       coef12 = matrix_yuv_bypass_coef[8];
+       coef20 = matrix_yuv_bypass_coef[9];
+       coef21 = matrix_yuv_bypass_coef[10];
+       coef22 = cont_v;
+       pre_offst0 = matrix_yuv_bypass_coef[0];
+       pre_offst1 = matrix_yuv_bypass_coef[1];
+       pre_offst2 = matrix_yuv_bypass_coef[2];
+       offst0 = matrix_yuv_bypass_coef[12];
+       offst1 = matrix_yuv_bypass_coef[13];
+       offst2 = matrix_yuv_bypass_coef[14];
+       rs = matrix_yuv_bypass_coef[15];
+       en = matrix_yuv_bypass_coef[16];
+
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_COEF00_01,
+               ((coef00 & 0x1fff) << 16) | (coef01 & 0x1fff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_COEF02_10,
+               ((coef02 & 0x1fff) << 16) | (coef10 & 0x1fff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_COEF11_12,
+               ((coef11 & 0x1fff) << 16) | (coef12 & 0x1fff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_COEF20_21,
+               ((coef20 & 0x1fff) << 16) | (coef21 & 0x1fff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_COEF22,
+               (coef22 & 0x1fff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_OFFSET0_1,
+               ((offst0 & 0xfff) << 16) | (offst1 & 0xfff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_OFFSET2,
+               (offst2 & 0xfff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_PRE_OFFSET0_1,
+               ((pre_offst0 & 0xfff) << 16) |
+               (pre_offst1 & 0xfff));
+       WRITE_VPP_REG(
+               VPP_VD1_MATRIX_PRE_OFFSET2,
+               (pre_offst2 & 0xfff));
+
+       WRITE_VPP_REG_BITS(VPP_VD1_MATRIX_CLIP, rs, 5, 3);
+       WRITE_VPP_REG_BITS(VPP_VD1_MATRIX_EN_CTRL, en, 0, 1);
+}
 /*for gxbbtv contrast adj in vadj1*/
 void vpp_vd_adj1_contrast(signed int cont_val, struct vframe_s *vf)
 {
        unsigned int vd1_contrast;
        unsigned int vdj1_ctl;
+       int contrast_uv;
+       int contrast_u;
+       int contrast_v;
 
        if ((cont_val > 1023) || (cont_val < -1024))
                return;
+       contrast_uv = cont_val + 1024;
        cont_val = ((cont_val + 1024) >> 3);
+
+       if (contrast_uv < 1024) {
+               contrast_u = contrast_uv;
+               contrast_v = contrast_uv;
+       } else {
+               contrast_u = (0x600 - 0x400) * (contrast_uv - 0x400) / 0x400
+                       + 0x400;
+               contrast_v = contrast_uv;
+       }
+
        /*VPP_VADJ_CTRL bit 1 off for contrast adj*/
        vdj1_ctl = READ_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 1);
        if (is_meson_gxtvbb_cpu()) {
@@ -1086,6 +1183,8 @@ void vpp_vd_adj1_contrast(signed int cont_val, struct vframe_s *vf)
                vd1_contrast = (READ_VPP_REG(VPP_VADJ1_Y_2) & 0x7ff00) |
                                                (cont_val << 0);
                WRITE_VPP_REG(VPP_VADJ1_Y_2, vd1_contrast);
+
+               vpp_contrast_adj_by_uv(contrast_u, contrast_v);
                return;
        } else if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB) {
                vd1_contrast = (READ_VPP_REG(VPP_VADJ1_Y) & 0x3ff00) |