dv: fix one picture displayed playing mvc when dv is on [1/1]

PD#SWPL-13590

Problem:
only one picture displayed playing 3D mvc when dv is on

Solution:
when playing 3D mvc bypass dv.

Verify:
Verified by u212

Change-Id: I73c85808b7aad91a009b1e80f2514545e96eedf2
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
Pengcheng Chen
2019-09-06 16:52:07 +08:00
committed by Tao Zeng
parent fadedb6bdb
commit ffaf984c2a
10 changed files with 219 additions and 55 deletions

View File

@@ -3785,8 +3785,6 @@ void enable_dolby_vision(int enable)
VPP_VD1_CLIP_MISC1,
0);
video_effect_bypass(0);
VSYNC_WR_DV_REG(VPP_DOLBY_CTRL,
dolby_ctrl_backup);
/* always vd2 to vpp and bypass core 1 */
viu_misc_ctrl_backup |=
(VSYNC_RD_DV_REG(VIU_MISC_CTRL1) & 2);
@@ -4256,15 +4254,16 @@ static int is_policy_changed(void)
static bool vf_is_hdr10_plus(struct vframe_s *vf);
static bool vf_is_hdr10(struct vframe_s *vf);
static bool vf_is_hlg(struct vframe_s *vf);
static const char *input_str[7] = {
static bool is_mvc_frame(struct vframe_s *vf);
static const char *input_str[8] = {
"NONE",
"HDR",
"HDR+",
"DOVI",
"PRIME",
"HLG",
"SDR"
"SDR",
"MVC"
};
static void update_src_format(
@@ -4282,6 +4281,8 @@ static void update_src_format(
dolby_vision_src_format = 1;
else if (vf_is_hlg(vf))
dolby_vision_src_format = 5;
else if (is_mvc_frame(vf))
dolby_vision_src_format = 7;
else
dolby_vision_src_format = 6;
}
@@ -4393,6 +4394,19 @@ static int dolby_vision_policy_process(
}
vinfo = get_current_vinfo();
if (src_format == FORMAT_MVC) {
if (dolby_vision_mode !=
DOLBY_VISION_OUTPUT_MODE_BYPASS) {
if (debug_dolby & 2)
pr_dolby_dbg(
"mvc, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n");
*mode = DOLBY_VISION_OUTPUT_MODE_BYPASS;
mode_change = 1;
} else {
mode_change = 0;
}
return mode_change;
}
if (dolby_vision_policy == DOLBY_VISION_FOLLOW_SINK) {
/* bypass dv_mode with efuse */
if ((efuse_mode == 1) && !dolby_vision_efuse_bypass) {
@@ -4745,6 +4759,35 @@ static bool is_hdr10_frame(struct vframe_s *vf)
return false;
}
static bool is_mvc_frame(struct vframe_s *vf)
{
if (!vf)
return false;
if (vf->type & VIDTYPE_MVC)
return true;
return false;
}
int dolby_vision_check_mvc(struct vframe_s *vf)
{
int mode;
if (is_mvc_frame(vf) && dolby_vision_on) {
/* mvc source, but dovi enabled, need bypass dv */
mode = dolby_vision_mode;
if (dolby_vision_policy_process(
&mode, FORMAT_MVC)) {
if ((mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) &&
(dolby_vision_mode !=
DOLBY_VISION_OUTPUT_MODE_BYPASS))
dolby_vision_wait_on = true;
return 1;
}
}
return 0;
}
EXPORT_SYMBOL(dolby_vision_check_mvc);
int dolby_vision_check_hlg(struct vframe_s *vf)
{
int mode;
@@ -6030,6 +6073,11 @@ int dolby_vision_parse_metadata(
src_format = FORMAT_HDR10PLUS;
}
if ((src_format != FORMAT_DOVI) &&
is_mvc_frame(vf)) {
src_format = FORMAT_MVC;
}
#ifdef V2_4
/* TODO: need 962e ? */
if ((src_format == FORMAT_SDR)
@@ -6844,6 +6892,8 @@ int dolby_vision_wait_metadata(struct vframe_s *vf)
check_format = FORMAT_HLG;
else if (is_hdr10plus_frame(vf))
check_format = FORMAT_HDR10PLUS;
else if (is_mvc_frame(vf))
check_format = FORMAT_MVC;
else
check_format = FORMAT_SDR;
if (dolby_vision_policy_process(
@@ -7588,6 +7638,7 @@ int register_dv_functions(const struct dolby_vision_func_s *func)
dolby_vision_wait_on = false;
dolby_vision_wait_init = false;
dolby_vision_on_in_uboot = 0;
last_dst_format = FORMAT_DOVI;
}
if ((!p_funcs_stb || !p_funcs_tv) && func) {

View File

@@ -207,7 +207,8 @@ enum signal_format_e {
FORMAT_DOVI_LL = 3,
FORMAT_HLG = 4,
FORMAT_HDR10PLUS = 5,
FORMAT_SDR_2020 = 6
FORMAT_SDR_2020 = 6,
FORMAT_MVC = 7
};
enum priority_mode_e {

View File

@@ -45,6 +45,7 @@
uint debug_csc;
static int cur_mvc_type[2];
module_param(debug_csc, uint, 0664);
MODULE_PARM_DESC(debug_csc, "\n debug_csc\n");
@@ -72,6 +73,15 @@ void hdr_vd1_off(void)
HDR_BYPASS, cur_hdr_process);
}
void hdr_vd2_off(void)
{
enum hdr_process_sel cur_hdr_process;
cur_hdr_process = hdr_func(VD2_HDR, HDR_BYPASS, get_current_vinfo());
pr_csc(8, "am_vecm: module=VD2_HDR, process=HDR_BYPASS(%d, %d)\n",
HDR_BYPASS, cur_hdr_process);
}
static struct hdr_data_t *phdr;
struct hdr_data_t *hdr_get_data(void)
@@ -3762,7 +3772,14 @@ int signal_type_changed(struct vframe_s *vf,
if (!vf)
return 0;
if (vf->type & VIDTYPE_MVC) {
if (cur_mvc_type[vd_path] != (vf->type & VIDTYPE_MVC)) {
change_flag |= SIG_SRC_CHG;
cur_mvc_type[vd_path] = vf->type & VIDTYPE_MVC;
return change_flag;
}
} else
cur_mvc_type[vd_path] = 0;
if ((vf->source_type == VFRAME_SOURCE_TYPE_TUNER) ||
(vf->source_type == VFRAME_SOURCE_TYPE_CVBS) ||
(vf->source_type == VFRAME_SOURCE_TYPE_COMP) ||
@@ -6364,6 +6381,8 @@ EXPORT_SYMBOL(is_vinfo_available);
static enum hdr_type_e get_source_type(enum vd_path_e vd_path)
{
get_cur_vd_signal_type(vd_path);
if (cur_mvc_type[vd_path] == VIDTYPE_MVC)
return HDRTYPE_MVC;
if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
get_dolby_vision_src_format()
@@ -7155,9 +7174,11 @@ static int vpp_matrix_update(
get_hdr_policy());
signal_change_flag |= SIG_HDR_MODE;
}
source_format[VD1_PATH] = get_source_type(VD1_PATH);
source_format[VD2_PATH] = get_source_type(VD2_PATH);
get_cur_vd_signal_type(vd_path);
signal_change_flag |=
hdr_policy_process(vinfo, source_format, vd_path);
if (signal_change_flag & SIG_OUTPUT_MODE_CHG) {
@@ -7488,7 +7509,9 @@ int amvecm_matrix_process(
get_source_type(VD1_PATH) ==
HDRTYPE_HDR10PLUS ||
get_source_type(VD1_PATH)
== HDRTYPE_HLG))) {
== HDRTYPE_HLG ||
get_source_type(VD1_PATH)
== HDRTYPE_MVC))) {
/* and VD1 adaptive or VD2 */
/* or always hdr hdr+/hlg bypass */
/* faked vframe to switch matrix */

View File

@@ -194,6 +194,7 @@ extern void hdr_exit(void);
extern void hdr_set_cfg_osd_100(int val);
extern void hdr_osd_off(void);
extern void hdr_vd1_off(void);
void hdr_vd2_off(void);
extern bool is_video_layer_on(enum vd_path_e vd_path);
#define HDR_MODULE_OFF 0

View File

@@ -148,7 +148,19 @@ int hdr_policy_process(
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT709;
} else if (cur_hdr_policy == 0) {
if (vd_path == VD1_PATH &&
if (source_format[vd_path] == HDRTYPE_MVC) {
/* hdr bypass output need sdr */
sdr_process_mode[vd_path] = PROC_BYPASS;
hdr_process_mode[vd_path] = PROC_BYPASS;
hlg_process_mode[vd_path] = PROC_BYPASS;
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
sdr_process_mode[oth_path] = PROC_BYPASS;
hdr_process_mode[oth_path] = PROC_BYPASS;
hlg_process_mode[oth_path] = PROC_BYPASS;
hdr10_plus_process_mode[oth_path] = PROC_BYPASS;
target_format[vd_path] = BT709;
target_format[oth_path] = BT709;
} else if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
!is_dolby_vision_on() &&
(source_format[vd_path]
@@ -254,7 +266,19 @@ int hdr_policy_process(
#endif
}
} else if (cur_hdr_policy == 1) {
if (vd_path == VD1_PATH &&
if (source_format[vd_path] == HDRTYPE_MVC) {
/* hdr bypass output need sdr */
sdr_process_mode[vd_path] = PROC_BYPASS;
hdr_process_mode[vd_path] = PROC_BYPASS;
hlg_process_mode[vd_path] = PROC_BYPASS;
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
sdr_process_mode[oth_path] = PROC_BYPASS;
hdr_process_mode[oth_path] = PROC_BYPASS;
hlg_process_mode[oth_path] = PROC_BYPASS;
hdr10_plus_process_mode[oth_path] = PROC_BYPASS;
target_format[vd_path] = BT709;
target_format[oth_path] = BT709;
} else if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
!is_dolby_vision_on() &&
source_format[vd_path]
@@ -797,6 +821,12 @@ int hdr_policy_process(
case HDRTYPE_SDR:
cur_sdr_process_mode[oth_path] = PROC_OFF;
break;
case HDRTYPE_MVC:
cur_sdr_process_mode[oth_path] = PROC_BYPASS;
cur_hdr_process_mode[oth_path] = PROC_BYPASS;
cur_hlg_process_mode[oth_path] = PROC_BYPASS;
cur_hdr10_plus_process_mode[oth_path] = PROC_BYPASS;
break;
default:
break;
}
@@ -1106,7 +1136,11 @@ void video_post_process(
hdr_proc(VD2_HDR, HDR_HLG, vinfo);
hdr_proc(OSD1_HDR, SDR_HLG, vinfo);
}
break;
case HDRTYPE_MVC:
hdr_osd_off();
hdr_vd1_off();
hdr_vd2_off();
break;
default:
break;
@@ -1128,6 +1162,12 @@ void video_post_process(
vd_path + 1,
cur_sdr_process_mode[vd_path],
sdr_process_mode[vd_path]);
if (cur_source_format[vd_path] == HDRTYPE_MVC)
pr_csc(1,
"am_vecm: vd%d: mvc_process_mode %d to %d\n",
vd_path + 1,
cur_sdr_process_mode[vd_path],
sdr_process_mode[vd_path]);
cur_sdr_process_mode[vd_path] =
sdr_process_mode[vd_path];
}

View File

@@ -4509,7 +4509,8 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
}
vd1_path_select(true, false);
if (is_mvc)
vd2_path_select(true, false);
VSYNC_WR_MPEG_REG(
VD1_IF0_GEN_REG + cur_dev->viu_off, 0);
return;
@@ -4584,6 +4585,8 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
vd1_path_select(false, true);
} else {
vd1_path_select(false, false);
if (is_mvc)
vd2_path_select(false, false);
VSYNC_WR_MPEG_REG(
AFBC_ENABLE, 0);
}
@@ -6724,6 +6727,16 @@ inline void switch_3dView_per_vsync(void)
}
#endif
int is_3d_enable(struct vframe_s *vf)
{
if (!vf && !process_3d_type)
return VFRAME_NONE;
if (process_3d_type ||
(vf->type & VIDTYPE_MVC))
return VFRAME_MVC;
return VFRAME_NO_MVC;
}
#ifdef FIQ_VSYNC
void vsync_fisr_in(void)
#else
@@ -7026,6 +7039,7 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
/* check video frame before VECM process */
if (is_dolby_vision_enable() && vf) {
dolby_vision_check_mvc(vf);
dolby_vision_check_hdr10(vf);
dolby_vision_check_hdr10plus(vf);
dolby_vision_check_hlg(vf);
@@ -7365,7 +7379,20 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
break;
else
frame_skip_check_cnt = 0;
#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
if (amvecm_on_vs(
(cur_dispbuf != &vf_local)
? cur_dispbuf : NULL,
vf, CSC_FLAG_CHECK_OUTPUT,
0,
0,
0,
0,
0,
0,
VD1_PATH) == 1)
break;
#endif
vf = video_vf_get();
if (!vf) {
ATRACE_COUNTER(MODULE_NAME, __LINE__);
@@ -7400,21 +7427,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
video_3d_format = vf->trans_fmt;
}
}
#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
if (amvecm_on_vs(
(cur_dispbuf != &vf_local)
? cur_dispbuf : NULL,
vf, CSC_FLAG_CHECK_OUTPUT,
0,
0,
0,
0,
0,
0,
VD1_PATH) == 1)
break;
#endif
vsync_toggle_frame(vf, __LINE__);
toggle_frame = vf;
@@ -8413,18 +8425,23 @@ SET_FILTER:
if (cur_pipbuf && (video2_enabled == 1)
&& ((vpp_misc_save & VPP_VD2_POSTBLEND) == 0)
&& (video2_onoff_state == VIDEO_ENABLE_STATE_IDLE)) {
vpp_misc_set |=
VPP_VD2_POSTBLEND |
VPP_POSTBLEND_EN;
if (is_3d_enable(cur_dispbuf) != VFRAME_MVC)
vpp_misc_set |=
VPP_VD2_POSTBLEND |
VPP_POSTBLEND_EN;
}
#endif
if ((video_enabled == 1) && ((vpp_misc_save & VPP_VD1_POSTBLEND) == 0)
&& (video_onoff_state == VIDEO_ENABLE_STATE_IDLE)) {
vpp_misc_set |=
VPP_VD1_PREBLEND |
VPP_VD1_POSTBLEND |
VPP_POSTBLEND_EN;
if (is_3d_enable(cur_dispbuf) == VFRAME_MVC)
vpp_misc_set |= VPP_VD1_PREBLEND | VPP_VD2_PREBLEND |
VPP_PREBLEND_EN | VPP_VD1_POSTBLEND;
else
vpp_misc_set |=
VPP_VD1_PREBLEND |
VPP_VD1_POSTBLEND |
VPP_POSTBLEND_EN;
}
if ((video_enabled == 1) && cur_frame_par
&& (cur_dispbuf != &vf_local) && (first_set == 0)
@@ -8507,29 +8524,27 @@ SET_FILTER:
video2_onoff_state = VIDEO_ENABLE_STATE_ON_PENDING;
} else if (video2_onoff_state ==
VIDEO_ENABLE_STATE_ON_PENDING) {
if (is_dolby_vision_on() &&
if (is_3d_enable(cur_dispbuf) == VFRAME_MVC) {
vpp_misc_set |= VPP_VD2_PREBLEND |
VPP_PREBLEND_EN;
} else if (is_dolby_vision_on() &&
(!is_dolby_vision_el_disable() ||
for_dolby_vision_certification()))
for_dolby_vision_certification())) {
vpp_misc_set &= ~(VPP_VD2_PREBLEND |
VPP_VD2_POSTBLEND | VPP_PREBLEND_EN);
else if (process_3d_type ||
(cur_dispbuf &&
(cur_dispbuf->type & VIDTYPE_MVC)))
vpp_misc_set |= VPP_VD2_PREBLEND |
VPP_PREBLEND_EN;
else if (!legacy_vpp)
vpp_misc_set |= VPP_VD2_POSTBLEND |
VPP_POSTBLEND_EN;
else
vpp_misc_set |= VPP_VD2_PREBLEND |
VPP_PREBLEND_EN;
} else if (cur_pipbuf) {
#ifdef VIDEO_PIP
if (cur_pipbuf) {
vpp_misc_set &=
~(VPP_PREBLEND_EN | VPP_VD2_PREBLEND);
vpp_misc_set |= VPP_VD2_POSTBLEND;
}
#endif
} else if (!legacy_vpp) {
vpp_misc_set |= VPP_VD2_POSTBLEND |
VPP_POSTBLEND_EN;
} else {
vpp_misc_set |= VPP_VD2_PREBLEND |
VPP_PREBLEND_EN;
}
/* g12a has no alpha overflow check in hardware */
if (!legacy_vpp)
vpp_misc_set |= (0x100 << VPP_VD2_ALPHA_BIT);
@@ -8564,17 +8579,20 @@ SET_FILTER:
VPP_VD2_POSTBLEND |
VPP_VD1_POSTBLEND |
VPP_PREBLEND_EN);
if (is_3d_enable(cur_dispbuf) != VFRAME_MVC) {
#ifdef VIDEO_PIP
/* should keep video2 display */
if (cur_pipbuf && video2_enabled)
vpp_misc_set |= VPP_VD2_POSTBLEND;
#endif
}
} else {
video_enabled = video_status_saved;
}
if (!video_enabled &&
(vpp_misc_set & VPP_VD1_POSTBLEND))
((vpp_misc_set & VPP_VD1_POSTBLEND) ||
(vpp_misc_set & VPP_VD1_PREBLEND)))
vpp_misc_set &= ~(VPP_VD1_PREBLEND |
VPP_VD1_POSTBLEND |
VPP_PREBLEND_EN);
@@ -8590,7 +8608,8 @@ SET_FILTER:
}
if (!video2_enabled &&
(vpp_misc_set & VPP_VD2_POSTBLEND))
((vpp_misc_set & VPP_VD2_POSTBLEND) ||
(vpp_misc_set & VPP_VD2_PREBLEND)))
vpp_misc_set &= ~(VPP_VD2_PREBLEND |
VPP_VD2_POSTBLEND);
#endif
@@ -8638,8 +8657,10 @@ SET_FILTER:
0xf);
/* if vd2 is bottom layer, need remove alpha for vd2 */
if (((vpp_misc_set & VPP_VD1_POSTBLEND) == 0)
&& (vpp_misc_set & VPP_VD2_POSTBLEND)) {
/* 3d case vd2 preblend, need remove alpha for vd2 */
if ((((vpp_misc_set & VPP_VD1_POSTBLEND) == 0) &&
(vpp_misc_set & VPP_VD2_POSTBLEND)) ||
(vpp_misc_set & VPP_VD2_PREBLEND)) {
vpp_misc_set &= ~(0x1ff << VPP_VD2_ALPHA_BIT);
vpp_misc_set |= (0x100 << VPP_VD2_ALPHA_BIT);
}

View File

@@ -1402,6 +1402,23 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data)
}
static void update_current_para(struct hdmitx_dev *hdev)
{
struct vinfo_s *info = NULL;
unsigned char mode[32];
info = hdmitx_get_current_vinfo();
if (!info)
return;
strncpy(mode, info->name, sizeof(mode));
if (strstr(hdev->fmt_attr, "420")) {
if (!strstr(mode, "420"))
strncat(mode, "420", 3);
}
hdev->para = hdmi_get_fmt_name(mode, hdev->fmt_attr);
}
static void hdmitx_set_vsif_pkt(enum eotf_type type,
enum mode_type tunnel_mode, struct dv_vsif_para *data, bool signal_sdr)
{
@@ -1502,6 +1519,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type,
HDMI_PACKET_VEND, NULL, NULL);
if (signal_sdr) {
pr_info("hdmitx: H14b VSIF, switching signal to SDR\n");
update_current_para(hdev);
hdev->HWOp.CntlConfig(hdev,
CONF_AVI_RGBYCC_INDIC, hdev->para->cs);
hdev->HWOp.CntlConfig(hdev,

View File

@@ -116,4 +116,5 @@ extern int get_dolby_vision_src_format(void);
extern bool is_dolby_vision_el_disable(void);
extern bool is_dovi_dual_layer_frame(struct vframe_s *vf);
void dolby_vision_set_provider(char *prov_name);
int dolby_vision_check_mvc(struct vframe_s *vf);
#endif

View File

@@ -103,6 +103,7 @@
#define PRIMESL_SOURCE 4
#define HLG_SOURCE 5
#define SDR_SOURCE 6
#define MVC_SOURCE 7
enum cm_hist_e {
CM_HUE_HIST = 0,
@@ -286,7 +287,8 @@ enum hdr_type_e {
HDRTYPE_HDR10 = HDR10_SOURCE,
HDRTYPE_HLG = HLG_SOURCE,
HDRTYPE_HDR10PLUS = HDR10PLUS_SOURCE,
HDRTYPE_DOVI = DOVI_SOURCE
HDRTYPE_DOVI = DOVI_SOURCE,
HDRTYPE_MVC = MVC_SOURCE,
};
enum pd_comb_fix_lvl_e {

View File

@@ -51,6 +51,12 @@ enum {
VIDEO_WIDEOPTION_MAX = 16
};
enum {
VFRAME_NONE,
VFRAME_MVC,
VFRAME_NO_MVC
};
/* TODO: move to register headers */
#define VPP_VADJ2_BLMINUS_EN (1 << 3)
#define VPP_VADJ2_EN (1 << 2)