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
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
#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");
}
}
+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,
(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,
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 {
}
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;
}
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)
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;
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 &
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);
int hsize,
int vsize,
int dolby_enable,
- int scramble_en)
+ int scramble_en,
+ u8 pps_state)
{
uint32_t count;
int i;
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()) {
}
} 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);
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;
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)
/* 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 */
/* 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,
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 ? */
(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();
}
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(
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;
}
/* 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) {
}
}
+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;
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) {
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 =
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 */
/* 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 <=
/* 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 <
{
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);
&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;
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)
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 &
#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
}
#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;
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
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,
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, */
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);