dv: change the pps bypass logic when dv on for 962e
authorzhilei.wu <zhilei.wu@amlogic.com>
Wed, 22 Aug 2018 09:11:28 +0000 (17:11 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 27 Aug 2018 07:11:18 +0000 (00:11 -0700)
PD#168736: dv: change the pps bypass logic when dv on for 962e

Change-Id: Ib9ee85f975d63e2124f87bd3e0507095ab659760
Signed-off-by: zhilei.wu <zhilei.wu@amlogic.com>
drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c
drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h
drivers/amlogic/media/enhancement/amvecm/amcsc.c
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/video_sink/vpp.c
include/linux/amlogic/media/amdolbyvision/dolby_vision.h
include/linux/amlogic/media/video_sink/vpp.h

index 47b45aa..f7ec16b 100644 (file)
@@ -67,9 +67,9 @@ struct amdolby_vision_dev_s {
        struct device               *dev;
        struct class                *clsp;
 };
-
 static struct amdolby_vision_dev_s amdolby_vision_dev;
 struct dv_device_data_s dv_meson_dev;
+static unsigned int dolby_vision_request_mode = 0xff;
 
 #define DOLBY_VISION_OUTPUT_MODE_IPT                   0
 #define DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL            1
@@ -193,6 +193,7 @@ static u32 last_dolby_vision_ll_policy = DOLBY_VISION_LL_DISABLE;
 
 static uint dolby_vision_on_count;
 
+#define FLAG_FORCE_CVM                         0x01
 #define FLAG_BYPASS_CVM                                0x02
 #define FLAG_BYPASS_VPP                                0x04
 #define FLAG_USE_SINK_MIN_MAX          0x08
@@ -218,7 +219,7 @@ static uint dolby_vision_on_count;
 #define FLAG_FRAME_DELAY_MASK  0xf
 #define FLAG_FRAME_DELAY_SHIFT 16
 
-static unsigned int dolby_vision_flags = FLAG_BYPASS_VPP;
+static unsigned int dolby_vision_flags = FLAG_BYPASS_VPP | FLAG_FORCE_CVM;
 module_param(dolby_vision_flags, uint, 0664);
 MODULE_PARM_DESC(dolby_vision_flags, "\n dolby_vision_flags\n");
 
@@ -1030,6 +1031,59 @@ static void prepare_stb_dolby_core1_lut(uint32_t base, uint32_t *p_core1_lut)
        }
 }
 
+static bool skip_cvm_tbl[2][2][4][4] = {
+       { /* core1: video */
+               { /* video priority */
+                       {1, 1, 0, 0}, /* dv in */
+                       {1, 1, 0, 0}, /* hdr in */
+                       {0, 0, 1, 0}, /* sdr in */
+                       {0, 0, 0, 0}  /* only hdmi in */
+               },
+               { /* graphic priority */
+                       {0, 0, 0, 0}, /* dv in */
+                       {0, 0, 0, 0}, /* hdr in */
+                       {0, 0, 1, 0}, /* sdr in */
+                       {0, 0, 0, 0}  /* only hdmi in */
+               }
+       },
+       { /* core2: graphic */
+               { /* video priority */
+                       {0, 0, 0, 0}, /* dv in */
+                       {0, 0, 0, 0}, /* hdr in */
+                       {0, 0, 1, 0}, /* sdr in */
+                       {0, 0, 0, 0}  /* only hdmi in */
+               },
+               { /* graphic priority */
+                       {0, 0, 0, 0}, /* dv in */
+                       {0, 0, 0, 0}, /* hdr in */
+                       {0, 0, 1, 0}, /* sdr in */
+                       {0, 0, 0, 0}  /* only hdmi in */
+               }
+       }
+};
+
+static bool need_skip_cvm(unsigned int is_graphic)
+{
+       if (dolby_vision_flags & FLAG_CERTIFICAION)
+               return false;
+       if (dolby_vision_flags & FLAG_FORCE_CVM)
+               return false;
+#ifdef V2_4
+       return skip_cvm_tbl[is_graphic]
+               [dolby_vision_graphics_priority]
+               [new_dovi_setting.src_format == FORMAT_INVALID ?
+                       FORMAT_SDR : new_dovi_setting.src_format]
+               [new_dovi_setting.dovi_ll_enable ?
+                       FORMAT_DOVI_LL : new_dovi_setting.dst_format];
+#else
+       return skip_cvm_tbl[is_graphic]
+               [dolby_vision_graphics_priority]
+               [new_dovi_setting.src_format == FORMAT_INVALID ?
+                       FORMAT_SDR : new_dovi_setting.src_format]
+               [new_dovi_setting.dst_format];
+#endif
+}
+
 static int stb_dolby_core1_set(
        uint32_t dm_count,
        uint32_t comp_count,
@@ -1079,10 +1133,7 @@ static int stb_dolby_core1_set(
                (hpotch << 16) | vpotch);
        VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL2,
                (hsize << 16) | vsize);
-       if (dolby_vision_flags & FLAG_CERTIFICAION)
-               VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL6, 0xba000000);
-       else
-               VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL6, 0xb8000000);
+       VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL6, 0xba000000);
        if (dolby_vision_flags & FLAG_DISABLE_COMPOSER)
                composer_enable = 0;
        VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL0,
@@ -1119,14 +1170,13 @@ static int stb_dolby_core1_set(
                bypass_flag |= 1 << 12; /* bypass CSC */
        if (dolby_vision_flags & FLAG_BYPASS_CVM)
                bypass_flag |= 1 << 13; /* bypass CVM */
+       if (need_skip_cvm(0))
+               bypass_flag |= 1 << 13; /* bypass CVM when tunnel out */
        /* bypass composer to get 12bit when SDR and HDR source */
 #ifndef V2_4
        if (!dovi_src)
                bypass_flag |= 1 << 14; /* bypass composer */
 #endif
-       if ((scramble_en) && !(dolby_vision_flags & FLAG_CERTIFICAION))
-               bypass_flag |= 1 << 13; /* bypass CVM when tunnel out */
-
        if (dolby_vision_run_mode != 0xff)
                run_mode = dolby_vision_run_mode;
        else {
@@ -1223,7 +1273,8 @@ static uint32_t tv_run_mode(int vsize, bool hdmi, bool hdr10, int el_41_mode)
        }
        if (dolby_vision_flags & FLAG_BYPASS_CSC)
                run_mode |= 1 << 12; /* bypass CSC */
-       if (dolby_vision_flags & FLAG_BYPASS_CVM)
+       if ((dolby_vision_flags & FLAG_BYPASS_CVM)
+               && !(dolby_vision_flags & FLAG_FORCE_CVM))
                run_mode |= 1 << 13; /* bypass CVM */
        return run_mode;
 }
@@ -1281,10 +1332,7 @@ static int tv_dolby_core1_set(
 
        VSYNC_WR_MPEG_REG_BITS(DOLBY_TV_SWAP_CTRL6, 1, 20, 1);
        /* bypass dither */
-       if (dolby_vision_flags & FLAG_CERTIFICAION)
-               VSYNC_WR_MPEG_REG_BITS(DOLBY_TV_SWAP_CTRL6, 1, 25, 1);
-       else
-               VSYNC_WR_MPEG_REG_BITS(DOLBY_TV_SWAP_CTRL6, 0, 25, 1);
+       VSYNC_WR_MPEG_REG_BITS(DOLBY_TV_SWAP_CTRL6, 1, 25, 1);
        if (src_chroma_format == 2)
                VSYNC_WR_MPEG_REG_BITS(DOLBY_TV_SWAP_CTRL6, 1, 29, 1);
        else if (src_chroma_format == 1)
@@ -1509,11 +1557,8 @@ static int dolby_core1_set(
                bypass_flag |= 1 << 1;
        if (dolby_vision_flags & FLAG_BYPASS_CVM)
                bypass_flag |= 1 << 2;
-       if (scramble_en) {
-               /* bypass CVM when dolby output */
-               if (!(dolby_vision_flags & FLAG_CERTIFICAION))
-                       bypass_flag |= 1 << 2;
-       }
+       if (need_skip_cvm(0))
+               bypass_flag |= 1 << 2;
        if (el_41_mode)
                bypass_flag |= 1 << 3;
 
@@ -1656,6 +1701,7 @@ static int dolby_core2_set(
        bool set_lut = false;
        bool reset = false;
        uint32_t *last_dm = (uint32_t *)&dovi_setting.dm_reg2;
+       uint32_t bypass_flag = 0;
 
        if (dolby_vision_on
                && (dolby_vision_flags &
@@ -1697,8 +1743,14 @@ static int dolby_core2_set(
                VSYNC_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL5, 0x0);
        VSYNC_WR_MPEG_REG(DOLBY_CORE2A_DMA_CTRL, 0x0);
        VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 2, 1);
-       VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 1, 2);
-       VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 1, 2);
+       if (need_skip_cvm(1))
+               bypass_flag |= 1 << 0;
+       VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 2, 1);
+       VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 1,
+               2 | bypass_flag);
+       VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 1,
+               2 | bypass_flag);
+       VSYNC_WR_MPEG_REG(DOLBY_CORE2A_CTRL, 0);
 
        VSYNC_WR_MPEG_REG(DOLBY_CORE2A_CTRL, 0);
 
@@ -1761,7 +1813,8 @@ static int dolby_core3_set(
        int hsize,
        int vsize,
        int dolby_enable,
-       int scramble_en)
+       int scramble_en,
+       u8 pps_state)
 {
        uint32_t count;
        int i;
@@ -1796,10 +1849,13 @@ static int dolby_core3_set(
        if (dolby_vision_on &&
                ((last_dolby_vision_ll_policy !=
                dolby_vision_ll_policy) ||
-               new_dovi_setting.vsvdb_changed)) {
+               new_dovi_setting.mode_changed ||
+               new_dovi_setting.vsvdb_changed ||
+               pps_state)) {
                last_dolby_vision_ll_policy =
                        dolby_vision_ll_policy;
                new_dovi_setting.vsvdb_changed = 0;
+               new_dovi_setting.mode_changed = 0;
                /* TODO: verify 962e case */
                if (is_meson_gxm() ||
                        is_meson_g12a()) {
@@ -1821,26 +1877,31 @@ static int dolby_core3_set(
                        }
                } else if (is_meson_txlx_stbmode()
                        || force_stb_mode) {
+                       if (pps_state == 2) {
+                               VSYNC_WR_MPEG_REG_BITS(
+                                       VPP_DOLBY_CTRL,
+                                       1, 0, 1); /* skip pps/dither/cm */
+                               VSYNC_WR_MPEG_REG(
+                                       VPP_DAT_CONV_PARA0, 0x08000800);
+                       } else if (pps_state == 1) {
+                               VSYNC_WR_MPEG_REG_BITS(
+                                       VPP_DOLBY_CTRL,
+                                       0, 0, 1); /* enable pps/dither/cm */
+                               VSYNC_WR_MPEG_REG(
+                                       VPP_DAT_CONV_PARA0, 0x20002000);
+                       }
                        if (new_dovi_setting.dovi_ll_enable &&
                                new_dovi_setting.diagnostic_enable == 0) {
-                               VSYNC_WR_MPEG_REG(
-                                       VPP_DAT_CONV_PARA1,
-                                       0x8000800);
-                               /* enable wm tp vks*/
                                /*   bypass gainoff to vks */
                                VSYNC_WR_MPEG_REG_BITS(
-                                       VPP_DOLBY_CTRL, 1, 1, 2);
+                                       VPP_DOLBY_CTRL, 0, 2, 1);
                                VSYNC_WR_MPEG_REG_BITS(
                                        VPP_MATRIX_CTRL,
                                        1, 0, 1); /* post matrix */
                        } else {
                                /* bypass wm tp vks*/
-                               /* bypass gainoff to vks */
                                VSYNC_WR_MPEG_REG_BITS(
-                                       VPP_DOLBY_CTRL, 3, 1, 2);
-                               VSYNC_WR_MPEG_REG(
-                                       VPP_DAT_CONV_PARA1,
-                                       0x20002000);
+                                       VPP_DOLBY_CTRL, 1, 2, 1);
                                if (is_meson_txlx_tvmode())
                                        enable_rgb_to_yuv_matrix_for_dvll(
                                                0, NULL, 12);
@@ -1939,7 +2000,7 @@ static int dolby_core3_set(
 
 static void apply_stb_core_settings(
        int enable, unsigned int mask,
-       bool reset, u32 frame_size)
+       bool reset, u32 frame_size, u8 pps_state)
 {
        const struct vinfo_s *vinfo = get_current_vinfo();
        u32 h_size = (frame_size >> 16) & 0xffff;
@@ -2042,7 +2103,8 @@ static void apply_stb_core_settings(
                        vinfo->width, v_size,
                        1,
                        dolby_vision_mode ==
-                       DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL);
+                       DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL,
+                       pps_state);
 }
 
 static void osd_bypass(int bypass)
@@ -2330,7 +2392,7 @@ void enable_dolby_vision(int enable)
                                        /* 12->10 before vadj2*/
                                        /*   10->12 after gainoff */
                                        VSYNC_WR_MPEG_REG(
-                                               VPP_DAT_CONV_PARA1, 0x20002000);
+                                               VPP_DAT_CONV_PARA1, 0x08000800);
                                        WRITE_VPP_REG(0x33e7, 0xb);
                                } else {
                                        /* bypass all video effect */
@@ -2344,7 +2406,7 @@ void enable_dolby_vision(int enable)
                                        /* 12->10 before vadj2*/
                                        /*   10->12 after gainoff */
                                        VSYNC_WR_MPEG_REG(
-                                               VPP_DAT_CONV_PARA1, 0x20002000);
+                                               VPP_DAT_CONV_PARA1, 0x08000800);
                                }
                                VSYNC_WR_MPEG_REG(
                                        VPP_DUMMY_DATA1,
@@ -4539,7 +4601,7 @@ int dolby_vision_parse_metadata(
                        prepare_hdr10_param(p_mdc, &hdr10_param);
                        /* for 962x with v1.4 or stb with v2.3 may use 12 bit */
                        src_bdp = 10;
-                       memset(&req, 0, sizeof(req));
+                       req.dv_enhance_exist = 0;
                }
 #ifdef V2_4
                /* TODO: need 962e ? */
@@ -4558,7 +4620,9 @@ int dolby_vision_parse_metadata(
                        (src_format == FORMAT_DOVI ? "DOVI" :
                        (req.dv_enhance_exist ? "DOVI (el meta)" : "SDR")),
                        req.aux_size, req.dv_enhance_exist);
-
+               if ((src_format != FORMAT_DOVI)
+                       && !req.dv_enhance_exist)
+                       memset(&req, 0, sizeof(req));
                if (req.dv_enhance_exist &&
                        (toggle_mode == 1)) {
                        el_vf = dvel_vf_get();
@@ -4683,6 +4747,10 @@ int dolby_vision_parse_metadata(
        }
 
        check_format = src_format;
+       if (dolby_vision_request_mode != 0xff) {
+               dolby_vision_mode = dolby_vision_request_mode;
+               dolby_vision_request_mode = 0xff;
+       }
        current_mode = dolby_vision_mode;
 
        if (dolby_vision_policy_process(
@@ -4692,11 +4760,14 @@ int dolby_vision_parse_metadata(
                pr_dolby_dbg("[dolby_vision_parse_metadata] output change from %d to %d\n",
                        dolby_vision_mode, current_mode);
                dolby_vision_mode = current_mode;
+               if (is_dolby_vision_stb_mode())
+                       new_dovi_setting.mode_changed = 1;
        }
 
        if (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) {
                new_dovi_setting.video_width = 0;
                new_dovi_setting.video_height = 0;
+               new_dovi_setting.mode_changed = 0;
                return -1;
        }
 
@@ -4862,6 +4933,8 @@ int dolby_vision_parse_metadata(
                /* TODO: 962e need ? */
                if (is_osd_off)
                        force_reset_core2 = true;
+               if (new_dovi_setting.mode_changed)
+                       force_reset_core2 = true;
                is_osd_off = false;
        }
        if (dolby_vision_flags & FLAG_USE_SINK_MIN_MAX) {
@@ -5341,8 +5414,33 @@ static void update_dolby_vision_status(enum signal_format_e src_format)
        }
 }
 
+static u8 last_pps_state;
+static void bypass_pps_path(u8 pps_state)
+{
+       if (is_meson_txlx_package_962E()
+               || force_stb_mode) {
+               if (pps_state == 2) {
+                       VSYNC_WR_MPEG_REG_BITS(
+                               VPP_DOLBY_CTRL, 1, 0, 1);
+                       VSYNC_WR_MPEG_REG(
+                               VPP_DAT_CONV_PARA0, 0x08000800);
+               } else if (pps_state == 1) {
+                       VSYNC_WR_MPEG_REG_BITS(
+                               VPP_DOLBY_CTRL, 0, 0, 1);
+                       VSYNC_WR_MPEG_REG(
+                               VPP_DAT_CONV_PARA0, 0x20002000);
+               }
+       }
+       if (pps_state && last_pps_state != pps_state) {
+               pr_dolby_dbg("pps_state %d => %d\n",
+                       last_pps_state, pps_state);
+               last_pps_state = pps_state;
+       }
+}
+
 static unsigned int last_dolby_vision_policy;
-int dolby_vision_process(struct vframe_s *vf, u32 display_size)
+int dolby_vision_process(struct vframe_s *vf, u32 display_size,
+       u8 pps_state) /* 0: no change, 1: pps enable, 2: pps disable */
 {
        int src_chroma_format = 0;
        u32 h_size = (display_size >> 16) & 0xffff;
@@ -5465,7 +5563,8 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size)
                return 0;
        }
 
-       if (dolby_vision_flags & FLAG_CERTIFICAION)
+       if ((dolby_vision_flags & FLAG_CERTIFICAION)
+               || (dolby_vision_flags & FLAG_BYPASS_VPP))
                video_effect_bypass(1);
 
        if (!p_funcs) {
@@ -5542,7 +5641,8 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size)
                                        dovi_setting_video_flag,
                                        dolby_vision_mask & 0x7,
                                        reset_flag,
-                                       (h_size << 16) | v_size);
+                                       (h_size << 16) | v_size,
+                                       pps_state);
                                memcpy(&dovi_setting, &new_dovi_setting,
                                        sizeof(dovi_setting));
                                new_dovi_setting.video_width =
@@ -5554,6 +5654,7 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size)
                                        pr_dolby_dbg("first frame reset %d\n",
                                                reset_flag);
                                enable_dolby_vision(1);
+                               bypass_pps_path(pps_state);
                                core1_disp_hsize = h_size;
                                core1_disp_vsize = v_size;
                                /* send HDMI packet according to dst_format */
@@ -5585,7 +5686,9 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size)
                                        /* core 1 only */
                                        dolby_vision_mask & 0x1,
                                        reset_flag,
-                                       (h_size << 16) | v_size);
+                                       (h_size << 16) | v_size,
+                                       pps_state);
+                               bypass_pps_path(pps_state);
                                core1_disp_hsize = h_size;
                                core1_disp_vsize = v_size;
                                if (dolby_vision_on_count <=
@@ -5639,7 +5742,8 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size)
                                        /* core 1 only */
                                        dolby_vision_mask & 0x1,
                                        reset_flag,
-                                       (h_size << 16) | v_size);
+                                       (h_size << 16) | v_size,
+                                       pps_state);
                                core1_disp_hsize = h_size;
                                core1_disp_vsize = v_size;
                                if (dolby_vision_on_count <
@@ -5687,7 +5791,8 @@ void set_dolby_vision_mode(int mode)
 {
        if ((is_meson_gxm() || is_meson_txlx() ||
                is_meson_g12a())
-               && dolby_vision_enable) {
+               && dolby_vision_enable
+               && (dolby_vision_request_mode == 0xff)) {
                if (dolby_vision_policy_process(
                        &mode, FORMAT_SDR)) {
                        dolby_vision_set_toggle_flag(1);
index 9507337..7f99c4c 100644 (file)
@@ -516,6 +516,7 @@ struct dovi_setting_s {
        struct ext_md_s ext_md;
        uint32_t vsvdb_len;
        uint32_t vsvdb_changed;
+       uint32_t mode_changed;
 #endif
 };
 
index 2dc3d67..a5b4410 100644 (file)
@@ -180,6 +180,7 @@ void hdr_exit(void)
 }
 
 /*-----------------------------------------*/
+static void vpp_set_mtx_en_read(void);
 static void vpp_set_mtx_en_write(void);
 
 struct hdr_osd_reg_s hdr_osd_reg = {
@@ -1936,6 +1937,8 @@ static void print_vpp_matrix(int m_select, int *s, int on)
 
 static int *cur_osd_mtx = RGB709_to_YUV709l_coeff;
 static int *cur_post_mtx = bypass_coeff;
+static int *cur_vd1_mtx = bypass_coeff;
+static int cur_vd1_on = CSC_OFF;
 static int cur_post_on = CSC_OFF;
 void set_vpp_matrix(int m_select, int *s, int on)
 {
@@ -1957,6 +1960,8 @@ void set_vpp_matrix(int m_select, int *s, int on)
        } else if (m_select == VPP_MATRIX_VD1) {
                m = vd1_matrix_coeff;
                size = MATRIX_5x3_COEF_SIZE;
+               cur_vd1_mtx = s;
+               cur_vd1_on = on;
        } else if (m_select == VPP_MATRIX_VD2) {
                m = vd2_matrix_coeff;
                size = MATRIX_5x3_COEF_SIZE;
@@ -2461,6 +2466,8 @@ EXPORT_SYMBOL(enable_osd_path);
 static int32_t *post_mtx_backup;
 static int32_t post_on_backup;
 static bool restore_post_table;
+static int32_t *vd1_mtx_backup;
+static int32_t vd1_on_backup;
 int enable_rgb_to_yuv_matrix_for_dvll(
        int32_t on, uint32_t *coeff_orig, uint32_t bits)
 {
@@ -2479,6 +2486,8 @@ int enable_rgb_to_yuv_matrix_for_dvll(
                        dvll_RGB_to_YUV709l_coeff) {
                        post_mtx_backup = cur_post_mtx;
                        post_on_backup = cur_post_on;
+                       vd1_mtx_backup = cur_vd1_mtx;
+                       vd1_on_backup = cur_vd1_on;
                }
                coeff01 = coeff_orig[0];
                coeff23 = coeff_orig[1];
@@ -2527,11 +2536,23 @@ int enable_rgb_to_yuv_matrix_for_dvll(
                coeff[18] -= (0x1000 - coeff[3] - coeff[4] - coeff[5]) >> 1;
 
                coeff[22] = 2;
+               vpp_set_mtx_en_read();
+               VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, 0);
+               set_vpp_matrix(VPP_MATRIX_OSD,
+                       cur_osd_mtx, CSC_OFF);
+               set_vpp_matrix(VPP_MATRIX_VD1,
+                       cur_vd1_mtx, CSC_OFF);
                set_vpp_matrix(VPP_MATRIX_POST,
                        coeff, CSC_ON);
                vpp_set_mtx_en_write();
                restore_post_table = true;
        } else if (restore_post_table) {
+               vpp_set_mtx_en_read();
+               VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, 0);
+               set_vpp_matrix(VPP_MATRIX_OSD,
+                       cur_osd_mtx, CSC_OFF);
+               set_vpp_matrix(VPP_MATRIX_VD1,
+                       vd1_mtx_backup, cur_vd1_on);
                set_vpp_matrix(VPP_MATRIX_POST,
                        post_mtx_backup, post_on_backup);
                vpp_set_mtx_en_write();
index 24d35cf..287b55e 100644 (file)
@@ -2825,7 +2825,9 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                    &frame_parms[1] : &frame_parms[0];
 
                vpp_set_filters(process_3d_type, wide_setting, vf,
-                       next_frame_par, vinfo);
+                       next_frame_par, vinfo,
+                       (is_dolby_vision_on() &&
+                       is_dolby_vision_stb_mode()));
 
                /* apply new vpp settings */
                frame_par_ready_to_set = 1;
@@ -5311,7 +5313,11 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
 
                        amlog_mask_if(toggle_cnt > 0, LOG_MASK_FRAMESKIP,
                                      "skipped\n");
-
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+                       if (is_dolby_vision_enable()
+                               && dolby_vision_need_wait())
+                               break;
+#endif
                        set_hdr_to_frame(vf);
 
 #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
@@ -5328,11 +5334,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
                                0) == 1)
                                break;
 #endif
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-                       if (is_dolby_vision_enable()
-                       && dolby_vision_need_wait())
-                               break;
-#endif
                        /*
                         *two special case:
                         *case1:4k display case,input buffer not enough &
@@ -5559,6 +5560,8 @@ SET_FILTER:
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
        if (is_dolby_vision_enable()) {
                u32 frame_size = 0, h_size, v_size;
+               u8 pps_state = 0; /* pps no change */
+
                /* force toggle when keeping frame after playing */
                if ((cur_dispbuf == &vf_local)
                        && !toggle_vf
@@ -5583,6 +5586,24 @@ SET_FILTER:
                }
 #endif
                if (cur_frame_par) {
+                       if (frame_par_ready_to_set || frame_par_force_to_set) {
+                               struct vppfilter_mode_s *vpp_filter =
+                                       &cur_frame_par->vpp_filter;
+                               if ((vpp_filter->vpp_hsc_start_phase_step
+                                       == 0x1000000) &&
+                                       (vpp_filter->vpp_vsc_start_phase_step
+                                       == 0x1000000) &&
+                                       (vpp_filter->vpp_hsc_start_phase_step ==
+                                       vpp_filter->vpp_hf_start_phase_step) &&
+                                       !vpp_filter->vpp_pre_vsc_en &&
+                                       !vpp_filter->vpp_pre_hsc_en &&
+                                       !cur_frame_par->supsc0_enable &&
+                                       !cur_frame_par->supsc1_enable &&
+                                       bypass_pps)
+                                       pps_state = 2; /* pps disable */
+                               else
+                                       pps_state = 1; /* pps enable */
+                       }
                        if (cur_frame_par->VPP_hd_start_lines_
                                >=  cur_frame_par->VPP_hd_end_lines_)
                                h_size = 0;
@@ -5605,7 +5626,7 @@ SET_FILTER:
                                toggle_vf->compHeight : toggle_vf->height;
                        frame_size = (h_size << 16) | v_size;
                }
-               dolby_vision_process(toggle_vf, frame_size);
+               dolby_vision_process(toggle_vf, frame_size, pps_state);
                dolby_vision_update_setting();
        }
 #endif
@@ -5895,7 +5916,7 @@ SET_FILTER:
                        16) | (cur_frame_par->video_input_h & 0x1fff));
 
                /* vpp super scaler */
-               if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB)
+               if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
                        vpp_set_super_scaler_regs(cur_frame_par->supscl_path,
                                cur_frame_par->supsc0_enable,
                                cur_frame_par->spsc0_w_in,
@@ -5909,6 +5930,14 @@ SET_FILTER:
                                cur_frame_par->supsc1_vert_ratio,
                                vinfo->width,
                                vinfo->height);
+                       if (is_dolby_vision_on() &&
+                               is_dolby_vision_stb_mode() &&
+                               !cur_frame_par->supsc0_enable &&
+                               !cur_frame_par->supsc1_enable) {
+                               VSYNC_WR_MPEG_REG(VPP_SRSHARP0_CTRL, 0);
+                               VSYNC_WR_MPEG_REG(VPP_SRSHARP1_CTRL, 0);
+                       }
+               }
 
                /* vpp filters */
                /* SET_MPEG_REG_MASK(VPP_SC_MISC + cur_dev->vpp_off, */
@@ -6548,7 +6577,9 @@ int get_current_vscale_skip_count(struct vframe_s *vf)
        int ret = 0;
        static struct vpp_frame_par_s frame_par;
 
-       vpp_set_filters(process_3d_type, wide_setting, vf, &frame_par, vinfo);
+       vpp_set_filters(process_3d_type, wide_setting, vf, &frame_par, vinfo,
+               (is_dolby_vision_on() &&
+               is_dolby_vision_stb_mode()));
        ret = frame_par.vscale_skip_count;
        if (cur_frame_par && (process_3d_type & MODE_3D_ENABLE))
                ret |= (cur_frame_par->vpp_3d_mode<<8);
index 52cbe89..c7e108d 100644 (file)
@@ -1842,7 +1842,8 @@ int vpp_set_super_scaler_regs(int scaler_path_sel,
 }
 
 static void vpp_set_super_scaler(const struct vinfo_s *vinfo,
-                       struct vpp_frame_par_s *next_frame_par)
+                       struct vpp_frame_par_s *next_frame_par,
+                       bool bypass_sr0, bool bypass_sr1)
 {
        unsigned int hor_sc_multiple_num, ver_sc_multiple_num, temp;
        u32 width_out = next_frame_par->VPP_hsc_endp -
@@ -1942,12 +1943,12 @@ static void vpp_set_super_scaler(const struct vinfo_s *vinfo,
                next_frame_par->supsc0_vert_ratio = 0;
                next_frame_par->supsc1_vert_ratio = 1;
        }
-       if (bypass_spscl0 || !(sr_support & SUPER_CORE0_SUPPORT)) {
+       if (bypass_sr0 || !(sr_support & SUPER_CORE0_SUPPORT)) {
                next_frame_par->supsc0_enable = 0;
                next_frame_par->supsc0_hori_ratio = 0;
                next_frame_par->supsc0_vert_ratio = 0;
        }
-       if (bypass_spscl1 || !(sr_support & SUPER_CORE1_SUPPORT)) {
+       if (bypass_sr1 || !(sr_support & SUPER_CORE1_SUPPORT)) {
                next_frame_par->supsc1_enable = 0;
                next_frame_par->supsc1_hori_ratio = 0;
                next_frame_par->supsc1_vert_ratio = 0;
@@ -2339,7 +2340,8 @@ void
 vpp_set_filters(u32 process_3d_type, u32 wide_mode,
        struct vframe_s *vf,
        struct vpp_frame_par_s *next_frame_par,
-       const struct vinfo_s *vinfo)
+       const struct vinfo_s *vinfo,
+       bool bypass_sr)
 {
        u32 src_width = 0;
        u32 src_height = 0;
@@ -2467,7 +2469,9 @@ vpp_set_filters(u32 process_3d_type, u32 wide_mode,
                vinfo->width, vinfo->height,
                vinfo, vpp_flags, next_frame_par, vf);
        /*config super scaler after set next_frame_par is calc ok for pps*/
-       vpp_set_super_scaler(vinfo, next_frame_par);
+       vpp_set_super_scaler(vinfo, next_frame_par,
+               (bypass_sr | bypass_spscl0),
+               (bypass_sr | bypass_spscl1));
 }
 
 void prot_get_parameter(u32 wide_mode,
index 8bf8196..8e33d69 100644 (file)
@@ -16,7 +16,8 @@ extern void dolby_vision_set_toggle_flag(int flag);
 extern int dolby_vision_wait_metadata(struct vframe_s *vf);
 extern int dolby_vision_pop_metadata(void);
 extern int dolby_vision_update_metadata(struct vframe_s *vf);
-extern int dolby_vision_process(struct vframe_s *vf, u32 display_size);
+extern int dolby_vision_process(struct vframe_s *vf, u32 display_size,
+       u8 pps_state);
 extern void dolby_vision_init_receiver(void *pdev);
 extern void dolby_vision_vf_put(struct vframe_s *vf);
 extern struct vframe_s *dolby_vision_vf_peek_el(struct vframe_s *vf);
index 08d8934..b429310 100644 (file)
@@ -246,7 +246,8 @@ void get_vpp_3d_mode(u32 process_3d_type, u32 trans_fmt, u32 *vpp_3d_mode);
 extern void
 vpp_set_filters(u32 process_3d_type, u32 wide_mode, struct vframe_s *vf,
                                struct vpp_frame_par_s *next_frame_par,
-                               const struct vinfo_s *vinfo);
+                               const struct vinfo_s *vinfo,
+                               bool bypass_sr);
 
 extern void vpp_set_video_source_crop(u32 t, u32 l, u32 b, u32 r);