summaryrefslogtreecommitdiff
authorBrian Zhu <brian.zhu@amlogic.com>2019-09-11 19:39:26 (GMT)
committer Tao Zeng <tao.zeng@amlogic.com>2019-10-09 01:22:12 (GMT)
commit8555b6c3721515251d7f9a906ea26824f25d7f9f (patch)
treec4c08bff2346ea2a6eae3b0affdeed1711191c14
parent4697d4b09d6a6d8bcca873c68f7f0728366c832a (diff)
downloadcommon-8555b6c3721515251d7f9a906ea26824f25d7f9f.zip
common-8555b6c3721515251d7f9a906ea26824f25d7f9f.tar.gz
common-8555b6c3721515251d7f9a906ea26824f25d7f9f.tar.bz2
vpp: improve the csc and dv switch flow and policy [1/1]
PD#SWPL-13990 Problem: There are some conflicts between csc and dv module switching. Can not switch to SDR->DV when HDR core is working on SDR->SDR mode. Solution: 1. Improve the switching policy. DV and csc will use same on. 2. add mute operation under dv mode. Verify: Verified on AC211 Change-Id: I4d59328fc34228a0ef5275d22643932c4dfe00b0 Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
Diffstat
-rw-r--r--drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c686
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amcsc.c556
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amcsc.h13
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c336
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c8
-rw-r--r--drivers/amlogic/media/video_sink/video.c132
-rw-r--r--include/linux/amlogic/media/amdolbyvision/dolby_vision.h13
-rw-r--r--include/linux/amlogic/media/video_sink/video.h7
8 files changed, 1311 insertions, 440 deletions
diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c
index 61b2735..2a84747 100644
--- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c
+++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c
@@ -218,13 +218,14 @@ static bool dolby_vision_el_disable;
#define FLAG_DISABLE_DOVI_OUT 0x2000
#define FLAG_FORCE_DOVI_LL 0x4000
#define FLAG_FORCE_RGB_OUTPUT 0x8000
-/* #define FLAG_DOVI_LL_RGB_DESIRED 0x8000 */
-#define FLAG_DOVI2HDR10_NOMAPPING 0x100000
-#define FLAG_PRIORITY_GRAPHIC 0x200000
-#define FLAG_DISABLE_LOAD_VSVDB 0x400000
-#define FLAG_DISABLE_CRC 0x800000
-#define FLAG_ENABLE_EL 0x1000000
-#define FLAG_COPY_CORE1S0 0x2000000
+#define FLAG_DOVI2HDR10_NOMAPPING 0x100000
+#define FLAG_PRIORITY_GRAPHIC 0x200000
+#define FLAG_DISABLE_LOAD_VSVDB 0x400000
+#define FLAG_DISABLE_CRC 0x800000
+#define FLAG_ENABLE_EL 0x1000000
+#define FLAG_COPY_CORE1S0 0x2000000
+#define FLAG_MUTE 0x4000000
+#define FLAG_FORCE_HDMI_PKT 0x8000000
#define FLAG_TOGGLE_FRAME 0x80000000
#define FLAG_FRAME_DELAY_MASK 0xf
@@ -276,7 +277,6 @@ static bool is_osd_off;
static bool force_reset_core2;
static int core1_switch;
static int core3_switch;
-static int video_enable;
module_param(vtotal_add, uint, 0664);
MODULE_PARM_DESC(vtotal_add, "\n vtotal_add\n");
@@ -2377,6 +2377,13 @@ static int dolby_core2_set(
return 0;
}
+bool is_core3_mute_reg(int index)
+{
+ return (index == 12) || /* ipt_scale for ipt*/
+ (index >= 16 && index <= 17) || /* rgb2yuv scale for yuv */
+ (index >= 5 && index <= 9); /* lms2rgb coeff for rgb */
+}
+
static int dolby_core3_set(
uint32_t dm_count,
uint32_t md_count,
@@ -2549,12 +2556,20 @@ static int dolby_core3_set(
count = 26;
else
count = dm_count;
- for (i = 0; i < count; i++)
+ for (i = 0; i < count; i++) {
if (reset || (p_core3_dm_regs[i] !=
- last_dm[i]))
+ last_dm[i]) || is_core3_mute_reg(i)) {
+ if ((dolby_vision_flags & FLAG_MUTE) &&
+ is_core3_mute_reg(i))
+ VSYNC_WR_DV_REG(
+ DOLBY_CORE3_REG_START + 0x6 + i,
+ 0);
+ else
VSYNC_WR_DV_REG(
DOLBY_CORE3_REG_START + 0x6 + i,
p_core3_dm_regs[i]);
+ }
+ }
/* from addr 0x18 */
if (scramble_en) {
@@ -2619,34 +2634,49 @@ static int is_graphic_changed(void)
force_reset_core2 = true;
pr_dolby_dbg("osd on\n");
is_osd_off = false;
- ret |= 1;
+ ret |= 2;
}
+ /* do not need to monitor osd change, */
+ /* because scaler is after dolby core2 */
if ((osd_graphic_width != new_osd_graphic_width) ||
(osd_graphic_height != new_osd_graphic_height)) {
- pr_dolby_dbg("osd changed %d %d-%d %d\n",
- osd_graphic_width,
- osd_graphic_height,
- new_osd_graphic_width,
- new_osd_graphic_height);
- osd_graphic_width = new_osd_graphic_width;
- osd_graphic_height = new_osd_graphic_height;
- ret |= 2;
+ if (debug_dolby & 0x10)
+ pr_dolby_dbg("osd changed %d %d-%d %d\n",
+ osd_graphic_width,
+ osd_graphic_height,
+ new_osd_graphic_width,
+ new_osd_graphic_height);
+ /* ignore osd size change */
+ /* osd scaler is after dobly core */
+ /* osd_graphic_width = new_osd_graphic_width; */
+ /* osd_graphic_height = new_osd_graphic_height; */
+ /* ret |= 4; */
}
return ret;
}
-static int is_video_turn_on(void)
-{
- int ret = 0;
- int new_video_enable = get_video_enabled();
+static int cur_mute_type;
+static char mute_type_str[4][4] = {
+ "NON",
+ "YUV",
+ "RGB",
+ "IPT"
+};
- if (video_enable != new_video_enable) {
- pr_dolby_dbg("video_enable changed %d-%d\n",
- video_enable, new_video_enable);
- ret = new_video_enable ? 1 : -1;
- }
- video_enable = new_video_enable;
- return ret;
+int get_mute_type(void)
+{
+ if (dolby_vision_ll_policy == DOLBY_VISION_LL_RGB444)
+ return MUTE_TYPE_RGB;
+ else if ((dolby_vision_ll_policy == DOLBY_VISION_LL_YUV422) ||
+ (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_SDR8) ||
+ (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_SDR10) ||
+ (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_HDR10))
+ return MUTE_TYPE_YUV;
+ else if ((dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_IPT) ||
+ (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL))
+ return MUTE_TYPE_IPT;
+ else
+ return MUTE_TYPE_NONE;
}
static void adjust_vpotch(void)
@@ -2728,6 +2758,12 @@ static void apply_stb_core_settings(
#endif
u32 graphics_w = osd_graphic_width;
u32 graphics_h = osd_graphic_height;
+ int mute_type;
+
+ if (h_size == 0xffff)
+ h_size = 0;
+ if (v_size == 0xffff)
+ v_size = 0;
if (is_dolby_vision_stb_mode()
&& (dolby_vision_flags & FLAG_CERTIFICAION)) {
@@ -2775,44 +2811,71 @@ static void apply_stb_core_settings(
reset);
}
- if (stb_core_setting_update_flag != FLAG_CHANGE_ALL) {
- /* when FLAG_CONST_TC2 is set, */
- /* set the stb_core_setting_update_flag */
- /* until only meeting the FLAG_CHANGE_TC2 */
- if (stb_core_setting_update_flag & FLAG_CONST_TC2)
- stb_core2_const_flag = true;
- else if (stb_core_setting_update_flag & FLAG_CHANGE_TC2)
- stb_core2_const_flag = false;
- }
+ if (mask & 2) {
+ if (stb_core_setting_update_flag != FLAG_CHANGE_ALL) {
+ /* when FLAG_CONST_TC2 is set, */
+ /* set the stb_core_setting_update_flag */
+ /* until only meeting the FLAG_CHANGE_TC2 */
+ if (stb_core_setting_update_flag & FLAG_CONST_TC2)
+ stb_core2_const_flag = true;
+ else if (stb_core_setting_update_flag & FLAG_CHANGE_TC2)
+ stb_core2_const_flag = false;
+ }
- /* revert the core2 lut as last corret one when const case */
- if (stb_core2_const_flag)
- memcpy(&new_dovi_setting.dm_lut2,
- &dovi_setting.dm_lut2,
- sizeof(struct dm_lut_ipcore_s));
+ /* revert the core2 lut as last corret one when const case */
+ if (stb_core2_const_flag)
+ memcpy(&new_dovi_setting.dm_lut2,
+ &dovi_setting.dm_lut2,
+ sizeof(struct dm_lut_ipcore_s));
- if (mask & 2)
dolby_core2_set(
24, 256 * 5,
(uint32_t *)&new_dovi_setting.dm_reg2,
(uint32_t *)&new_dovi_setting.dm_lut2,
graphics_w, graphics_h, 1, 1);
- v_size = vinfo->height;
- if (((vinfo->width == 720) &&
- (vinfo->height == 480) &&
- (vinfo->height != vinfo->field_height)) ||
- ((vinfo->width == 720) &&
- (vinfo->height == 576) &&
- (vinfo->height != vinfo->field_height)) ||
- ((vinfo->width == 1920) &&
- (vinfo->height == 1080) &&
- (vinfo->height != vinfo->field_height)) ||
- ((vinfo->width == 1920) &&
- (vinfo->height == 1080) &&
- (vinfo->height != vinfo->field_height) &&
- (vinfo->sync_duration_num / vinfo->sync_duration_den == 50)))
- v_size = v_size/2;
- if (mask & 4)
+ }
+
+ if (mask & 4) {
+ v_size = vinfo->height;
+ if (((vinfo->width == 720) &&
+ (vinfo->height == 480) &&
+ (vinfo->height != vinfo->field_height)) ||
+ ((vinfo->width == 720) &&
+ (vinfo->height == 576) &&
+ (vinfo->height != vinfo->field_height)) ||
+ ((vinfo->width == 1920) &&
+ (vinfo->height == 1080) &&
+ (vinfo->height != vinfo->field_height)) ||
+ ((vinfo->width == 1920) &&
+ (vinfo->height == 1080) &&
+ (vinfo->height != vinfo->field_height) &&
+ (vinfo->sync_duration_num
+ / vinfo->sync_duration_den == 50)))
+ v_size = v_size / 2;
+ mute_type = get_mute_type();
+ if ((get_video_mute() == VIDEO_MUTE_ON_DV) &&
+ (!(dolby_vision_flags & FLAG_MUTE) ||
+ cur_mute_type != mute_type)) {
+ pr_dolby_dbg("mute %s\n", mute_type_str[mute_type]);
+ /* unmute vpp and mute by core3 */
+ VSYNC_WR_MPEG_REG(VPP_CLIP_MISC0,
+ (0x3ff << 20) |
+ (0x3ff << 10) |
+ 0x3ff);
+ VSYNC_WR_MPEG_REG(VPP_CLIP_MISC1,
+ (0x0 << 20) |
+ (0x0 << 10) | 0x0);
+ cur_mute_type = mute_type;
+ dolby_vision_flags |= FLAG_MUTE;
+ } else if ((get_video_mute() == VIDEO_MUTE_OFF) &&
+ (dolby_vision_flags & FLAG_MUTE)) {
+ /* vpp unmuted when dv mute */
+ /* clean flag to unmute core3 here*/
+ pr_dolby_dbg("unmute %s\n",
+ mute_type_str[cur_mute_type]);
+ cur_mute_type = MUTE_TYPE_NONE;
+ dolby_vision_flags &= ~FLAG_MUTE;
+ }
dolby_core3_set(
26, new_dovi_setting.md_reg3.size,
(uint32_t *)&new_dovi_setting.dm_reg3,
@@ -2822,6 +2885,7 @@ static void apply_stb_core_settings(
dolby_vision_mode ==
DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL,
pps_state);
+ }
}
static void osd_bypass(int bypass)
@@ -3409,7 +3473,10 @@ void enable_dolby_vision(int enable)
last_dolby_vision_ll_policy =
dolby_vision_ll_policy;
#endif
- pr_info("Dolby Vision G12a turn on\n");
+ pr_dolby_dbg(
+ "Dolby Vision G12a turn on%s\n",
+ dolby_vision_core1_on ?
+ ", core1 on" : "");
} else {
VSYNC_WR_DV_REG(VPP_DOLBY_CTRL,
/* cm_datx4_mode */
@@ -3485,7 +3552,10 @@ void enable_dolby_vision(int enable)
last_dolby_vision_ll_policy =
dolby_vision_ll_policy;
#endif
- pr_info("Dolby Vision turn on\n");
+ pr_dolby_dbg(
+ "Dolby Vision turn on%s\n",
+ dolby_vision_core1_on ?
+ ", core1 on" : "");
}
} else {
if (!dolby_vision_core1_on
@@ -3522,7 +3592,7 @@ void enable_dolby_vision(int enable)
0,
16, 1); /* core1 */
dolby_vision_core1_on = true;
- pr_dolby_dbg("dolby_vision_core1_on\n");
+ pr_dolby_dbg("Dolby Vision core1 turn on\n");
} else if (dolby_vision_core1_on
&& (!(dolby_vision_mask & 1)
|| !dovi_setting_video_flag)) {
@@ -3542,6 +3612,7 @@ void enable_dolby_vision(int enable)
1,
16, 1); /* core1 */
dolby_vision_core1_on = false;
+ pr_dolby_dbg("Dolby Vision core1 turn off\n");
}
}
dolby_vision_on = true;
@@ -3737,8 +3808,12 @@ void enable_dolby_vision(int enable)
dolby_vision_wait_init = false;
dolby_vision_wait_count = 0;
dolby_vision_status = BYPASS_PROCESS;
+ dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_BYPASS;
+ dolby_vision_src_format = 0;
dolby_vision_on_count = 0;
cur_csc_type[VD1_PATH] = VPP_MATRIX_NULL;
+ /* clean mute flag for next time dv on */
+ dolby_vision_flags &= ~FLAG_MUTE;
hdr_osd_off();
hdr_vd1_off();
}
@@ -4142,52 +4217,8 @@ static int sink_support_hdr10_plus(const struct vinfo_s *vinfo)
return 0;
}
-static bool is_vinfo_available(const struct vinfo_s *vinfo)
-{
- return strcmp(vinfo->name, "invalid") &&
- strcmp(vinfo->name, "null") &&
- strcmp(vinfo->name, "576cvbs") &&
- strcmp(vinfo->name, "470cvbs");
-}
-
static int current_hdr_cap = -1; /* should set when probe */
static int current_sink_available;
-static int is_sink_cap_changed(const struct vinfo_s *vinfo)
-{
- int hdr_cap;
- int sink_available;
- int ret = 0;
-
- if (vinfo && is_vinfo_available(vinfo)) {
- hdr_cap = (1 << 0) |
- (sink_support_dolby_vision(vinfo) << 1) |
- (sink_support_hdr10_plus(vinfo) << 2) |
- (sink_support_hdr(vinfo) << 3);
- sink_available = 1;
- } else {
- hdr_cap = 0;
- current_hdr_cap = 0;
- sink_available = 0;
- }
- if (current_hdr_cap == -1) {
- current_hdr_cap = hdr_cap;
- pr_dolby_dbg("hdr cap=%d, output=%s\n",
- hdr_cap, vinfo->name);
- ret |= 4;
- } else if (current_hdr_cap != hdr_cap) {
- pr_dolby_dbg("hdr cap changed %d->%d, video %s, output=%s\n",
- current_hdr_cap, hdr_cap,
- get_video_enabled() ? "on" : "off", vinfo->name);
- current_hdr_cap = hdr_cap;
- ret |= 2;
- }
- if (current_sink_available != sink_available) {
- pr_dolby_dbg("sink available = %d\n", sink_available);
- current_sink_available = sink_available;
- ret |= 1;
- }
- return ret;
-}
static int is_policy_changed(void)
{
@@ -4201,15 +4232,15 @@ static int is_policy_changed(void)
last_dolby_vision_policy = dolby_vision_policy;
ret |= 1;
}
-#if 0 // do not need to monitor, since this is dynamic changing
if (last_dolby_vision_ll_policy != dolby_vision_ll_policy) {
- /* handle policy change */
- pr_dolby_dbg("ll policy changed %d->%d\n",
- last_dolby_vision_ll_policy,
- dolby_vision_ll_policy);
- ret |= 2;
+ /* handle ll policy change when dolby on */
+ if (dolby_vision_on) {
+ pr_dolby_dbg("ll policy changed %d->%d\n",
+ last_dolby_vision_ll_policy,
+ dolby_vision_ll_policy);
+ ret |= 2;
+ }
}
-#endif
if (last_dolby_vision_hdr10_policy != dolby_vision_hdr10_policy) {
/* handle policy change */
pr_dolby_dbg("hdr10 policy changed %d->%d\n",
@@ -4252,16 +4283,16 @@ static void update_src_format(
dolby_vision_src_format = 5;
else
dolby_vision_src_format = 6;
- if (cur_format != dolby_vision_src_format) {
- pr_dolby_dbg(
- "dolby_vision_src_format changed: %s => %s, signal_type = 0x%x\n",
- input_str[cur_format],
- input_str[dolby_vision_src_format],
- vf->signal_type);
- cur_format = dolby_vision_src_format;
- }
}
}
+ if (cur_format != dolby_vision_src_format) {
+ pr_dolby_dbg(
+ "dolby_vision_src_format changed: %s => %s, signal_type = 0x%x\n",
+ input_str[cur_format],
+ input_str[dolby_vision_src_format],
+ vf->signal_type);
+ cur_format = dolby_vision_src_format;
+ }
}
int get_dolby_vision_src_format(void)
@@ -4384,9 +4415,7 @@ static int dolby_vision_policy_process(
mode_change = 1;
}
} else if ((cur_csc_type[VD1_PATH] != 0xffff) &&
- (get_hdr_module_status(VD1_PATH) == HDR_MODULE_ON) &&
- (src_format != FORMAT_DOVI) &&
- (src_format != FORMAT_DOVI_LL)) {
+ (get_hdr_module_status(VD1_PATH) == HDR_MODULE_ON)) {
/*if vpp is playing hlg/hdr10+*/
/*dolby need bypass at this time*/
if (dolby_vision_mode !=
@@ -4474,9 +4503,7 @@ static int dolby_vision_policy_process(
return mode_change;
}
if ((cur_csc_type[VD1_PATH] != 0xffff) &&
- (get_hdr_module_status(VD1_PATH) == HDR_MODULE_ON) &&
- (src_format != FORMAT_DOVI) &&
- (src_format != FORMAT_DOVI_LL)) {
+ (get_hdr_module_status(VD1_PATH) == HDR_MODULE_ON)) {
/* bypass dolby incase VPP is not in sdr mode */
if (dolby_vision_mode !=
DOLBY_VISION_OUTPUT_MODE_BYPASS) {
@@ -4536,7 +4563,7 @@ static int dolby_vision_policy_process(
} else if (dolby_vision_mode !=
DOLBY_VISION_OUTPUT_MODE_BYPASS) {
/* HDR/SDR bypass */
- pr_dolby_dbg("sdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS");
+ pr_dolby_dbg("sdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n");
*mode = DOLBY_VISION_OUTPUT_MODE_BYPASS;
mode_change = 1;
}
@@ -4550,6 +4577,17 @@ static int dolby_vision_policy_process(
return mode_change;
}
+static char dv_provider[32] = "dvbldec";
+
+void dolby_vision_set_provider(char *prov_name)
+{
+ if (prov_name && strlen(prov_name) < 32) {
+ strcpy(dv_provider, prov_name);
+ pr_dolby_dbg("provider changed to %s\n", dv_provider);
+ }
+}
+EXPORT_SYMBOL(dolby_vision_set_provider);
+
bool is_dovi_frame(struct vframe_s *vf)
{
struct provider_aux_req_s req;
@@ -4577,9 +4615,9 @@ bool is_dovi_frame(struct vframe_s *vf)
else
return 0;
} else if (vf->source_type == VFRAME_SOURCE_TYPE_OTHERS) {
- vf_notify_provider_by_name("dvbldec",
- VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
- (void *)&req);
+ vf_notify_provider_by_name(dv_provider,
+ VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
+ (void *)&req);
if (req.dv_enhance_exist)
return true;
if (!req.aux_buf || !req.aux_size)
@@ -5495,6 +5533,7 @@ static bool send_hdmi_pkt(
(p_hdr->display_primaries_y_0_MSB << 8)
| p_hdr->display_primaries_y_0_LSB;
}
+
if (hdr10_data.white_point[0] !=
((p_hdr->white_point_x_MSB << 8)
| p_hdr->white_point_x_LSB))
@@ -5542,6 +5581,7 @@ static bool send_hdmi_pkt(
hdr10_data.max_frame_average =
(p_hdr->max_frame_average_light_level_MSB << 8)
| p_hdr->max_frame_average_light_level_LSB;
+
if (vinfo && vinfo->vout_device &&
vinfo->vout_device->fresh_tx_hdr_pkt)
vinfo->vout_device->fresh_tx_hdr_pkt(&hdr10_data);
@@ -5550,10 +5590,12 @@ static bool send_hdmi_pkt(
vinfo->vout_device->fresh_tx_vsif_pkt)
vinfo->vout_device->fresh_tx_vsif_pkt(0, 0, NULL, true);
#endif
- if (last_dst_format != FORMAT_HDR10)
- pr_info("send_hdmi_pkt: HDR10\n");
+ if ((last_dst_format != FORMAT_HDR10) ||
+ (dolby_vision_flags & FLAG_FORCE_HDMI_PKT))
+ pr_dolby_dbg("send_hdmi_pkt: HDR10\n");
+
last_dst_format = dst_format;
- if (flag) {
+ if (flag && debug_dolby & 8) {
pr_dolby_dbg("Info frame for hdr10 changed:\n");
for (i = 0; i < 3; i++)
pr_dolby_dbg(
@@ -5624,9 +5666,10 @@ static bool send_hdmi_pkt(
? RGB_8BIT : YUV422_BIT12, &vsif,
false);
}
- if (last_dst_format != FORMAT_DOVI)
- pr_info("send_hdmi_pkt: %s\n",
- dovi_setting.dovi_ll_enable ? "LL" : "DV");
+ if ((last_dst_format != FORMAT_DOVI) ||
+ (dolby_vision_flags & FLAG_FORCE_HDMI_PKT))
+ pr_dolby_dbg("send_hdmi_pkt: %s\n",
+ dovi_setting.dovi_ll_enable ? "LL" : "DV");
last_dst_format = dst_format;
} else if (last_dst_format != dst_format) {
if (last_dst_format == FORMAT_HDR10) {
@@ -5665,21 +5708,21 @@ static bool send_hdmi_pkt(
/* HLG/HDR10+ case: first switch to SDR
* immediately.
*/
- pr_info("send_hdmi_pkt: HDR10+/HLG: signal SDR first\n");
+ pr_dolby_dbg("send_hdmi_pkt: HDR10+/HLG: signal SDR first\n");
vinfo->vout_device->fresh_tx_vsif_pkt(
0, 0, NULL, true);
last_dst_format = dst_format;
sdr_transition_delay = 0;
} else if (sdr_transition_delay >=
MAX_TRANSITION_DELAY) {
- pr_info("send_hdmi_pkt: VSIF disabled, signal SDR\n");
+ pr_dolby_dbg("send_hdmi_pkt: VSIF disabled, signal SDR\n");
vinfo->vout_device->fresh_tx_vsif_pkt(
0, 0, NULL, true);
last_dst_format = dst_format;
sdr_transition_delay = 0;
} else {
if (sdr_transition_delay == 0) {
- pr_info("send_hdmi_pkt: disable Dovi/H14b VSIF\n");
+ pr_dolby_dbg("send_hdmi_pkt: disable Dovi/H14b VSIF\n");
vinfo->vout_device->fresh_tx_vsif_pkt(
0, 0, NULL, false);
}
@@ -5688,6 +5731,8 @@ static bool send_hdmi_pkt(
}
}
}
+ if (dolby_vision_flags & FLAG_FORCE_HDMI_PKT)
+ dolby_vision_flags &= ~FLAG_FORCE_HDMI_PKT;
return flag;
}
@@ -5786,8 +5831,8 @@ int dolby_vision_parse_metadata(
int total_comp_size = 0;
bool el_flag = 0;
bool el_halfsize_flag = 1;
- uint32_t w = 3840;
- uint32_t h = 2160;
+ u32 w = 0xffff;
+ u32 h = 0xffff;
int meta_flag_bl = 1;
int meta_flag_el = 1;
int src_chroma_format = 0;
@@ -5913,9 +5958,9 @@ int dolby_vision_parse_metadata(
req.aux_buf = NULL;
req.aux_size = 0;
req.dv_enhance_exist = 0;
- vf_notify_provider_by_name("dvbldec",
- VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
- (void *)&req);
+ vf_notify_provider_by_name(dv_provider,
+ VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
+ (void *)&req);
if (debug_dolby & 1 && req.aux_buf && req.aux_size)
pr_dolby_dbg("dvbldec get aux data %p %x\n",
req.aux_buf, req.aux_size);
@@ -5930,14 +5975,14 @@ int dolby_vision_parse_metadata(
&ret_flags, drop_flag);
if (ret_flags && req.dv_enhance_exist
&& (frame_count == 0)) {
- vf_notify_provider_by_name("dvbldec",
+ vf_notify_provider_by_name(
+ dv_provider,
VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL,
(void *)&req);
pr_info("bypass mel\n");
}
- if (ret_flags == 1) {
+ if (ret_flags == 1)
mel_flag = true;
- }
if (!is_dv_standard_es(req.dv_enhance_exist,
ret_flags, w)) {
src_format = FORMAT_SDR;
@@ -5995,7 +6040,7 @@ int dolby_vision_parse_metadata(
|| (frame_count == 0))
&& (toggle_mode == 1))
pr_info(
- "frame %d pts %lld, src bdp: %d format: %s, aux_size:%d, enhance: %d\n",
+ "DOLBY: dolby_vision_parse_metadata frame %d pts %lld, src bdp: %d format: %s, aux_size:%d, enhance: %d\n",
frame_count, vf->pts_us64, src_bdp,
(src_format == FORMAT_HDR10) ? "HDR10" :
(src_format == FORMAT_DOVI ? "DOVI" :
@@ -6123,10 +6168,6 @@ int dolby_vision_parse_metadata(
/* use old setting for this frame */
return -1;
}
- w = (vf->type & VIDTYPE_COMPRESS) ?
- vf->compWidth : vf->width;
- h = (vf->type & VIDTYPE_COMPRESS) ?
- vf->compHeight : vf->height;
}
if ((src_format == FORMAT_DOVI)
@@ -6544,12 +6585,11 @@ int dolby_vision_parse_metadata(
}
}
-#if 0 /* check video/graphics priority on the fly */
+ /* check video/graphics priority on the fly */
if (get_video_enabled() && is_graphics_output_off())
dolby_vision_graphics_priority = 0;
else
dolby_vision_graphics_priority = 1;
-#endif
if (dolby_vision_graphics_priority ||
(dolby_vision_flags &
@@ -6665,20 +6705,28 @@ int dolby_vision_parse_metadata(
osd_graphic_width,
osd_graphic_height);
if (el_flag)
- pr_dolby_dbg("setting %d->%d(T:%d-%d): flag=%x, md=%d,comp=%d, frame:%d\n",
- src_format, dst_format,
- dolby_vision_target_min,
- dolby_vision_target_max[src_format][dst_format],
- flag,
- total_md_size, total_comp_size,
- frame_count);
+ pr_dolby_dbg("video %d:%dx%d setting %d->%d(T:%d-%d): flag=%x, md=%d,comp=%d, frame:%d\n",
+ dovi_setting_video_flag,
+ w == 0xffff ? 0 : w,
+ h == 0xffff ? 0 : h,
+ src_format, dst_format,
+ dolby_vision_target_min,
+ dolby_vision_target_max
+ [src_format][dst_format],
+ flag,
+ total_md_size, total_comp_size,
+ frame_count);
else
- pr_dolby_dbg("setting %d->%d(T:%d-%d): flag=%x, md=%d, frame:%d\n",
- src_format, dst_format,
- dolby_vision_target_min,
- dolby_vision_target_max[src_format][dst_format],
- flag,
- total_md_size, frame_count);
+ pr_dolby_dbg("video %d:%dx%d setting %d->%d(T:%d-%d): flag=%x, md=%d, frame:%d\n",
+ dovi_setting_video_flag,
+ w == 0xffff ? 0 : w,
+ h == 0xffff ? 0 : h,
+ src_format, dst_format,
+ dolby_vision_target_min,
+ dolby_vision_target_max
+ [src_format][dst_format],
+ flag,
+ total_md_size, frame_count);
}
dump_setting(&new_dovi_setting, frame_count, debug_dolby);
el_mode = el_flag;
@@ -6735,7 +6783,8 @@ int dolby_vision_wait_metadata(struct vframe_s *vf)
req.dv_enhance_exist = 0;
if (vf->source_type == VFRAME_SOURCE_TYPE_OTHERS)
- vf_notify_provider_by_name("dvbldec",
+ vf_notify_provider_by_name(
+ dv_provider,
VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
(void *)&req);
}
@@ -6896,7 +6945,10 @@ static void bypass_pps_path(u8 pps_state)
}
}
-int dolby_vision_process(struct vframe_s *vf, u32 display_size,
+int dolby_vision_process(
+ struct vframe_s *rpt_vf,
+ struct vframe_s *vf,
+ u32 display_size,
u8 pps_state) /* 0: no change, 1: pps enable, 2: pps disable */
{
int src_chroma_format = 0;
@@ -6907,6 +6959,12 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
bool force_set = false;
static int sdr_delay;
unsigned int mode = dolby_vision_mode;
+ static bool video_turn_off = true;
+ static bool video_on[VD_PATH_MAX];
+ int video_status = 0;
+ int graphic_status = 0;
+ int policy_changed = 0;
+ int sink_changed = 0;
if (!is_meson_box() && !is_meson_txlx() && !is_meson_tm2())
return -1;
@@ -6920,6 +6978,11 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
vf->compWidth : vf->width;
v_size = (vf->type & VIDTYPE_COMPRESS) ?
vf->compHeight : vf->height;
+ } else if (rpt_vf) {
+ h_size = (rpt_vf->type & VIDTYPE_COMPRESS) ?
+ rpt_vf->compWidth : rpt_vf->width;
+ v_size = (rpt_vf->type & VIDTYPE_COMPRESS) ?
+ rpt_vf->compHeight : rpt_vf->height;
} else {
h_size = 0;
v_size = 0;
@@ -6928,9 +6991,58 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
dolby_vision_run_mode_delay;
}
- if ((core1_disp_hsize != h_size)
- || (core1_disp_vsize != v_size))
- force_set = true;
+ if (dolby_vision_flags & FLAG_TOGGLE_FRAME) {
+ h_size = (display_size >> 16) & 0xffff;
+ v_size = display_size & 0xffff;
+ if (new_dovi_setting.video_width & 0xffff &&
+ new_dovi_setting.video_height & 0xffff) {
+ if (new_dovi_setting.video_width != h_size ||
+ new_dovi_setting.video_height != v_size) {
+ if (debug_dolby & 8)
+ pr_dolby_dbg(
+ "update display size %d %d -> %d %d\n",
+ new_dovi_setting.video_width,
+ new_dovi_setting.video_height,
+ h_size, v_size);
+ }
+ if (h_size && v_size) {
+ new_dovi_setting.video_width = h_size;
+ new_dovi_setting.video_height = v_size;
+ } else {
+ new_dovi_setting.video_width = 0xffff;
+ new_dovi_setting.video_height = 0xffff;
+ }
+
+ /* tvcore need a reset for resolution change */
+ if (is_meson_tvmode() &&
+ ((core1_disp_hsize != h_size) ||
+ (core1_disp_vsize != v_size)))
+ force_set = true;
+ } else if (core1_disp_hsize != h_size ||
+ core1_disp_vsize != v_size) {
+ if (debug_dolby & 8)
+ pr_dolby_dbg(
+ "vpp update display size %d %d -> %d %d\n",
+ core1_disp_hsize,
+ core1_disp_vsize,
+ h_size, v_size);
+ if (h_size && v_size) {
+ new_dovi_setting.video_width = h_size;
+ new_dovi_setting.video_height = v_size;
+ } else {
+ new_dovi_setting.video_width = 0xffff;
+ new_dovi_setting.video_height = 0xffff;
+ }
+ }
+ if (!vf && !sdr_delay) {
+ /* log to monitor if has dv toggles not needed */
+ /* !sdr_delay: except in transition from DV to SDR */
+ pr_dolby_dbg("NULL frame, hdr module %s, video %s\n",
+ get_hdr_module_status(VD1_PATH)
+ == HDR_MODULE_ON ? "on" : "off",
+ get_video_enabled() ? "on" : "off");
+ }
+ }
if ((dolby_vision_flags & FLAG_CERTIFICAION)
&& (setting_update_count > crc_count)
@@ -6965,42 +7077,71 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
}
}
- if (dolby_vision_on
- && is_video_output_off(vf)
- && !video_off_handled) {
- dolby_vision_set_toggle_flag(1);
- frame_count = 0;
- video_off_handled = 1;
- if (debug_dolby & 2) {
- pr_dolby_dbg("video off\n");
- }
- }
+ video_status = is_video_turn_on(video_on, VD1_PATH);
+ if (video_status == -1)
+ video_turn_off = true;
+ else if (video_status == 1)
+ video_turn_off = false;
- if (is_sink_cap_changed(vinfo)) {
- if (vf)
- dolby_vision_parse_metadata(vf, 1, false, false);
- dolby_vision_set_toggle_flag(1);
- }
- if (is_video_turn_on() == 1) {
- if (vf && !dolby_vision_parse_metadata(vf, 0, false, false))
- dolby_vision_set_toggle_flag(1);
+ if (video_turn_off &&
+ get_hdr_module_status(VD1_PATH)
+ != HDR_MODULE_ON) {
+ vf = NULL;
+ rpt_vf = NULL;
}
- /* only monitor dolby_vision_policy */
- /* other policy will be updated for video */
- if (is_policy_changed() & 1)
+ graphic_status = is_graphic_changed();
+
+ /* monitor policy changes */
+ policy_changed = is_policy_changed();
+ if (policy_changed)
dolby_vision_set_toggle_flag(1);
- if (is_graphic_changed())
+
+ if (graphic_status & 2)
dolby_vision_set_toggle_flag(1);
- if (!vf && !get_video_enabled()) {
- if (dolby_vision_policy == DOLBY_VISION_FOLLOW_SINK
- && !is_dolby_vision_video_on()) {
- if (dolby_vision_policy_process(
- &mode, FORMAT_SDR)) {
+ if (!is_dolby_vision_on())
+ dolby_vision_flags &= ~FLAG_FORCE_HDMI_PKT;
+
+ sink_changed = (is_sink_cap_changed(vinfo,
+ &current_hdr_cap, &current_sink_available) & 2) ? 1 : 0;
+ if (sink_changed || policy_changed ||
+ (video_status == 1) || (graphic_status & 2) ||
+ (dolby_vision_flags & FLAG_FORCE_HDMI_PKT)) {
+ u8 toggle_mode;
+
+ pr_dolby_dbg("sink %s, cap 0x%x, video %s, osd %s, vf %p, rpt_vf %p\n",
+ current_sink_available ? "on" : "off",
+ current_hdr_cap,
+ video_turn_off ? "off" : "on",
+ is_graphics_output_off() ? "off" : "on",
+ vf, rpt_vf);
+ if (vf && (vf != rpt_vf))
+ toggle_mode = 1;
+ else
+ toggle_mode = 0;
+ if ((vf || rpt_vf) &&
+ !dolby_vision_parse_metadata(
+ vf ? vf : rpt_vf, toggle_mode, false, false)) {
+ h_size = (display_size >> 16) & 0xffff;
+ v_size = display_size & 0xffff;
+ new_dovi_setting.video_width = h_size;
+ new_dovi_setting.video_height = v_size;
+ dolby_vision_set_toggle_flag(1);
+ }
+ }
+
+ if (!vf && video_turn_off) {
+ if (dolby_vision_policy_process(&mode, FORMAT_SDR)) {
+ pr_dolby_dbg("Fake SDR, mode->%d\n", mode);
+ if (dolby_vision_policy == DOLBY_VISION_FOLLOW_SOURCE &&
+ mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) {
+ dolby_vision_mode =
+ DOLBY_VISION_OUTPUT_MODE_BYPASS;
+ dolby_vision_set_toggle_flag(0);
+ dolby_vision_wait_on = false;
+ } else
dolby_vision_set_toggle_flag(1);
- pr_dolby_dbg("Fake SDR, mode->%d\n", mode);
- }
}
if (dolby_vision_flags & FLAG_TOGGLE_FRAME)
dolby_vision_parse_metadata(
@@ -7008,8 +7149,6 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
}
if (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) {
- if (vinfo && sink_support_dolby_vision(vinfo))
- dolby_vision_set_toggle_flag(1);
if (!is_meson_tvmode() || force_stb_mode) {
if (vinfo && vinfo->vout_device &&
(!vinfo->vout_device->dv_info)
@@ -7021,6 +7160,8 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
if (dolby_vision_status != BYPASS_PROCESS) {
if (vinfo && !is_meson_tvmode() &&
!force_stb_mode) {
+ if (!vf && rpt_vf)
+ rpt_vf = vf;
if (vf && is_hdr10plus_frame(vf)) {
/* disable dolby immediately */
pr_info("Dolby bypass: HDR10+: Switched to SDR first\n");
@@ -7034,28 +7175,51 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
FORMAT_SDR, vinfo, vf);
enable_dolby_vision(0);
} else if (last_dst_format != FORMAT_DOVI) {
- /* disable dolby immediately */
- pr_info("Dolby bypass: Switched %d to SDR\n",
- last_dst_format);
+ /* disable dolby immediately:
+ * non-dovi alwyas hdr to adaptive
+ */
+ pr_dolby_dbg("Dolby bypass: Switched %d to SDR\n",
+ last_dst_format);
send_hdmi_pkt(dolby_vision_src_format,
FORMAT_SDR, vinfo, vf);
enable_dolby_vision(0);
} else {
+ /* disable dolby after sdr delay:
+ * dovi alwyas hdr to adaptive or dovi
+ * playback exit in adaptive mode on
+ * a dovi tv
+ */
+ if (sdr_delay == 0) {
+ pr_dolby_dbg("Dolby bypass: Start - Switched to SDR\n");
+ dolby_vision_set_toggle_flag(1);
+ }
+ if ((get_video_mute() ==
+ VIDEO_MUTE_ON_DV &&
+ !(dolby_vision_flags & FLAG_MUTE)) ||
+ (get_video_mute() == VIDEO_MUTE_OFF &&
+ dolby_vision_flags & FLAG_MUTE))
+ /* core 3 only */
+ apply_stb_core_settings(
+ dovi_setting_video_flag,
+ 0x4,
+ 0,
+ (dovi_setting.video_width << 16)
+ | dovi_setting.video_height,
+ pps_state);
send_hdmi_pkt(dolby_vision_src_format,
FORMAT_SDR, vinfo, vf);
if (sdr_delay >= MAX_TRANSITION_DELAY) {
- pr_info("Dolby bypass: Done - Switched to SDR\n");
+ pr_dolby_dbg("Dolby bypass: Done - Switched to SDR\n");
enable_dolby_vision(0);
sdr_delay = 0;
- }
- sdr_delay++;
+ } else
+ sdr_delay++;
}
} else
enable_dolby_vision(0);
-
- if (dolby_vision_flags & FLAG_TOGGLE_FRAME)
- dolby_vision_flags &= ~FLAG_TOGGLE_FRAME;
}
+ if (sdr_delay == 0)
+ dolby_vision_flags &= ~FLAG_TOGGLE_FRAME;
return 0;
} else if (sdr_delay != 0) {
/* in case mode change to a mode requiring dolby block */
@@ -7126,6 +7290,10 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
} else {
if ((new_dovi_setting.video_width & 0xffff)
&& (new_dovi_setting.video_height & 0xffff)) {
+ if (new_dovi_setting.video_width == 0xffff)
+ new_dovi_setting.video_width = 0;
+ if (new_dovi_setting.video_height == 0xffff)
+ new_dovi_setting.video_height = 0;
if (force_set &&
!(dolby_vision_flags
& FLAG_CERTIFICAION))
@@ -7134,22 +7302,45 @@ 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,
+ (new_dovi_setting.video_width << 16)
+ | new_dovi_setting.video_height,
pps_state);
memcpy(&dovi_setting, &new_dovi_setting,
sizeof(dovi_setting));
+ if (core1_disp_hsize !=
+ dovi_setting.video_width ||
+ core1_disp_vsize !=
+ dovi_setting.video_height)
+ if (core1_disp_hsize &&
+ core1_disp_vsize)
+ pr_dolby_dbg(
+ "frame size %d %d->%d %d\n",
+ core1_disp_hsize,
+ core1_disp_vsize,
+ dovi_setting.video_width,
+ dovi_setting.video_height);
new_dovi_setting.video_width =
new_dovi_setting.video_height = 0;
- if (!h_size || !v_size)
+ if (!dovi_setting.video_width ||
+ !dovi_setting.video_height)
dovi_setting_video_flag = false;
if (dovi_setting_video_flag
&& (dolby_vision_on_count == 0))
pr_dolby_dbg("first frame reset %d\n",
reset_flag);
+ /* clr hdr+ pkt when enable dv */
+ if (!dolby_vision_on &&
+ vinfo && vinfo->vout_device &&
+ vinfo->vout_device->fresh_tx_hdr10plus_pkt)
+ vinfo->vout_device->
+ fresh_tx_hdr10plus_pkt(
+ 0, NULL);
enable_dolby_vision(1);
bypass_pps_path(pps_state);
- core1_disp_hsize = h_size;
- core1_disp_vsize = v_size;
+ core1_disp_hsize =
+ dovi_setting.video_width;
+ core1_disp_vsize =
+ dovi_setting.video_height;
/* send HDMI packet according to dst_format */
if (vinfo && !force_stb_mode)
send_hdmi_pkt(
@@ -7158,6 +7349,29 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
vinfo, vf);
update_dolby_vision_status(
dovi_setting.src_format);
+ } else {
+ if ((get_video_mute() == VIDEO_MUTE_ON_DV &&
+ !(dolby_vision_flags & FLAG_MUTE)) ||
+ (get_video_mute() == VIDEO_MUTE_OFF &&
+ dolby_vision_flags & FLAG_MUTE) ||
+ (last_dolby_vision_ll_policy !=
+ dolby_vision_ll_policy))
+ /* core 3 only */
+ apply_stb_core_settings(
+ dovi_setting_video_flag,
+ 0x4,
+ reset_flag,
+ (dovi_setting.video_width << 16)
+ | dovi_setting.video_height,
+ pps_state);
+ /* force send hdmi pkt */
+ if (dolby_vision_flags & FLAG_FORCE_HDMI_PKT) {
+ if (vinfo && !force_stb_mode)
+ send_hdmi_pkt(
+ dovi_setting.src_format,
+ dovi_setting.dst_format,
+ vinfo, vf);
+ }
}
}
dolby_vision_flags &= ~FLAG_TOGGLE_FRAME;
@@ -7231,15 +7445,16 @@ 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,
+ (core1_disp_hsize << 16)
+ | core1_disp_vsize,
pps_state);
- core1_disp_hsize = h_size;
- core1_disp_vsize = v_size;
if (dolby_vision_on_count <
dolby_vision_run_mode_delay)
- pr_dolby_dbg("fake frame %d reset %d\n",
- dolby_vision_on_count,
- reset_flag);
+ pr_dolby_dbg("fake frame (%d %d) %d reset %d\n",
+ core1_disp_hsize,
+ core1_disp_vsize,
+ dolby_vision_on_count,
+ reset_flag);
}
}
}
@@ -7281,10 +7496,13 @@ EXPORT_SYMBOL(for_dolby_vision_certification);
void dolby_vision_set_toggle_flag(int flag)
{
- if (flag)
+ if (flag) {
dolby_vision_flags |= FLAG_TOGGLE_FRAME;
- else
+ if (flag & 2)
+ dolby_vision_flags |= FLAG_FORCE_HDMI_PKT;
+ } else {
dolby_vision_flags &= ~FLAG_TOGGLE_FRAME;
+ }
}
EXPORT_SYMBOL(dolby_vision_set_toggle_flag);
@@ -7335,6 +7553,12 @@ bool is_dolby_vision_el_disable(void)
}
EXPORT_SYMBOL(is_dolby_vision_el_disable);
+void set_dolby_vision_policy(int policy)
+{
+ dolby_vision_policy = policy;
+}
+EXPORT_SYMBOL(set_dolby_vision_policy);
+
int get_dolby_vision_policy(void)
{
return dolby_vision_policy;
@@ -7353,9 +7577,11 @@ int register_dv_functions(const struct dolby_vision_func_s *func)
*otherwise it will effect hdr module
*/
if (dolby_vision_on_in_uboot) {
- if (is_vinfo_available(vinfo)) {
- is_sink_cap_changed(vinfo);
- } else
+ if (is_vinfo_available(vinfo))
+ is_sink_cap_changed(vinfo,
+ &current_hdr_cap,
+ &current_sink_available);
+ else
pr_info("sink not available\n");
dolby_vision_on = true;
dolby_vision_wait_on = false;
diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.c b/drivers/amlogic/media/enhancement/amvecm/amcsc.c
index 7aa379e..ac17546 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amcsc.c
+++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.c
@@ -127,7 +127,7 @@ static ssize_t write_file_hdr_cfgosd(
hdr_set_cfg_osd_100(val);
- pr_info("en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100);
+ pr_info("HDR: en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100);
return count;
}
@@ -337,12 +337,56 @@ static uint hdmi_csc_type = 0xffff;
module_param(hdmi_csc_type, uint, 0444);
MODULE_PARM_DESC(hdmi_csc_type, "\n current color space convert type\n");
+/* 0: follow sink, 1: follow source, 2: debug, 0xff: bootup default value */
+/* by default follow source to match default sdr_mode*/
+static uint hdr_policy = 1;
+static uint cur_hdr_policy = 0xff;
+module_param(hdr_policy, uint, 0664);
+MODULE_PARM_DESC(hdr_policy, "\n current hdr_policy\n");
+
+/* when cur_hdr_policy == 2 && dovi disable */
+/* enum output_format_e */
+/* BT709 = 1, */
+/* BT2020 = 2, */
+/* BT2020_PQ = 3, */
+/* BT2020_PQ_DYNAMIC = 4, */
+/* BT2020_HLG = 5, */
+/* BT2100_IPT = 6 */
+/* BT2020 = 2: 2020 + gamma not support in hdmi now */
+static uint force_output = 1; /* BT709 */
+module_param(force_output, uint, 0664);
+MODULE_PARM_DESC(force_output, "\n current force_output\n");
+
+int get_hdr_policy(void)
+{
+ int dv_policy = 0;
+ int dv_mode = 0;
+
+ if (is_dolby_vision_enable()) {
+ /* sync hdr_policy with dolby_vision_policy */
+ /* get current dolby_vision_mode */
+ dv_policy = get_dolby_vision_policy();
+ dv_mode = get_dolby_vision_mode();
+ if ((dv_policy != DOLBY_VISION_FORCE_OUTPUT_MODE) ||
+ (dv_mode != DOLBY_VISION_OUTPUT_MODE_BYPASS)) {
+ /* use dv policy when not force bypass */
+ return dv_policy;
+ }
+ }
+ return hdr_policy;
+}
+EXPORT_SYMBOL(get_hdr_policy);
+
+enum output_format_e get_force_output(void)
+{
+ return force_output;
+}
+EXPORT_SYMBOL(get_force_output);
+
static uint hdr_mode = 2; /* 0: hdr->hdr, 1:hdr->sdr, 2:auto */
module_param(hdr_mode, uint, 0664);
MODULE_PARM_DESC(hdr_mode, "\n set hdr_mode\n");
-static uint cur_hdr_mode;
-
/* 0: hdr->hdr, 1:hdr->sdr, 2:hdr->hlg */
uint hdr_process_mode[VD_PATH_MAX];
uint cur_hdr_process_mode[VD_PATH_MAX] = {PROC_OFF, PROC_OFF};
@@ -418,18 +462,15 @@ module_param(hdr_flag, uint, 0664);
MODULE_PARM_DESC(hdr_flag, "\n set hdr_flag\n");
/* 0: off, 1: normal, 2: bypass */
-static int video_process_status[VD_PATH_MAX];
+static int video_process_status[VD_PATH_MAX] = {2, 2};
module_param_array(video_process_status, uint, &vd_path_max, 0664);
MODULE_PARM_DESC(video_process_status, "\n video_process_status\n");
-int get_hdr_module_status(enum vd_path_e vd_path)
-{
- return video_process_status[vd_path];
-}
-EXPORT_SYMBOL(get_hdr_module_status);
void set_hdr_module_status(enum vd_path_e vd_path, int status)
{
video_process_status[vd_path] = status;
+ pr_csc(4, "video_process_status[VD%d] = %d",
+ vd_path + 1, status);
}
EXPORT_SYMBOL(set_hdr_module_status);
@@ -3714,8 +3755,8 @@ int signal_type_changed(struct vframe_s *vf,
u32 default_signal_type;
int change_flag = 0;
int i, j;
- struct vframe_master_display_colour_s *p_cur;
- struct vframe_master_display_colour_s *p_new;
+ struct vframe_master_display_colour_s *p_cur = NULL;
+ struct vframe_master_display_colour_s *p_new = NULL;
struct vframe_master_display_colour_s cus;
int ret;
@@ -3820,9 +3861,11 @@ int signal_type_changed(struct vframe_s *vf,
/*vf->signal_type, signal_type);*/
}
- ret = hdr10_primaries_changed(p_new, p_cur);
- if (ret)
- change_flag |= SIG_PRI_INFO;
+ if (p_new && p_cur) {
+ ret = hdr10_primaries_changed(p_new, p_cur);
+ if (ret)
+ change_flag |= SIG_PRI_INFO;
+ }
if (change_flag & SIG_PRI_INFO) {
pr_csc(1, "vd%d Master_display_colour changed %x.\n",
vd_path + 1, ret);
@@ -6264,23 +6307,100 @@ static void hdr_support_process(struct vinfo_s *vinfo, enum vd_path_e vd_path)
sdr_process_mode[vd_path] = sdr_mode;
}
+static int sink_support_dolby_vision(const struct vinfo_s *vinfo)
+{
+ if (!vinfo || !vinfo->vout_device || !vinfo->vout_device->dv_info)
+ return 0;
+ if (vinfo->vout_device->dv_info->ieeeoui != 0x00d046)
+ return 0;
+ if (vinfo->vout_device->dv_info->block_flag != CORRECT)
+ return 0;
+ if (strstr(vinfo->name, "2160p60hz") ||
+ strstr(vinfo->name, "2160p50hz")) {
+ if (!vinfo->vout_device->dv_info->sup_2160p60hz)
+ return 0;
+ }
+ return 1;
+}
+
+static int sink_support_hdr(const struct vinfo_s *vinfo)
+{
+ if (!vinfo)
+ return 0;
+ if (vinfo->hdr_info.hdr_support & HDR_SUPPORT)
+ return 1;
+ return 0;
+}
+
+static int sink_support_hlg(const struct vinfo_s *vinfo)
+{
+ if (!vinfo)
+ return 0;
+ if (vinfo->hdr_info.hdr_support & HLG_SUPPORT)
+ return 1;
+ return 0;
+}
+
+static int sink_support_hdr10_plus(const struct vinfo_s *vinfo)
+{
+ if ((vinfo->hdr_info.hdr10plus_info.ieeeoui
+ == 0x90848B) &&
+ (vinfo->hdr_info.hdr10plus_info.application_version
+ == 1))
+ return 1;
+
+ return 0;
+}
+
+bool is_vinfo_available(const struct vinfo_s *vinfo)
+{
+ return strcmp(vinfo->name, "invalid") &&
+ strcmp(vinfo->name, "null") &&
+ strcmp(vinfo->name, "576cvbs") &&
+ strcmp(vinfo->name, "470cvbs");
+}
+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 (vd_path == VD1_PATH &&
+ is_dolby_vision_enable() &&
+ get_dolby_vision_src_format()
+ == HDRTYPE_DOVI)
+ return HDRTYPE_DOVI;
if (((signal_transfer_characteristic == 14) ||
- (signal_transfer_characteristic == 18)) &&
- (signal_color_primaries == 9))
+ (signal_transfer_characteristic == 18)) &&
+ (signal_color_primaries == 9))
return HDRTYPE_HLG;
- else if ((signal_transfer_characteristic == 0x30)
- && (signal_color_primaries == 9))
- return HDRTYPE_HDR10PLUS;
- else if ((signal_transfer_characteristic == 16)
- || (signal_color_primaries == 9))
+ else if ((signal_transfer_characteristic == 0x30) &&
+ (signal_color_primaries == 9)) {
+ if (sink_support_hdr10_plus(get_current_vinfo()))
+ return HDRTYPE_HDR10PLUS;
+ else
+ return HDRTYPE_HDR10;
+ } else if ((signal_transfer_characteristic == 16) ||
+ (signal_color_primaries == 9))
return HDRTYPE_HDR10;
else
return HDRTYPE_SDR;
}
+int get_hdr_module_status(enum vd_path_e vd_path)
+{
+ if (vd_path == VD1_PATH &&
+ is_dolby_vision_enable() &&
+ get_dolby_vision_policy()
+ == DOLBY_VISION_FOLLOW_SOURCE &&
+ get_source_type(VD1_PATH)
+ == HDRTYPE_SDR &&
+ sdr_process_mode[VD1_PATH]
+ == PROC_BYPASS)
+ return HDR_MODULE_BYPASS;
+ return video_process_status[vd_path];
+}
+EXPORT_SYMBOL(get_hdr_module_status);
+
static bool video_layer_wait_on[VD_PATH_MAX];
bool is_video_layer_on(enum vd_path_e vd_path)
{
@@ -6346,6 +6466,7 @@ static void hdr10_plus_metadata_update(struct vframe_s *vf,
static struct hdr10plus_para hdmitx_hdr10plus_params[VD_PATH_MAX];
static int hdr10_plus_pkt_update;
static bool hdr10_plus_pkt_on;
+/* 0: no delay, 1:delay one frame, >1:delay one frame and repeat */
static uint hdr10_plus_pkt_delay = 1;
static struct hdr10plus_para cur_hdr10plus_params;
static struct master_display_info_s cur_send_info;
@@ -6418,8 +6539,8 @@ void send_hdr10_plus_pkt(enum vd_path_e vd_path)
else
hdr10_plus_pkt_update = HDRPLUS_PKT_IDLE;
pr_csc(2, "send_hdr10_plus_pkt update\n");
- } else if ((hdr10_plus_pkt_update == HDRPLUS_PKT_REPEAT)
- && (get_hdr10_plus_pkt_delay() > 1)) {
+ } else if ((hdr10_plus_pkt_update == HDRPLUS_PKT_REPEAT) &&
+ (get_hdr10_plus_pkt_delay() > 1)) {
vdev->fresh_tx_hdr_pkt(
&cur_send_info);
vdev->fresh_tx_hdr10plus_pkt(
@@ -6918,6 +7039,59 @@ static void video_process(
}
}
+static int current_hdr_cap[VD_PATH_MAX] = {-1, -1}; /* should set when probe */
+static int current_sink_available[VD_PATH_MAX] = {-1, -1};
+
+int is_sink_cap_changed(
+ const struct vinfo_s *vinfo,
+ int *p_current_hdr_cap,
+ int *p_current_sink_available)
+{
+ int hdr_cap;
+ int sink_available;
+ int ret = 0;
+
+ if (is_vinfo_available(vinfo)) {
+ hdr_cap = (1 << 0) |
+ (sink_support_dolby_vision(vinfo) << 1) |
+ (sink_support_hdr10_plus(vinfo) << 2) |
+ (sink_support_hdr(vinfo) << 3) |
+ (sink_support_hlg(vinfo) << 3);
+ sink_available = 1;
+ } else {
+ hdr_cap = 0;
+ *p_current_hdr_cap = 0;
+ sink_available = 0;
+ }
+
+ if (*p_current_hdr_cap == -1) {
+ *p_current_hdr_cap = hdr_cap;
+ ret |= 4;
+ } else if (*p_current_hdr_cap != hdr_cap) {
+ *p_current_hdr_cap = hdr_cap;
+ ret |= 2;
+ }
+ if (*p_current_sink_available != sink_available) {
+ *p_current_sink_available = sink_available;
+ ret |= 1;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(is_sink_cap_changed);
+
+static bool video_on[VD_PATH_MAX];
+int is_video_turn_on(bool *vd_on, enum vd_path_e vd_path)
+{
+ int ret = 0;
+
+ if (vd_on[vd_path] != is_video_layer_on(vd_path)) {
+ vd_on[vd_path] = is_video_layer_on(vd_path);
+ ret = vd_on[vd_path] ? 1 : -1;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(is_video_turn_on);
+
static int vpp_matrix_update(
struct vframe_s *vf, struct vinfo_s *vinfo, int flags,
enum vd_path_e vd_path)
@@ -6951,13 +7125,19 @@ static int vpp_matrix_update(
else
csc_type = get_csc_type();
-
- if (video_process_status[vd_path] == HDR_MODULE_BYPASS) {
- if (is_video_layer_on(vd_path) &&
- (!is_dolby_vision_on() || (vd_path == VD2_PATH)))
+ if ((video_process_status[vd_path] == HDR_MODULE_BYPASS) &&
+ !(video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS)) {
+ if ((is_video_layer_on(vd_path) ||
+ video_layer_wait_on[vd_path]) &&
+ (!is_dolby_vision_on() ||
+ (vd_path == VD2_PATH))) {
video_process_status[vd_path] = HDR_MODULE_ON;
- else
+ pr_csc(4,
+ "video_process_status[%s] = HDR_MODULE_ON\n",
+ vd_path == VD1_PATH ? "VD1" : "VD2");
+ } else {
return 2;
+ }
}
if (is_dolby_vision_on() && (vd_path == VD1_PATH))
@@ -6969,6 +7149,12 @@ static int vpp_matrix_update(
enum vd_path_e oth_path =
(vd_path == VD1_PATH) ? VD2_PATH : VD1_PATH;
+ if (get_hdr_policy() != cur_hdr_policy) {
+ pr_csc(4, "policy changed from %d to %d.\n",
+ cur_hdr_policy,
+ 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);
@@ -7026,11 +7212,13 @@ static int vpp_matrix_update(
SIG_SRC_OUTPUT_CHG | SIG_HDR10_PLUS_MODE |
SIG_SRC_CHG | SIG_HDR_OOTF_CHG))) {
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) &&
- (get_cpu_type() != MESON_CPU_MAJOR_ID_TL1))
+ (get_cpu_type() != MESON_CPU_MAJOR_ID_TL1)) {
video_post_process(csc_type, vinfo, vd_path);
- else
+ cur_hdr_policy = get_hdr_policy();
+ } else {
video_process(vf, csc_type, signal_change_flag,
vinfo, p, vd_path);
+ }
}
/* eye protection mode */
@@ -7040,11 +7228,12 @@ static int vpp_matrix_update(
return 0;
}
+static struct vframe_s last_vf_backup[VD_PATH_MAX];
static struct vframe_s *last_vf[VD_PATH_MAX];
static int last_vf_signal_type[VD_PATH_MAX];
-static int null_vf_cnt[VD_PATH_MAX];
-static int prev_hdr_support;
+static int null_vf_cnt[VD_PATH_MAX] = {2, 2};
static int prev_color_fmt;
+static bool dovi_on;
static unsigned int fg_vf_sw_dbg;
unsigned int null_vf_max = 2;
@@ -7057,9 +7246,12 @@ int amvecm_matrix_process(
{
struct vframe_s fake_vframe;
struct vinfo_s *vinfo = get_current_vinfo();
- int toggle_frame;
+ int toggle_frame = 0;
int i;
int ret;
+ int sink_changed = 0;
+ bool cap_changed = false;
+ bool send_fake_frame = false;
if ((get_cpu_type() < MESON_CPU_MAJOR_ID_GXTVBB) ||
is_meson_gxl_package_905M2() || (csc_en == 0) ||
@@ -7083,15 +7275,43 @@ int amvecm_matrix_process(
CSC_ON);
}
- if (is_dolby_vision_on() && vd_path == VD1_PATH) {
- if ((video_process_status[vd_path] == HDR_MODULE_BYPASS)
- && (vf || vf_rpt))
- return vpp_matrix_update(
- vf ? vf : vf_rpt, vinfo, flags, vd_path);
- else
- return 0;
+ if (vd_path == VD1_PATH) {
+ if (is_dolby_vision_on()) {
+ dovi_on = true;
+ if ((video_process_status[vd_path]
+ == HDR_MODULE_BYPASS) &&
+ (vf || vf_rpt))
+ return vpp_matrix_update(
+ vf ? vf : vf_rpt,
+ vinfo, flags, vd_path);
+ else
+ return 0;
+ } else {
+ /* dv from on to off */
+ if (dovi_on) {
+ cap_changed = true;
+ dovi_on = false;
+ }
+ }
}
+ sink_changed = is_sink_cap_changed(vinfo,
+ &current_hdr_cap[vd_path],
+ &current_sink_available[vd_path]);
+ if (sink_changed) {
+ cap_changed = sink_changed & 0x02;
+ pr_csc(4, "sink %s, cap%s 0x%x, vd%d %s %p %p\n",
+ current_sink_available[vd_path] ? "on" : "off",
+ cap_changed ? " changed" : "",
+ current_hdr_cap[vd_path],
+ vd_path + 1,
+ is_video_layer_on(vd_path) ? "on" : "off",
+ vf, vf_rpt);
+ }
+
+ if (is_video_turn_on(video_on, vd_path) == 1)
+ cap_changed = true;
+
if ((vf != NULL) && (flags & CSC_FLAG_CHECK_OUTPUT)) {
ret = vpp_matrix_update(vf, vinfo, flags, vd_path);
if (ret == 1) {
@@ -7105,12 +7325,20 @@ int amvecm_matrix_process(
}
} else if ((vf != NULL) && (flags & CSC_FLAG_TOGGLE_FRAME)) {
if (is_video_layer_on(vd_path) ||
+ video_layer_wait_on[vd_path] ||
video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) {
- video_process_status[vd_path] = HDR_MODULE_ON;
+ if (video_process_status[vd_path] != HDR_MODULE_ON) {
+ video_process_status[vd_path] = HDR_MODULE_ON;
+ pr_csc(4,
+ "video_process_status[%s] = HDR_MODULE_ON\n",
+ vd_path == VD1_PATH ? "VD1" : "VD2");
+ }
vpp_matrix_update(vf, vinfo, flags, vd_path);
video_process_flags[vd_path] &=
~PROC_FLAG_FORCE_PROCESS;
- last_vf[vd_path] = vf;
+ memcpy(&last_vf_backup[vd_path], vf,
+ sizeof(struct vframe_s));
+ last_vf[vd_path] = &last_vf_backup[vd_path];
last_vf_signal_type[vd_path] = vf->signal_type;
null_vf_cnt[vd_path] = 0;
pr_csc(2, "vd%d: process toggle frame(%p) %x\n",
@@ -7123,100 +7351,180 @@ int amvecm_matrix_process(
fg_vf_sw_dbg = 1;
/* debug vframe info backup */
dbg_vf = vf;
- } else if ((vf_rpt != NULL) && is_video_layer_on(vd_path)) {
- if (video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) {
+ } else if (vf_rpt &&
+ (is_video_layer_on(vd_path) ||
+ video_layer_wait_on[vd_path])) {
+ if ((video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) ||
+ cap_changed) {
+ if (video_process_status[vd_path] != HDR_MODULE_ON) {
+ video_process_status[vd_path] = HDR_MODULE_ON;
+ pr_csc(4,
+ "video_process_status[%s] = HDR_MODULE_ON\n",
+ vd_path == VD1_PATH ? "VD1" : "VD2");
+ }
vpp_matrix_update(vf_rpt, vinfo, flags, vd_path);
video_process_flags[vd_path] &=
~PROC_FLAG_FORCE_PROCESS;
- pr_csc(2, "vd%d: rpt and process frame(%p)\n",
- vd_path + 1, vf_rpt);
- } else
+ pr_csc(4, "vd%d: rpt and process frame(%p)\n",
+ vd_path + 1, vf_rpt);
+ } else {
pr_csc(2, "vd%d: rpt frame(%p)\n", vd_path + 1, vf_rpt);
+ }
null_vf_cnt[vd_path] = 0;
fg_vf_sw_dbg = 2;
- } else if ((last_vf[vd_path] != NULL) && is_video_layer_on(vd_path)) {
- pr_csc(2, "vd%d: rpt frame local\n",
- vd_path + 1);
+ } else if (last_vf[vd_path] &&
+ (is_video_layer_on(vd_path) ||
+ video_layer_wait_on[vd_path])) {
+ if (video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS ||
+ cap_changed) {
+ vpp_matrix_update(
+ last_vf[vd_path], vinfo, flags, vd_path);
+ video_process_flags[vd_path] &=
+ ~PROC_FLAG_FORCE_PROCESS;
+ pr_csc(4, "vd%d: rpt and process frame local(%p)\n",
+ vd_path + 1, last_vf[vd_path]);
+ } else {
+ pr_csc(2, "vd%d: rpt frame local\n",
+ vd_path + 1);
+ }
null_vf_cnt[vd_path] = 0;
fg_vf_sw_dbg = 3;
} else {
+ last_vf[vd_path] = NULL;
+
+ if (null_vf_cnt[vd_path] <= null_vf_max)
+ null_vf_cnt[vd_path]++;
+
/* handle change between TV support/not support HDR */
- if (prev_hdr_support != vinfo->hdr_info.hdr_support) {
- if ((vd_path == VD1_PATH) ||
- ((vd_path == VD2_PATH) &&
- is_video_layer_on(VD2_PATH)))
+ if (cap_changed) {
+ if (is_video_layer_on(vd_path))
null_vf_cnt[vd_path] = 0;
- prev_hdr_support = vinfo->hdr_info.hdr_support;
- pr_csc(2, "vd%d: hdr_support changed\n",
- vd_path + 1);
+ pr_csc(4, "vd%d: sink cap changed when idle\n",
+ vd_path + 1);
}
+
/* handle change between output mode*/
if (prev_color_fmt != vinfo->viu_color_fmt) {
- if ((vd_path == VD1_PATH) ||
- ((vd_path == VD2_PATH) &&
- is_video_layer_on(VD2_PATH)))
+ if (is_video_layer_on(vd_path))
null_vf_cnt[vd_path] = 0;
prev_color_fmt = vinfo->viu_color_fmt;
- pr_csc(2, "vd%d: output color format changed\n",
- vd_path + 1);
+ pr_csc(4, "vd%d: output color format changed\n",
+ vd_path + 1);
}
+
/* handle eye protect mode */
- if ((cur_eye_protect_mode != wb_val[0])
- && (vd_path == VD1_PATH)) {
+ if ((cur_eye_protect_mode != wb_val[0]) &&
+ (vd_path == VD1_PATH) &&
+ is_video_layer_on(vd_path)) {
null_vf_cnt[vd_path] = 0;
- pr_csc(2, "vd%d: eye_protect_mode changed\n",
- vd_path + 1);
+ pr_csc(4, "vd%d: eye_protect_mode changed\n",
+ vd_path + 1);
}
- if (!is_video_layer_on(vd_path)
- && (video_process_status[vd_path] == HDR_MODULE_ON))
- null_vf_cnt[vd_path] = toggle_frame = 1;
- else if (csc_en & 0x10)
- toggle_frame = null_vf_max;
- else
- toggle_frame = 0;
-
/* handle sdr_mode change */
- if ((vinfo->hdr_info.hdr_support & 0xc) &&
- ((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) &&
- (vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
+ if (is_video_layer_on(vd_path) &&
+ (vinfo->hdr_info.hdr_support & 0x4) &&
+ ((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) &&
+ (vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
- if (hdr_mode != cur_hdr_mode) {
- null_vf_cnt[vd_path] = toggle_frame;
- cur_hdr_mode = hdr_mode;
- pr_csc(2, "vd%d: hdr_mode changed\n",
- vd_path + 1);
- }
if (sdr_mode != cur_sdr_mode) {
- null_vf_cnt[vd_path] = toggle_frame;
+ null_vf_cnt[vd_path] = 0;
cur_sdr_mode = sdr_mode;
- pr_csc(2, "vd%d: sdr_mode changed\n",
- vd_path + 1);
+ pr_csc(4, "vd%d: sdr_mode changed\n",
+ vd_path + 1);
}
- } else if (((sdr_process_mode[vd_path] !=
- PROC_SDR_TO_HDR)
- && (sdr_mode > 0))
- || ((sdr_process_mode[vd_path] > PROC_BYPASS) &&
- (sdr_process_mode[vd_path] != PROC_OFF) &&
- (sdr_mode == 0)))
- null_vf_cnt[vd_path] = toggle_frame;
+ } else {
+ if (((sdr_process_mode[vd_path] !=
+ PROC_SDR_TO_HDR) &&
+ (sdr_mode > 0)) ||
+ ((sdr_process_mode[vd_path]
+ > PROC_BYPASS) &&
+ (sdr_process_mode[vd_path]
+ != PROC_OFF) &&
+ (sdr_mode == 0))) {
+ null_vf_cnt[vd_path] = 0;
+ pr_csc(4, "vd%d: sdr_mode changed\n",
+ vd_path + 1);
+ }
+ }
+ }
+ if (!is_dolby_vision_enable() &&
+ get_hdr_policy() != cur_hdr_policy) {
+ null_vf_cnt[vd_path] = 1;
+ toggle_frame = 1;
+ } else if (!is_video_layer_on(vd_path) &&
+ (video_process_status[vd_path]
+ == HDR_MODULE_ON)) {
+ null_vf_cnt[vd_path] = 1;
+ toggle_frame = 1;
+ } else if (csc_en & 0x10) {
+ toggle_frame = null_vf_max;
+ } else {
+ toggle_frame = 0;
}
-
if (null_vf_cnt[vd_path] == toggle_frame) {
- pr_csc(8,
- "vd%d: %d %d Fake SDR frame%s, dolby on=%d, dolby policy =%d\n",
- vd_path + 1,
- null_vf_cnt[vd_path],
- toggle_frame,
- is_video_layer_on(vd_path) ?
- " " : ", video off",
- is_dolby_vision_on(),
- get_dolby_vision_policy());
- video_process_status[vd_path] = HDR_MODULE_OFF;
- if ((get_dolby_vision_policy() != 0) ||
- (!is_dolby_vision_on())) {
- /*send a faked vframe to switch matrix*/
- /*from 2020 to 601 when video disabled */
+ if (null_vf_cnt[vd_path] == 0) {
+ /* video on */
+ video_process_flags[vd_path] |=
+ PROC_FLAG_FORCE_PROCESS;
+ return 0;
+ }
+ /* video off */
+ if (is_dolby_vision_enable()) {
+ /* dolby enable */
+ pr_csc(8,
+ "vd%d: %d %d Fake SDR frame%s, dolby on=%d, dolby policy =%d\n",
+ vd_path + 1,
+ null_vf_cnt[vd_path],
+ toggle_frame,
+ is_video_layer_on(vd_path) ?
+ " " : ", video off",
+ is_dolby_vision_on(),
+ get_dolby_vision_policy());
+ if (vd_path == VD2_PATH ||
+ (vd_path == VD1_PATH &&
+ (get_dolby_vision_policy() !=
+ DOLBY_VISION_FOLLOW_SINK ||
+ get_source_type(VD1_PATH) ==
+ HDRTYPE_HDR10PLUS ||
+ get_source_type(VD1_PATH)
+ == HDRTYPE_HLG))) {
+ /* and VD1 adaptive or VD2 */
+ /* or always hdr hdr+/hlg bypass */
+ /* faked vframe to switch matrix */
+ /* 2020 to 601 when video disabled */
+ /* and bypass hdr module for dv core*/
+ send_fake_frame = true;
+ video_process_status[vd_path] =
+ HDR_MODULE_OFF;
+ }
+ } else {
+ /* dolby disable */
+ pr_csc(8,
+ "vd%d: %d %d Fake SDR frame%s, policy =%d\n",
+ vd_path + 1,
+ null_vf_cnt[vd_path],
+ toggle_frame,
+ is_video_layer_on(vd_path) ?
+ " " : ", video off",
+ get_hdr_policy());
+ send_fake_frame = true;
+ if (get_hdr_policy() == 1) {
+ /* adaptive hdr */
+ /* faked vframe to switch matrix */
+ /* turn off hdr module */
+ video_process_status[vd_path] =
+ HDR_MODULE_OFF;
+ } else {
+ /* always hdr */
+ /* faked vframe to switch matrix */
+ /* hdr module to handle osd */
+ video_process_status[vd_path] =
+ HDR_MODULE_ON;
+ }
+ }
+
+ if (send_fake_frame) {
fake_vframe.source_type =
VFRAME_SOURCE_TYPE_OTHERS;
fake_vframe.signal_type = 0;
@@ -7225,23 +7533,25 @@ int amvecm_matrix_process(
fake_vframe.prop.
master_display_colour.present_flag
= 0x80000000;
- if (null_vf_cnt[vd_path] == toggle_frame)
- vpp_matrix_update(
- &fake_vframe, vinfo,
- CSC_FLAG_TOGGLE_FRAME, vd_path);
- else if (null_vf_cnt[vd_path] == 0)
- vpp_matrix_update(
- &fake_vframe, vinfo,
- CSC_FLAG_CHECK_OUTPUT, vd_path);
+ vpp_matrix_update(
+ &fake_vframe, vinfo,
+ CSC_FLAG_TOGGLE_FRAME, vd_path);
+ last_vf[vd_path] = NULL;
+ null_vf_cnt[vd_path] = null_vf_max + 1;
+ fg_vf_sw_dbg = 4;
+ dbg_vf = NULL;
+ video_process_status[vd_path] =
+ HDR_MODULE_BYPASS;
+ pr_csc(4,
+ "video_process_status[%s] = HDR_MODULE_BYPASS\n",
+ vd_path == VD1_PATH ? "VD1" : "VD2");
+ if ((vd_path == VD2_PATH) &&
+ (is_video_layer_on(VD1_PATH) ||
+ video_layer_wait_on[VD1_PATH]))
+ video_process_flags[VD1_PATH] |=
+ PROC_FLAG_FORCE_PROCESS;
}
- last_vf[vd_path] = NULL;
- null_vf_cnt[vd_path] = null_vf_max;
- fg_vf_sw_dbg = 4;
- dbg_vf = NULL;
- video_process_status[vd_path] = HDR_MODULE_BYPASS;
}
- if (null_vf_cnt[vd_path] <= null_vf_max)
- null_vf_cnt[vd_path]++;
}
return 0;
}
diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.h b/drivers/amlogic/media/enhancement/amvecm/amcsc.h
index 3dd6a85..b63ed64 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amcsc.h
+++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.h
@@ -101,6 +101,12 @@ enum output_format_e {
#define HDR_SUPPORT (1 << 2)
#define HLG_SUPPORT (1 << 3)
+bool is_vinfo_available(const struct vinfo_s *vinfo);
+int is_sink_cap_changed(const struct vinfo_s *vinfo,
+ int *p_current_hdr_cap,
+ int *p_current_sink_available);
+int is_video_turn_on(bool *vd_on, enum vd_path_e vd_path);
+
#define SIG_CS_CHG 0x01
#define SIG_SRC_CHG 0x02
#define SIG_PRI_INFO 0x04
@@ -132,6 +138,9 @@ extern int video_rgb_ogo_xvy_mtx;
extern int tx_op_color_primary;
extern uint cur_csc_type[VD_PATH_MAX];
+int get_hdr_policy(void);
+enum output_format_e get_force_output(void);
+
/* 0: hdr->hdr, 1:hdr->sdr, 2:hdr->hlg */
extern uint hdr_process_mode[VD_PATH_MAX];
extern uint cur_hdr_process_mode[VD_PATH_MAX];
@@ -158,6 +167,10 @@ extern int amvecm_hdr_dbg(u32 sel);
extern u32 get_video_enabled(void);
extern u32 get_videopip_enabled(void);
+
+void set_video_mute(bool on);
+int get_video_mute(void);
+
extern void get_hdr_source_type(void);
extern void get_cur_vd_signal_type(enum vd_path_e vd_path);
extern enum color_primary_e get_color_primary(void);
diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c
index ff5f23b..17a907b 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c
+++ b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c
@@ -23,12 +23,6 @@
#include "set_hdr2_v0.h"
#include "hdr/am_hdr10_plus.h"
-/* 0: follow sink, 1: follow source */
-static uint hdr_policy = 1;
-module_param(hdr_policy, uint, 0664);
-MODULE_PARM_DESC(hdr_policy, "\n hdr policy\n");
-
-static uint cur_hdr_policy;
static enum output_format_e target_format[VD_PATH_MAX];
static enum hdr_type_e cur_source_format[VD_PATH_MAX];
static enum output_format_e output_format;
@@ -125,8 +119,10 @@ int hdr_policy_process(
int change_flag = 0;
enum vd_path_e oth_path =
(vd_path == VD1_PATH) ? VD2_PATH : VD1_PATH;
+ int cur_hdr_policy;
int dv_policy = 0;
int dv_mode = 0;
+ int dv_format = 0;
bool hdr10_plus_support =
(vinfo->hdr_info.hdr10plus_info.ieeeoui
== HDR_PLUS_IEEE_OUI) &&
@@ -135,37 +131,53 @@ int hdr_policy_process(
tx_hdr10_plus_support = hdr10_plus_support;
- cur_hdr_policy = hdr_policy;
+ cur_hdr_policy = get_hdr_policy();
if (is_dolby_vision_enable()) {
/* sync hdr_policy with dolby_vision_policy */
/* get current dolby_vision_mode */
dv_policy = get_dolby_vision_policy();
dv_mode = get_dolby_vision_mode();
- if ((dv_policy != DOLBY_VISION_FORCE_OUTPUT_MODE)
- || (dv_mode != DOLBY_VISION_OUTPUT_MODE_BYPASS)) {
- /* use dv policy when not force bypass */
- cur_hdr_policy = dv_policy;
- }
+ dv_format = get_dolby_vision_src_format();
}
- if ((get_hdr_module_status(vd_path) != HDR_MODULE_ON)
- && is_dolby_vision_enable()) {
+ if (get_hdr_module_status(vd_path) != HDR_MODULE_ON) {
+ /* hdr module off or bypass */
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;
target_format[vd_path] = BT709;
} else if (cur_hdr_policy == 0) {
- if ((vd_path == VD1_PATH)
- && (source_format[vd_path] == HDRTYPE_HLG)
- && (vinfo->hdr_info.hdr_support & HLG_SUPPORT)) {
+ if (vd_path == VD1_PATH &&
+ is_dolby_vision_enable() &&
+ !is_dolby_vision_on() &&
+ (source_format[vd_path]
+ == HDRTYPE_DOVI ||
+ source_format[vd_path]
+ == HDRTYPE_HDR10 ||
+ source_format[vd_path]
+ == HDRTYPE_SDR)) {
+ /* vd1 follow sink: dv handle sdr/hdr/dovi */
+ 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;
+ target_format[vd_path] = BT709;
+ set_hdr_module_status(vd_path, HDR_MODULE_OFF);
+ dolby_vision_set_toggle_flag(1);
+ } else if ((vd_path == VD1_PATH) &&
+ (source_format[vd_path]
+ == HDRTYPE_HLG) &&
+ (vinfo->hdr_info.hdr_support
+ & HLG_SUPPORT)) {
/* vd1 bypass hlg */
hlg_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT2020_HLG;
- } else if ((vd_path == VD1_PATH)
- && (!is_video_layer_on(VD2_PATH))
- && (source_format[vd_path] == HDRTYPE_HDR10PLUS)
- && hdr10_plus_support) {
+ } else if ((vd_path == VD1_PATH) &&
+ (!is_video_layer_on(VD2_PATH)) &&
+ (source_format[vd_path]
+ == HDRTYPE_HDR10PLUS) &&
+ hdr10_plus_support) {
/* vd1 bypass hdr+ when vd2 off */
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT2020_PQ_DYNAMIC;
@@ -176,8 +188,8 @@ int hdr_policy_process(
sdr_process_mode[vd_path] = PROC_MATCH;
hdr10_plus_process_mode[vd_path] = PROC_MATCH;
target_format[vd_path] = BT2100_IPT;
- } else if ((vd_path == VD2_PATH)
- && is_video_layer_on(VD1_PATH)) {
+ } else if ((vd_path == VD2_PATH) &&
+ is_video_layer_on(VD1_PATH)) {
/* vd1 on and vd2 follow vd1 output */
if (target_format[VD1_PATH] == BT2020_HLG) {
/* vd2 *->hlg when vd1 output hlg */
@@ -188,7 +200,8 @@ int hdr_policy_process(
PROC_HDRP_TO_HLG;
target_format[vd_path] = BT2020_HLG;
} else if ((target_format[VD1_PATH] == BT2020_PQ) ||
- (target_format[VD1_PATH] == BT2020_PQ_DYNAMIC)) {
+ (target_format[VD1_PATH]
+ == BT2020_PQ_DYNAMIC)) {
/* vd2 *->hdr when vd1 output hdr/hdr+ */
sdr_process_mode[vd_path] = PROC_SDR_TO_HDR;
hdr_process_mode[vd_path] = PROC_BYPASS;
@@ -209,10 +222,10 @@ int hdr_policy_process(
else
target_format[vd_path] = BT709;
}
- } else if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT)
- && ((source_format[vd_path] != HDRTYPE_HLG)
- || ((source_format[vd_path] == HDRTYPE_HLG)
- && (hdr_flag & 0x10)))) {
+ } else if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT) &&
+ ((source_format[vd_path] != HDRTYPE_HLG) ||
+ ((source_format[vd_path] == HDRTYPE_HLG) &&
+ (hdr_flag & 0x10)))) {
/* *->hdr */
sdr_process_mode[vd_path] = PROC_SDR_TO_HDR;
hdr_process_mode[vd_path] = PROC_BYPASS;
@@ -227,10 +240,11 @@ int hdr_policy_process(
hlg_process_mode[vd_path] = PROC_HLG_TO_SDR;
hdr10_plus_process_mode[vd_path] =
PROC_HDRP_TO_SDR;
-#if 0
+#ifdef AMCSC_DEBUG_TEST
if ((vinfo->hdr_info.colorimetry_support
& SINK_SUPPORTS_BT2020) &&
- (source_format[vd_path] == HDRTYPE_HLG) &&
+ ((source_format[vd_path] == HDRTYPE_HLG) ||
+ (source_format[vd_path] == HDRTYPE_HDR10)) &&
!is_video_layer_on(oth_path))
target_format[vd_path] = BT2020;
else
@@ -240,14 +254,28 @@ int hdr_policy_process(
#endif
}
} else if (cur_hdr_policy == 1) {
- if ((vd_path == VD2_PATH) && is_dolby_vision_on()) {
+ if (vd_path == VD1_PATH &&
+ is_dolby_vision_enable() &&
+ !is_dolby_vision_on() &&
+ source_format[vd_path]
+ == HDRTYPE_DOVI) {
+ /* vd1 follow source: dv handle dovi */
+ 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;
+ target_format[vd_path] = BT709;
+ set_hdr_module_status(vd_path, HDR_MODULE_OFF);
+ dolby_vision_set_toggle_flag(1);
+ } else if ((vd_path == VD2_PATH) && is_dolby_vision_on()) {
/* VD2 with VD1 in DV mode */
hdr_process_mode[vd_path] = PROC_MATCH;
hlg_process_mode[vd_path] = PROC_MATCH;
sdr_process_mode[vd_path] = PROC_MATCH; /* *->ipt */
target_format[vd_path] = BT2100_IPT;
- } else if ((vd_path == VD1_PATH)
- || ((vd_path == VD2_PATH) && !is_video_layer_on(VD1_PATH))) {
+ } else if ((vd_path == VD1_PATH) ||
+ ((vd_path == VD2_PATH) &&
+ !is_video_layer_on(VD1_PATH))) {
/* VD1(with/without VD2) */
/* or VD2(without VD1) <= should switch to VD1 */
switch (source_format[vd_path]) {
@@ -314,7 +342,7 @@ int hdr_policy_process(
/* hlg->sdr */
hlg_process_mode[vd_path] =
PROC_HLG_TO_SDR;
-#if 0
+#ifdef AMCSC_DEBUG_TEST
if ((vinfo->hdr_info.colorimetry_support
& SINK_SUPPORTS_BT2020) &&
!is_video_layer_on(oth_path))
@@ -347,8 +375,17 @@ int hdr_policy_process(
/* hdr ->sdr */
hdr_process_mode[vd_path] =
PROC_HDR_TO_SDR;
+#ifdef AMCSC_DEBUG_TEST
+ if ((vinfo->hdr_info.colorimetry_support
+ & SINK_SUPPORTS_BT2020) &&
+ !is_video_layer_on(oth_path))
+ target_format[vd_path] =
+ BT2020;
+ else
+#else
target_format[vd_path] =
BT709;
+#endif
}
break;
case HDRTYPE_HDR10PLUS:
@@ -376,7 +413,17 @@ int hdr_policy_process(
/* hdr+ *->sdr */
hdr10_plus_process_mode[vd_path] =
PROC_HDRP_TO_SDR;
- target_format[vd_path] = BT709;
+#ifdef AMCSC_DEBUG_TEST
+ if ((vinfo->hdr_info.colorimetry_support
+ & SINK_SUPPORTS_BT2020) &&
+ !is_video_layer_on(oth_path))
+ target_format[vd_path] =
+ BT2020;
+ else
+#else
+ target_format[vd_path] =
+ BT709;
+#endif
}
break;
default:
@@ -501,12 +548,182 @@ int hdr_policy_process(
}
}
}
- } else if (cur_hdr_policy == 2) {
- /* *->ipt */
- hdr_process_mode[vd_path] = PROC_MATCH;
- hlg_process_mode[vd_path] = PROC_MATCH;
- sdr_process_mode[vd_path] = PROC_MATCH;
- target_format[vd_path] = BT2100_IPT;
+ } else if (cur_hdr_policy == 2 &&
+ !is_dolby_vision_enable()) {
+ /* dv off, and policy == debug */
+ /* *->force_output */
+ if ((vd_path == VD1_PATH) ||
+ ((vd_path == VD2_PATH) &&
+ !is_video_layer_on(VD1_PATH))) {
+ /* VD1 or VD2 without VD1 */
+ target_format[vd_path] = get_force_output();
+ switch (target_format[vd_path]) {
+ case BT709:
+ sdr_process_mode[vd_path] =
+ PROC_BYPASS;
+ hlg_process_mode[vd_path] =
+ PROC_HLG_TO_SDR;
+ hdr_process_mode[vd_path] =
+ PROC_HDR_TO_SDR;
+ hdr10_plus_process_mode[vd_path]
+ = PROC_HDRP_TO_SDR;
+ break;
+ case BT2020:
+ break;
+ case BT2020_PQ:
+ sdr_process_mode[vd_path] =
+ PROC_SDR_TO_HDR;
+ hlg_process_mode[vd_path] =
+ PROC_HLG_TO_HDR;
+ hdr_process_mode[vd_path] =
+ PROC_BYPASS;
+ hdr10_plus_process_mode[vd_path]
+ = PROC_HDRP_TO_HDR;
+ break;
+ case BT2020_PQ_DYNAMIC:
+ sdr_process_mode[vd_path] =
+ PROC_SDR_TO_HDR;
+ hlg_process_mode[vd_path] =
+ PROC_HLG_TO_HDR;
+ hdr_process_mode[vd_path] =
+ PROC_BYPASS;
+ hdr10_plus_process_mode[vd_path] =
+ PROC_BYPASS;
+ break;
+ case BT2020_HLG:
+ sdr_process_mode[vd_path] =
+ PROC_SDR_TO_HLG;
+ hlg_process_mode[vd_path] =
+ PROC_BYPASS;
+ hdr_process_mode[vd_path] =
+ PROC_HDR_TO_HLG;
+ hdr10_plus_process_mode[vd_path]
+ = PROC_HDRP_TO_HLG;
+ break;
+ case BT2100_IPT:
+ /* hdr module not handle dv output */
+ default:
+ break;
+ }
+ } else {
+ /* VD2 with VD1 on */
+ if (is_dolby_vision_on()) {
+ /* VD1 is dolby vision */
+ hdr_process_mode[vd_path] = PROC_MATCH;
+ hlg_process_mode[vd_path] = PROC_MATCH;
+ sdr_process_mode[vd_path] = PROC_MATCH;
+ target_format[vd_path] = BT2100_IPT;
+ } else {
+ oth_path = VD1_PATH;
+ switch (source_format[vd_path]) {
+ case HDRTYPE_SDR:
+ /* VD2 source SDR */
+ if ((target_format[oth_path] ==
+ BT2020_PQ) ||
+ (target_format[oth_path] ==
+ BT2020_PQ_DYNAMIC)) {
+ /* other layer output HDR */
+ /* sdr *->hdr */
+ sdr_process_mode[vd_path] =
+ PROC_SDR_TO_HDR;
+ target_format[vd_path] =
+ BT2020_PQ;
+ } else if (target_format[oth_path] ==
+ BT2020_HLG) {
+ /* other layer on and not sdr */
+ /* sdr *->hlg */
+ sdr_process_mode[vd_path] =
+ PROC_SDR_TO_HLG;
+ target_format[vd_path] =
+ BT2020_HLG;
+ } else {
+ /* sdr->sdr */
+ sdr_process_mode[vd_path] =
+ PROC_BYPASS;
+ target_format[vd_path] = BT709;
+ }
+ break;
+ case HDRTYPE_HLG:
+ /* VD2 source HLG */
+ if (target_format[oth_path]
+ == BT2020_HLG) {
+ /* hlg->hlg */
+ hlg_process_mode[vd_path] =
+ PROC_BYPASS;
+ target_format[vd_path] =
+ BT2020_HLG;
+ } else if ((target_format[oth_path] ==
+ BT2020_PQ) ||
+ (target_format[oth_path] ==
+ BT2020_PQ_DYNAMIC)) {
+ /* hlg->hdr */
+ hlg_process_mode[vd_path] =
+ PROC_HLG_TO_HDR;
+ target_format[vd_path] =
+ BT2020_PQ;
+ } else if (target_format[oth_path] ==
+ BT709) {
+ /* hlg->sdr */
+ hlg_process_mode[vd_path] =
+ PROC_HLG_TO_SDR;
+ target_format[vd_path] = BT709;
+ }
+ break;
+ case HDRTYPE_HDR10:
+ /* VD2 source HDR10 */
+ if ((target_format[oth_path] ==
+ BT2020_PQ) ||
+ (target_format[oth_path] ==
+ BT2020_PQ_DYNAMIC)) {
+ /* hdr->hdr */
+ hdr_process_mode[vd_path] =
+ PROC_BYPASS;
+ target_format[vd_path] =
+ BT2020_PQ;
+ } else if (target_format[oth_path]
+ == BT2020_HLG) {
+ /* hdr->hlg */
+ hdr_process_mode[vd_path] =
+ PROC_HDR_TO_HLG;
+ target_format[vd_path] =
+ BT2020_HLG;
+ } else {
+ /* hdr->sdr */
+ hdr_process_mode[vd_path] =
+ PROC_HDR_TO_SDR;
+ target_format[vd_path] = BT709;
+ }
+ break;
+ case HDRTYPE_HDR10PLUS:
+ /* VD2 source HDR10+ */
+ if ((target_format[oth_path] ==
+ BT2020_PQ) ||
+ (target_format[oth_path] ==
+ BT2020_PQ_DYNAMIC)) {
+ /* hdr->hdr */
+ hdr10_plus_process_mode[vd_path]
+ = PROC_HDRP_TO_HDR;
+ target_format[vd_path] =
+ BT2020_PQ;
+ } else if (target_format[oth_path]
+ == BT2020_HLG) {
+ /* hdr->hlg */
+ hdr_process_mode[vd_path] =
+ PROC_HDR_TO_HLG;
+ target_format[vd_path] =
+ BT2020_HLG;
+ } else {
+ /* hdr->sdr */
+ hdr10_plus_process_mode[vd_path]
+ = PROC_HDRP_TO_SDR;
+ target_format[vd_path] = BT709;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
/* update change flags */
@@ -515,7 +732,7 @@ int hdr_policy_process(
pr_csc(4, "am_vecm: vd%d: (%s) %s->%s.\n",
vd_path + 1,
policy_str[dv_policy],
- input_str[get_dolby_vision_src_format()],
+ input_str[dv_format],
dv_output_str[dv_mode]);
} else {
if (cur_hdr10_plus_process_mode[vd_path]
@@ -545,19 +762,19 @@ int hdr_policy_process(
}
cur_source_format[vd_path] = source_format[vd_path];
- if (is_dolby_vision_on()
- && (vd_path == VD2_PATH)
- && is_video_layer_on(VD2_PATH)
- && (target_format[vd_path] != BT2100_IPT)) {
+ if (is_dolby_vision_on() &&
+ (vd_path == VD2_PATH) &&
+ is_video_layer_on(VD2_PATH) &&
+ (target_format[vd_path] != BT2100_IPT)) {
pr_csc(4, "am_vecm: vd%d output mode not match to dolby %s.\n",
vd_path + 1,
output_str[target_format[vd_path]]);
change_flag |= SIG_OUTPUT_MODE_CHG;
- } else if (!is_dolby_vision_on()
- && is_video_layer_on(VD1_PATH)
- && is_video_layer_on(VD2_PATH)
- && (target_format[vd_path]
- != target_format[oth_path])) {
+ } else if (!is_dolby_vision_on() &&
+ is_video_layer_on(VD1_PATH) &&
+ is_video_layer_on(VD2_PATH) &&
+ (target_format[vd_path]
+ != target_format[oth_path])) {
pr_csc(4, "am_vecm: vd%d output mode not match %s %s.\n",
vd_path + 1,
output_str[target_format[vd_path]],
@@ -767,7 +984,22 @@ void video_post_process(
struct vinfo_s *vinfo,
enum vd_path_e vd_path)
{
- switch (cur_source_format[vd_path]) {
+ enum hdr_type_e src_format = cur_source_format[vd_path];
+
+ if (get_hdr_module_status(vd_path) == HDR_MODULE_OFF) {
+ if (vd_path == VD1_PATH)
+ hdr_proc(VD1_HDR, HDR_BYPASS, vinfo);
+ else
+ hdr_proc(VD2_HDR, HDR_BYPASS, vinfo);
+ if (((vd_path == VD1_PATH) &&
+ !is_video_layer_on(VD2_PATH)) ||
+ ((vd_path == VD2_PATH) &&
+ !is_video_layer_on(VD1_PATH)))
+ hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo);
+ src_format = HDRTYPE_NONE;
+ }
+
+ switch (src_format) {
case HDRTYPE_SDR:
if (vd_path == VD2_PATH && is_dolby_vision_on()) {
hdr_proc(VD2_HDR, SDR_IPT, vinfo);
diff --git a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c
index 88f788a..de9f77e 100644
--- a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c
+++ b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c
@@ -2015,7 +2015,7 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel,
hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i];
if (i < HDR2_CGAIN_LUT_SIZE)
hdr_lut_param.cgain_lut[i] =
- cgain_lut_bypass[i] - 1;
+ cgain_lut0[i] - 1;
}
hdr_lut_param.bitdepth = bit_depth;
hdr_lut_param.lut_on = LUT_ON;
@@ -2068,11 +2068,11 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel,
hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i];
if (i < HDR2_CGAIN_LUT_SIZE)
hdr_lut_param.cgain_lut[i] =
- cgain_lut_bypass[i] - 1;
+ cgain_lut0[i] - 1;
}
hdr_lut_param.lut_on = LUT_ON;
hdr_lut_param.bitdepth = bit_depth;
- hdr_lut_param.cgain_en = LUT_OFF;
+ hdr_lut_param.cgain_en = LUT_ON;
} else if (hdr_process_select == HLG_SDR) {
for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) {
hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i];
@@ -2183,7 +2183,7 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel,
hdr_lut_param.eotf_lut[i] = eo_y_lut_pq[i];
if (i < HDR2_CGAIN_LUT_SIZE)
hdr_lut_param.cgain_lut[i] =
- cgain_lut1[i] - 1;
+ cgain_lut0[i] - 1;
}
//pr_info("\t oo_gain = %lld of 512\n",
// hdr_lut_param.ogain_lut[0]);
diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c
index a04ba14..4181ede 100644
--- a/drivers/amlogic/media/video_sink/video.c
+++ b/drivers/amlogic/media/video_sink/video.c
@@ -6128,13 +6128,6 @@ struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf)
height_el - 1;
}
- if (!get_video_enabled()) {
- /* when video layer off */
- /* not need to update setting */
- dolby_vision_set_toggle_flag(0);
- return NULL;
- };
-
if (ret == 0) {
/* setting generated for this frame */
/* or DOVI in bypass mode */
@@ -6187,6 +6180,74 @@ static int dolby_vision_drop_frame(void)
return 0;
}
#endif
+
+static bool video_mute_on;
+MODULE_PARM_DESC(video_mute_on, "\n video_mute_on\n");
+module_param(video_mute_on, bool, 0664);
+
+/* 0: off, 1: vpp mute 2:dv mute */
+static int video_mute_status;
+
+void set_video_mute(bool on)
+{
+ video_mute_on = on;
+}
+EXPORT_SYMBOL(set_video_mute);
+
+int get_video_mute(void)
+{
+ return video_mute_status;
+}
+EXPORT_SYMBOL(get_video_mute);
+
+static void check_video_mute(void)
+{
+ if (video_mute_on) {
+ if (is_dolby_vision_on()) {
+ /* core 3 black */
+ if (video_mute_status != VIDEO_MUTE_ON_DV) {
+ dolby_vision_set_toggle_flag(1);
+ pr_info("DOLBY: check_video_mute: VIDEO_MUTE_ON_DV\n");
+ }
+ video_mute_status = VIDEO_MUTE_ON_DV;
+ } else {
+ if (video_mute_status != VIDEO_MUTE_ON_VPP) {
+ /* vpp black */
+ VSYNC_WR_MPEG_REG(VPP_CLIP_MISC0,
+ (0x0 << 20) |
+ (0x200 << 10) |
+ 0x200);
+ VSYNC_WR_MPEG_REG(VPP_CLIP_MISC1,
+ (0x0 << 20) |
+ (0x200 << 10) |
+ 0x200);
+ pr_info("DOLBY: check_video_mute: VIDEO_MUTE_ON_VPP\n");
+ }
+ video_mute_status = VIDEO_MUTE_ON_VPP;
+ }
+ } else {
+ if (is_dolby_vision_on()) {
+ if (video_mute_status != VIDEO_MUTE_OFF) {
+ dolby_vision_set_toggle_flag(2);
+ pr_info("DOLBY: check_video_mute: VIDEO_MUTE_OFF dv on\n");
+ }
+ video_mute_status = VIDEO_MUTE_OFF;
+ } else {
+ if (video_mute_status != VIDEO_MUTE_OFF) {
+ VSYNC_WR_MPEG_REG(VPP_CLIP_MISC0,
+ (0x3ff << 20) |
+ (0x3ff << 10) |
+ 0x3ff);
+ VSYNC_WR_MPEG_REG(VPP_CLIP_MISC1,
+ (0x0 << 20) |
+ (0x0 << 10) | 0x0);
+ pr_info("DOLBY: check_video_mute: VIDEO_MUTE_OFF dv off\n");
+ }
+ video_mute_status = VIDEO_MUTE_OFF;
+ }
+ }
+}
+
/* patch for 4k2k bandwidth issue, skiw mali and vpu mif */
static void dmc_adjust_for_mali_vpu(unsigned int width,
unsigned int height, bool force_adjust)
@@ -7497,8 +7558,9 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
} else
vsync_toggle_frame(cur_dispbuf,
__LINE__);
- if (is_dolby_vision_enable()
- && is_dolby_vision_video_on()) {
+ if (is_dolby_vision_enable() &&
+ is_dolby_vision_on() &&
+ get_video_enabled()) {
pause_vf = cur_dispbuf;
video_pause_global = 1;
} else {
@@ -7659,6 +7721,8 @@ SET_FILTER:
if (is_dolby_vision_enable()) {
u32 frame_size = 0, h_size, v_size;
u8 pps_state = 0; /* pps no change */
+ static struct vframe_s *cur_dv_vf;
+ static u32 cur_frame_size;
/* force toggle when keeping frame after playing */
if ((cur_dispbuf == &vf_local)
@@ -7669,22 +7733,8 @@ SET_FILTER:
dolby_vision_parse_metadata(
toggle_vf, 2, false, false);
dolby_vision_set_toggle_flag(1);
- //pr_info("DOLBY: keep frame %p", toggle_vf);
+ /* pr_info("DOLBY: keep frame %p", toggle_vf); */
}
-/* pause mode was moved to video display property */
-#if 0
- /* force toggle in pause mode */
- if (cur_dispbuf
- && (cur_dispbuf != &vf_local)
- && !toggle_vf
- && is_dolby_vision_on()
- && !for_dolby_vision_certification()) {
- toggle_vf = cur_dispbuf;
- dolby_vision_parse_metadata(
- cur_dispbuf, 0, false, false);
- dolby_vision_set_toggle_flag(1);
- }
-#endif
if (cur_frame_par) {
if (frame_par_ready_to_set || frame_par_force_to_set) {
struct vppfilter_mode_s *vpp_filter =
@@ -7726,8 +7776,28 @@ SET_FILTER:
toggle_vf->compHeight : toggle_vf->height;
frame_size = (h_size << 16) | v_size;
}
- dolby_vision_process((cur_dispbuf != &vf_local)
- ? cur_dispbuf : toggle_vf, frame_size, pps_state);
+
+ if (cur_dispbuf == &vf_local) {
+ if (get_video_enabled())
+ toggle_vf = cur_dispbuf;
+ else
+ toggle_vf = NULL;
+ }
+ /* trigger dv process once when stop playing */
+ /* because toggle_vf is not sync with video off */
+ if (cur_dv_vf && !toggle_vf)
+ dolby_vision_set_toggle_flag(1);
+
+ if (cur_frame_size != frame_size) {
+ cur_frame_size = frame_size;
+ if (!toggle_vf && get_video_enabled())
+ toggle_vf = cur_dispbuf;
+ dolby_vision_set_toggle_flag(1);
+ }
+ cur_dv_vf = toggle_vf;
+ dolby_vision_process(
+ cur_dispbuf, toggle_vf,
+ frame_size, pps_state);
dolby_vision_update_setting();
}
#endif
@@ -8315,6 +8385,9 @@ SET_FILTER:
#if defined(PTS_LOGGING) || defined(PTS_TRACE_DEBUG)
pts_trace++;
#endif
+
+ check_video_mute();
+
vpp_misc_save = READ_VCBUS_REG(VPP_MISC + cur_dev->vpp_off);
vpp_misc_set = vpp_misc_save;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
@@ -13346,10 +13419,11 @@ int vout_notify_callback(struct notifier_block *block, unsigned long cmd,
spin_unlock_irqrestore(&lock, flags);
new_vmode = vinfo->mode;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- pr_info("vout_notify_callback: VOUT_EVENT_MODE_CHANGE");
- /* make sure dolby policy process runs atleast once */
+ pr_info("DOLBY: vout_notify_callback: VOUT_EVENT_MODE_CHANGE\n");
+ /* force send hdmi pkt in dv code */
+ /* to workaround pkt cleaned during hotplug */
if (is_dolby_vision_enable())
- dolby_vision_set_toggle_flag(1);
+ dolby_vision_set_toggle_flag(2);
#endif
break;
case VOUT_EVENT_OSD_PREBLEND_ENABLE:
diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h
index ea8fbe2..d3c4849c 100644
--- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h
+++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h
@@ -22,6 +22,7 @@
#define V2_4
#include <linux/types.h>
+#include <linux/amlogic/media/vout/vinfo.h>
#define DOLBY_VISION_OUTPUT_MODE_IPT 0
#define DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL 1
@@ -47,6 +48,11 @@
/* else bypass Dolby Vision */
#define DOLBY_VISION_FORCE_OUTPUT_MODE 2
+#define MUTE_TYPE_NONE 0
+#define MUTE_TYPE_YUV 1
+#define MUTE_TYPE_RGB 2
+#define MUTE_TYPE_IPT 3
+
extern void enable_dolby_vision(int enable);
extern bool is_dolby_vision_enable(void);
extern bool is_dolby_vision_on(void);
@@ -58,8 +64,9 @@ 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);
int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag);
-extern int dolby_vision_process(struct vframe_s *vf, u32 display_size,
- u8 pps_state);
+int dolby_vision_process(
+ struct vframe_s *rpt_vf, 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);
@@ -104,7 +111,9 @@ extern bool is_dovi_frame(struct vframe_s *vf);
extern void update_graphic_width_height(unsigned int width,
unsigned int height);
extern int get_dolby_vision_policy(void);
+void set_dolby_vision_policy(int policy);
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);
#endif
diff --git a/include/linux/amlogic/media/video_sink/video.h b/include/linux/amlogic/media/video_sink/video.h
index 640271b..eb67cde 100644
--- a/include/linux/amlogic/media/video_sink/video.h
+++ b/include/linux/amlogic/media/video_sink/video.h
@@ -238,6 +238,13 @@ static inline int amvideo_notifier_call_chain(unsigned long val, void *v)
}
#endif
+/* 0: off, 1: vpp mute 2:dv mute */
+#define VIDEO_MUTE_OFF 0
+#define VIDEO_MUTE_ON_VPP 1
+#define VIDEO_MUTE_ON_DV 2
+void set_video_mute(bool on);
+int get_video_mute(void);
+
int query_video_status(int type, int *value);
u32 set_blackout_policy(int policy);
u32 get_blackout_policy(void);