diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index 47b45aaf7700..f7ec16bb332b 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -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); diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h index 95073370cbd2..7f99c4c4430d 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h @@ -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 }; diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.c b/drivers/amlogic/media/enhancement/amvecm/amcsc.c index 2dc3d67822a0..a5b4410f08cb 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.c +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.c @@ -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(); diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 24d35cf12ef8..287b55ea50bf 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -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) @@ -5327,11 +5333,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) cur_frame_par->supsc1_vert_ratio : 0) == 1) break; -#endif -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (is_dolby_vision_enable() - && dolby_vision_need_wait()) - break; #endif /* *two special case: @@ -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); diff --git a/drivers/amlogic/media/video_sink/vpp.c b/drivers/amlogic/media/video_sink/vpp.c index 52cbe89ae83a..c7e108dce6b1 100644 --- a/drivers/amlogic/media/video_sink/vpp.c +++ b/drivers/amlogic/media/video_sink/vpp.c @@ -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, diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h index 8bf8196d782d..8e33d69b6598 100644 --- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h +++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h @@ -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); diff --git a/include/linux/amlogic/media/video_sink/vpp.h b/include/linux/amlogic/media/video_sink/vpp.h index 08d893421fc0..b4293104c838 100644 --- a/include/linux/amlogic/media/video_sink/vpp.h +++ b/include/linux/amlogic/media/video_sink/vpp.h @@ -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);