From 40acf218c997e3cc761469bcb1a1b11159c20428 Mon Sep 17 00:00:00 2001 From: robin zhu Date: Tue, 25 Jun 2019 13:02:14 -0700 Subject: [PATCH] dv: support PIP [1/1] PD#SWPL-9950 Problem: not support VD1+VD2 PIP for DV+None_DV or 2xNone_DV need bypass HDR+ to HDR module when Sink support need always bypass to HDR module for HLG not fully support convert between format SDR/HDR(+)/HLG not support convert all format to IPT(DV) not support follow sink/follow src policy for PIP Solution: add full matrix support to convert between SDR/HDR formats add support to convert all format to IPT(DV) rewrite policy, video process and tx handing for PIP Verify: tested and merged in raven project need test on for src need test for sink(has regression, need to fix) Change-Id: I001d9dcdcb94c95fb2b7651e726d1ebadc8f4551 Signed-off-by: robin zhu --- MAINTAINERS | 2 +- .../enhancement/amdolby_vision/amdolby_vision.c | 907 ++++++++--- .../enhancement/amdolby_vision/amdolby_vision.h | 5 +- drivers/amlogic/media/enhancement/amvecm/Makefile | 1 + drivers/amlogic/media/enhancement/amvecm/amcsc.c | 1564 +++++++++++++------ drivers/amlogic/media/enhancement/amvecm/amcsc.h | 95 +- .../amlogic/media/enhancement/amvecm/amcsc_pip.c | 929 +++++++++++ .../amlogic/media/enhancement/amvecm/amcsc_pip.h | 34 + drivers/amlogic/media/enhancement/amvecm/amvecm.c | 56 +- .../media/enhancement/amvecm/hdr/am_hdr10_plus.c | 15 +- .../amlogic/media/enhancement/amvecm/set_hdr2_v0.c | 1609 ++++++++++++-------- .../amlogic/media/enhancement/amvecm/set_hdr2_v0.h | 70 +- drivers/amlogic/media/video_sink/video.c | 167 +- .../media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c | 83 +- .../amlogic/media/amdolbyvision/dolby_vision.h | 29 + include/linux/amlogic/media/amvecm/amvecm.h | 30 +- include/linux/amlogic/media/vout/vinfo.h | 4 +- 17 files changed, 4199 insertions(+), 1401 deletions(-) create mode 100644 drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c create mode 100644 drivers/amlogic/media/enhancement/amvecm/amcsc_pip.h diff --git a/MAINTAINERS b/MAINTAINERS index 2e5f1e0..70cffc2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13924,7 +13924,7 @@ F: drivers/amlogic/media/enhancement/amvecm/arch/* F: drivers/amlogic/media/enhancement/amvecm/dnlp_algorithm/* F: include/linux/amlogic/media/amvecm/* F: drivers/amlogic/media/enhancement/amvecm/hdr/* -F: drivers/amlogic/media/enhancement/amvecm/amprime_sl/* +F: drivers/amlogic/media/enhancement/amvecm/amprime_sl/* AMLOGIC GXL ADD SKT DTS M: Yun Cai diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index 91b19ee..72ff32d 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -35,6 +35,7 @@ #include "../amvecm/arch/vpp_regs.h" #include "../amvecm/arch/vpp_hdr_regs.h" #include "../amvecm/arch/vpp_dolbyvision_regs.h" +#include "../amvecm/amcsc.h" #include #include #include @@ -77,12 +78,6 @@ static struct amdolby_vision_dev_s amdolby_vision_dev; struct dv_device_data_s dv_meson_dev; static unsigned int dolby_vision_request_mode = 0xff; -#define DOLBY_VISION_OUTPUT_MODE_IPT 0 -#define DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL 1 -#define DOLBY_VISION_OUTPUT_MODE_HDR10 2 -#define DOLBY_VISION_OUTPUT_MODE_SDR10 3 -#define DOLBY_VISION_OUTPUT_MODE_SDR8 4 -#define DOLBY_VISION_OUTPUT_MODE_BYPASS 5 static unsigned int dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; module_param(dolby_vision_mode, uint, 0664); MODULE_PARM_DESC(dolby_vision_mode, "\n dolby_vision_mode\n"); @@ -98,29 +93,32 @@ MODULE_PARM_DESC(dolby_vision_level, "\n dolby_vision_level\n"); /* STB: if sink support DV, always output DV*/ /* else always output SDR/HDR */ /* TV: when source is DV, convert to SDR */ -#define DOLBY_VISION_FOLLOW_SINK 0 +/* #define DOLBY_VISION_FOLLOW_SINK 0 */ /* STB: output DV only if source is DV*/ /* and sink support DV*/ /* else always output SDR/HDR */ /* TV: when source is DV or HDR, convert to SDR */ -#define DOLBY_VISION_FOLLOW_SOURCE 1 +/* #define DOLBY_VISION_FOLLOW_SOURCE 1 */ /* STB: always follow dolby_vision_mode */ /* TV: if set dolby_vision_mode to SDR8,*/ /* convert all format to SDR by TV core,*/ /* else bypass Dolby Vision */ -#define DOLBY_VISION_FORCE_OUTPUT_MODE 2 +/* #define DOLBY_VISION_FORCE_OUTPUT_MODE 2 */ static unsigned int dolby_vision_policy; module_param(dolby_vision_policy, uint, 0664); MODULE_PARM_DESC(dolby_vision_policy, "\n dolby_vision_policy\n"); +static unsigned int last_dolby_vision_policy; -/* bit0: 0: bypass hdr to vpp, 1: process hdr by dolby core */ -/* bit1: 0: output to sdr, 1: output to hdr if sink support hdr not dovi */ -static unsigned int dolby_vision_hdr10_policy; +/* bit0: follow sink 0: bypass hdr to vpp, 1: process hdr by dolby core */ +/* bit1: follow source 0: bypass hdr to vpp, 1: process hdr by dolby core */ +/* bit2: 0: bypass hlg/hdr10+ to vpp, 1: process hlg/hdr10+ by dolby core */ +static unsigned int dolby_vision_hdr10_policy = 1; module_param(dolby_vision_hdr10_policy, uint, 0664); MODULE_PARM_DESC(dolby_vision_hdr10_policy, "\n dolby_vision_hdr10_policy\n"); +static unsigned int last_dolby_vision_hdr10_policy = 1; static bool dolby_vision_enable; module_param(dolby_vision_enable, bool, 0664); @@ -197,6 +195,10 @@ MODULE_PARM_DESC(dolby_vision_ll_policy, "\n dolby_vision_ll_policy\n"); static u32 last_dolby_vision_ll_policy = DOLBY_VISION_LL_DISABLE; #endif +static unsigned int dolby_vision_src_format; +module_param(dolby_vision_src_format, uint, 0664); +MODULE_PARM_DESC(dolby_vision_src_format, "\n dolby_vision_src_format\n"); + static uint dolby_vision_on_count; static bool dolby_vision_el_disable; @@ -244,7 +246,7 @@ static unsigned int g_vtotal_add = 0x80; static unsigned int g_vsize_add; static unsigned int g_vwidth = 0x18; static unsigned int g_hwidth = 0x10; -static unsigned int g_vpotch = 0x8; +static unsigned int g_vpotch = 0x10; static unsigned int g_hpotch = 0x10; /*dma size:1877x2x64 bit = 30032 byte*/ #define TV_DMA_TBL_SIZE 3754 @@ -264,6 +266,8 @@ static u32 core1_disp_hsize; static u32 core1_disp_vsize; static u32 vsync_count; #define FLAG_VSYNC_CNT 10 +#define MAX_TRANSITION_DELAY 15 +#define MIN_TRANSITION_DELAY 2 static bool is_osd_off; static bool force_reset_core2; @@ -274,6 +278,9 @@ MODULE_PARM_DESC(vtotal_add, "\n vtotal_add\n"); module_param(vpotch, uint, 0664); MODULE_PARM_DESC(vpotch, "\n vpotch\n"); +module_param(g_vpotch, uint, 0664); +MODULE_PARM_DESC(g_vpotch, "\n vpotch\n"); + static unsigned int dolby_vision_target_min = 50; /* 0.0001 */ #ifdef V2_4 static unsigned int dolby_vision_target_max[3][3] = { @@ -296,7 +303,7 @@ static unsigned int dolby_vision_default_max[3][3] = { }; static unsigned int dolby_vision_graphic_min = 50; /* 0.0001 */ -static unsigned int dolby_vision_graphic_max; /* 100 *//* 0.1 */ +static unsigned int dolby_vision_graphic_max; /* 100 */ module_param(dolby_vision_graphic_min, uint, 0664); MODULE_PARM_DESC(dolby_vision_graphic_min, "\n dolby_vision_graphic_min\n"); module_param(dolby_vision_graphic_max, uint, 0664); @@ -316,6 +323,8 @@ static unsigned int dv_target_graphics_LL_max[3][3] = { /*these two parameters form OSD*/ static unsigned int osd_graphic_width = 1920; static unsigned int osd_graphic_height = 1080; +static unsigned int new_osd_graphic_width = 1920; +static unsigned int new_osd_graphic_height = 1080; static unsigned int dv_cert_graphic_width = 1920; static unsigned int dv_cert_graphic_height = 1080; @@ -1013,7 +1022,14 @@ MODULE_PARM_DESC(debug_dolby_frame, "\n debug_dolby_frame\n"); #define dump_enable \ ((debug_dolby_frame >= 0xffff) || \ (debug_dolby_frame + 1 == frame_count)) - +static int is_graphics_output_off(void) +{ + if (is_meson_g12()) + return !(READ_VPP_REG(OSD1_BLEND_SRC_CTRL) & (0xf<<8)) + && !(READ_VPP_REG(OSD2_BLEND_SRC_CTRL) & (0xf<<8)); + else + return (!(READ_VPP_REG(VPP_MISC) & (1<<12))); +} #define single_step_enable \ (((debug_dolby_frame >= 0xffff) || \ ((debug_dolby_frame + 1) == frame_count)) && \ @@ -1249,14 +1265,6 @@ static unsigned int amdolby_vision_poll(struct file *file, poll_table *wait) return mask; } -static int is_graphics_output_off(void) -{ - if (is_meson_g12() || is_meson_tm2_stbmode()) - return !(READ_VPP_DV_REG(OSD1_BLEND_SRC_CTRL) & (1<<8)); - else - return (!(READ_VPP_DV_REG(VPP_MISC) & (1<<12))); -} - static void dump_tv_setting( struct tv_dovi_setting_s *setting, int frame_cnt, int debug_flag) @@ -2543,8 +2551,39 @@ static int dolby_core3_set( void update_graphic_width_height(unsigned int width, unsigned int height) { - osd_graphic_width = width; - osd_graphic_height = height; + new_osd_graphic_width = width; + new_osd_graphic_height = height; +} + +static int is_graphic_changed(void) +{ + int ret = 0; + + if (is_graphics_output_off()) { + if (!is_osd_off) { + pr_dolby_dbg("osd off\n"); + is_osd_off = true; + ret |= 1; + } + } else if (is_osd_off) { + /* force reset core2 when osd off->on */ + force_reset_core2 = true; + pr_dolby_dbg("osd on\n"); + is_osd_off = false; + ret |= 1; + } + 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; + } + return ret; } static void apply_stb_core_settings( @@ -2561,6 +2600,7 @@ static void apply_stb_core_settings( #endif u32 graphics_w = osd_graphic_width; u32 graphics_h = osd_graphic_height; + if (is_dolby_vision_stb_mode() && (dolby_vision_flags & FLAG_CERTIFICAION)) { graphics_w = dv_cert_graphic_width; @@ -2920,6 +2960,7 @@ void enable_dolby_vision(int enable) if (enable) { if (!dolby_vision_on) { + dolby_vision_wait_on = true; dolby_ctrl_backup = VSYNC_RD_DV_REG(VPP_DOLBY_CTRL); viu_misc_ctrl_backup = @@ -3128,23 +3169,27 @@ void enable_dolby_vision(int enable) #endif pr_dolby_dbg("Dolby Vision STB cores turn on\n"); } else if (is_meson_g12() || is_meson_tm2_stbmode()) { + hdr_osd_off(); + hdr_vd1_off(); + set_hdr_module_status(VD1_PATH, + HDR_MODULE_BYPASS); if (dolby_vision_mask & 4) VSYNC_WR_DV_REG_BITS(VPP_DOLBY_CTRL, 1, 3, 1); /* core3 enable */ else VSYNC_WR_DV_REG_BITS(VPP_DOLBY_CTRL, 0, 3, 1); /* bypass core3 */ - - if (is_meson_g12()) { - /*g12a/g12b/sm1: osd1 green line*/ - enable_osd1_mtx(0); - } else if (is_meson_tm2_stbmode()) { + if (is_meson_tm2_stbmode()) { + /* TODO: backup reg */ VSYNC_WR_DV_REG( - VPP_WRAP_OSD1_MATRIX_EN_CTRL, 0x0); + VPP_WRAP_OSD1_MATRIX_EN_CTRL, + 0x0); VSYNC_WR_DV_REG( - VPP_WRAP_OSD2_MATRIX_EN_CTRL, 0x0); + VPP_WRAP_OSD2_MATRIX_EN_CTRL, + 0x0); VSYNC_WR_DV_REG( - VPP_WRAP_OSD3_MATRIX_EN_CTRL, 0x0); + VPP_WRAP_OSD3_MATRIX_EN_CTRL, + 0x0); } if (dolby_vision_mask & 2) VSYNC_WR_DV_REG_BITS( @@ -3438,16 +3483,17 @@ void enable_dolby_vision(int enable) memset(&dovi_setting, 0, sizeof(dovi_setting)); pr_dolby_dbg("Dolby Vision STB cores turn off\n"); } else if (is_meson_g12() || is_meson_tm2_stbmode()) { - if (is_meson_g12()) { - /*g12a/g12b/sm1:osd1 green line*/ - enable_osd1_mtx(1); - } else if (is_meson_tm2_stbmode()) { + if (is_meson_tm2_stbmode()) { + /* TODO: restore reg */ VSYNC_WR_DV_REG( - VPP_WRAP_OSD1_MATRIX_EN_CTRL, 0x1); + VPP_WRAP_OSD1_MATRIX_EN_CTRL, + 0x1); VSYNC_WR_DV_REG( - VPP_WRAP_OSD2_MATRIX_EN_CTRL, 0x1); + VPP_WRAP_OSD2_MATRIX_EN_CTRL, + 0x1); VSYNC_WR_DV_REG( - VPP_WRAP_OSD3_MATRIX_EN_CTRL, 0x1); + VPP_WRAP_OSD3_MATRIX_EN_CTRL, + 0x1); } VSYNC_WR_DV_REG_BITS( DOLBY_PATH_CTRL, @@ -3561,12 +3607,16 @@ void enable_dolby_vision(int enable) core1_disp_hsize = 0; core1_disp_vsize = 0; dolby_vision_on = false; + force_reset_core2 = true; dolby_vision_core1_on = false; dolby_vision_wait_on = false; dolby_vision_wait_init = false; dolby_vision_wait_count = 0; dolby_vision_status = BYPASS_PROCESS; dolby_vision_on_count = 0; + cur_csc_type[VD1_PATH] = VPP_MATRIX_NULL; + hdr_osd_off(); + hdr_vd1_off(); } } EXPORT_SYMBOL(enable_dolby_vision); @@ -3929,12 +3979,12 @@ static int sink_support_dolby_vision(const struct vinfo_s *vinfo) return 0; if (dolby_vision_flags & FLAG_DISABLE_DOVI_OUT) return 0; - if ((vinfo->width >= 1920) && - (vinfo->height >= 1080) && - (vinfo->field_height >= 1080)) - return 1; - else - return 0; + if ((strstr(vinfo->name, "2160p60hz") != NULL) || + (strstr(vinfo->name, "2160p50hz") != NULL)) { + if (!vinfo->vout_device->dv_info->sup_2160p60hz) + return 0; + } + return 1; } static int sink_support_hdr(const struct vinfo_s *vinfo) @@ -3947,6 +3997,145 @@ static int sink_support_hdr(const struct vinfo_s *vinfo) 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; +} + +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 (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) +{ + int ret = 0; + + if (last_dolby_vision_policy != dolby_vision_policy) { + /* handle policy change */ + pr_dolby_dbg("policy changed %d->%d\n", + last_dolby_vision_policy, + dolby_vision_policy); + 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; + } +#endif + if (last_dolby_vision_hdr10_policy != dolby_vision_hdr10_policy) { + /* handle policy change */ + pr_dolby_dbg("hdr10 policy changed %d->%d\n", + last_dolby_vision_hdr10_policy, + dolby_vision_hdr10_policy); + last_dolby_vision_hdr10_policy = dolby_vision_hdr10_policy; + ret |= 4; + } + return ret; +} + +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] = { + "NONE", + "HDR", + "HDR+", + "DOVI", + "PRIME", + "HLG", + "SDR" +}; + +static void update_src_format( + enum signal_format_e src_format, struct vframe_s *vf) +{ + enum signal_format_e cur_format = dolby_vision_src_format; + + if (src_format == FORMAT_DOVI) { + dolby_vision_src_format = 3; + } else { + if (vf) { + if (vf_is_hdr10_plus(vf)) + dolby_vision_src_format = 2; + else if (vf_is_hdr10(vf)) + dolby_vision_src_format = 1; + else if (vf_is_hlg(vf)) + 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; + } + } + } +} + +int get_dolby_vision_src_format(void) +{ + return dolby_vision_src_format; +} +EXPORT_SYMBOL(get_dolby_vision_src_format); + static int dolby_vision_policy_process( int *mode, enum signal_format_e src_format) { @@ -4049,68 +4238,94 @@ static int dolby_vision_policy_process( mode_change = 0; return mode_change; } - if (vinfo && sink_support_dolby_vision(vinfo)) { + + if (((src_format == FORMAT_HLG) || + (src_format == FORMAT_HDR10PLUS)) + && !(dolby_vision_hdr10_policy & 4)) { + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_BYPASS) { + if (debug_dolby & 2) + pr_dolby_dbg( + "hlg/hdr+, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; + 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)) { + /*if vpp is playing hlg/hdr10+*/ + /*dolby need bypass at this time*/ + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_BYPASS) { + if (debug_dolby & 2) + pr_dolby_dbg( + "src=%d, hdr module on, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n", + src_format); + *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; + mode_change = 1; + } + return mode_change; + } else if (vinfo && sink_support_dolby_vision(vinfo)) { /* TV support DOVI, All -> DOVI */ if (dolby_vision_mode != DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) { - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL\n"); + pr_dolby_dbg("src=%d, dovi output -> DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL\n", + src_format); *mode = DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL; mode_change = 1; } - } else if (vinfo && sink_support_hdr(vinfo) - && (dolby_vision_hdr10_policy & 2)) { + } else if (vinfo && sink_support_hdr(vinfo)) { /* TV support HDR, All -> HDR */ if (dolby_vision_mode != DOLBY_VISION_OUTPUT_MODE_HDR10) { - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_HDR10\n"); + pr_dolby_dbg("src=%d, dovi output -> DOLBY_VISION_OUTPUT_MODE_HDR10\n", + src_format); *mode = DOLBY_VISION_OUTPUT_MODE_HDR10; mode_change = 1; } } else { - /* TV not support DOVI */ + /* TV not support DOVI and HDR */ if ((src_format == FORMAT_DOVI) || (src_format == FORMAT_DOVI_LL)) { /* DOVI to SDR */ if (dolby_vision_mode != DOLBY_VISION_OUTPUT_MODE_SDR8) { - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); - *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; - mode_change = 1; - } - } else if (src_format == FORMAT_HDR10 - && (dolby_vision_hdr10_policy & 1)) { - if (dolby_vision_mode != - DOLBY_VISION_OUTPUT_MODE_SDR8) { - /* HDR10 to SDR */ - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); + pr_dolby_dbg("dovi, dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; mode_change = 1; } - } else if (src_format == FORMAT_HDR10 - && (!(dolby_vision_hdr10_policy & 1))) { - if (dolby_vision_mode != - DOLBY_VISION_OUTPUT_MODE_BYPASS) { + } else if (src_format == FORMAT_HDR10) { + if (dolby_vision_hdr10_policy & 0x01) { + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_SDR8) { + /* HDR10 to SDR */ + pr_dolby_dbg("hdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); + *mode = + DOLBY_VISION_OUTPUT_MODE_SDR8; + mode_change = 1; + } + } else if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_BYPASS) { /* HDR bypass */ - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); + pr_dolby_dbg("hdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; mode_change = 1; } } else if ((is_meson_g12b_cpu() && is_meson_rev_a()) || is_meson_g12a_cpu()) { - /*g12 verA has a hardware bug.Therefore,dv cores - *must keep working even if under sdr mode - */ + /* dv cores keep on if in sdr mode */ if (dolby_vision_mode != - DOLBY_VISION_OUTPUT_MODE_SDR8) { + DOLBY_VISION_OUTPUT_MODE_SDR8) { /* SDR to SDR */ - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); + pr_dolby_dbg("sdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; mode_change = 1; } } else if (dolby_vision_mode != - DOLBY_VISION_OUTPUT_MODE_BYPASS) { - /* SDR bypass */ - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); + DOLBY_VISION_OUTPUT_MODE_BYPASS) { + /* HDR/SDR bypass */ + pr_dolby_dbg("sdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; mode_change = 1; } @@ -4126,47 +4341,77 @@ static int dolby_vision_policy_process( mode_change = 0; return mode_change; } - if ((src_format == FORMAT_DOVI) || + 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)) { + /* bypass dolby incase VPP is not in sdr mode */ + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_BYPASS) { + pr_dolby_dbg("hdr module on, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; + mode_change = 1; + } + return mode_change; + } else if ((src_format == FORMAT_DOVI) || (src_format == FORMAT_DOVI_LL)) { /* DOVI source */ if (vinfo && sink_support_dolby_vision(vinfo)) { /* TV support DOVI, DOVI -> DOVI */ if (dolby_vision_mode != DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) { - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL\n"); + pr_dolby_dbg("dovi, dovi output -> DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL\n"); *mode = DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL; mode_change = 1; } + } else if (vinfo && sink_support_hdr(vinfo)) { + /* TV support HDR, DOVI -> HDR */ + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_HDR10) { + pr_dolby_dbg("dovi, dovi output -> DOLBY_VISION_OUTPUT_MODE_HDR10\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_HDR10; + mode_change = 1; + } } else { - /* TV not support DOVI, DOVI -> SDR */ + /* TV not support DOVI and HDR, DOVI -> SDR */ if (dolby_vision_mode != DOLBY_VISION_OUTPUT_MODE_SDR8) { - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); + pr_dolby_dbg("dovi, dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; mode_change = 1; } } - } else if (src_format == FORMAT_HDR10 - && (dolby_vision_hdr10_policy & 1)) { - if (dolby_vision_mode != - DOLBY_VISION_OUTPUT_MODE_SDR8) { - /* HDR10 to SDR */ - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); - *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; - mode_change = 1; + } else if ((src_format == FORMAT_HDR10) + && (dolby_vision_hdr10_policy & 0x02)) { + if (vinfo && sink_support_hdr(vinfo)) { + /* TV support HDR, HDR -> HDR */ + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_HDR10) { + pr_dolby_dbg("hdr10, dovi output -> DOLBY_VISION_OUTPUT_MODE_HDR10\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_HDR10; + mode_change = 1; + } + } else { + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_SDR8) { + /* HDR10 to SDR */ + pr_dolby_dbg("hdr10, dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; + mode_change = 1; + } } } else if (dolby_vision_mode != DOLBY_VISION_OUTPUT_MODE_BYPASS) { /* HDR/SDR bypass */ - pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS"); + pr_dolby_dbg("sdr, dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS"); *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; mode_change = 1; } } else if (dolby_vision_policy == DOLBY_VISION_FORCE_OUTPUT_MODE) { if (dolby_vision_mode != *mode) { - pr_dolby_dbg("dovi output mode change %d -> %d\n", - dolby_vision_mode, *mode); + pr_dolby_dbg("src=%d, dovi output mode change %d -> %d\n", + src_format, dolby_vision_mode, *mode); mode_change = 1; } } @@ -4247,7 +4492,59 @@ EXPORT_SYMBOL(is_dovi_dual_layer_frame); #define signal_color_primaries ((vf->signal_type >> 16) & 0xff) #define signal_transfer_characteristic ((vf->signal_type >> 8) & 0xff) -static bool is_hdr10_frame(struct vframe_s *vf) + +static bool vf_is_hlg(struct vframe_s *vf) +{ + if (((signal_transfer_characteristic == 14) || + (signal_transfer_characteristic == 18)) && + (signal_color_primaries == 9)) + return true; + return false; +} + +static bool is_hlg_frame(struct vframe_s *vf) +{ + if (!vf) + return false; + if (!(dolby_vision_hdr10_policy & 4)) { + if (((signal_transfer_characteristic == 14) || + (signal_transfer_characteristic == 18)) && + (signal_color_primaries == 9)) + return true; + } + + return false; +} + +static bool vf_is_hdr10_plus(struct vframe_s *vf) +{ + if ((signal_transfer_characteristic == 0x30) + && ((signal_color_primaries == 9) + || (signal_color_primaries == 2))) + return true; + return false; +} + +static bool is_hdr10plus_frame(struct vframe_s *vf) +{ + const struct vinfo_s *vinfo = get_current_vinfo(); + + if (!vf) + return false; + if (!(dolby_vision_hdr10_policy & 4)) { + /* report hdr10 for the content hdr10+ and + * sink is hdr10+ case + */ + if ((signal_transfer_characteristic == 0x30) + && (sink_support_hdr10_plus(vinfo)) + && ((signal_color_primaries == 9) + || (signal_color_primaries == 2))) + return true; + } + return false; +} + +static bool vf_is_hdr10(struct vframe_s *vf) { if ((signal_transfer_characteristic == 16) && ((signal_color_primaries == 9) @@ -4256,6 +4553,64 @@ static bool is_hdr10_frame(struct vframe_s *vf) return false; } +static bool is_hdr10_frame(struct vframe_s *vf) +{ + const struct vinfo_s *vinfo = get_current_vinfo(); + + if (!vf) + return false; + if (((signal_transfer_characteristic == 16) || + /* report hdr10 for the content hdr10+ and + * sink is not hdr10+ case + */ + ((signal_transfer_characteristic == 0x30) && + (!sink_support_hdr10_plus(vinfo)))) + && ((signal_color_primaries == 9) + || (signal_color_primaries == 2))) + return true; + return false; +} + +int dolby_vision_check_hlg(struct vframe_s *vf) +{ + int mode; + + if (is_hlg_frame(vf) && !dolby_vision_on) { + /* dovi source, but dovi not enabled */ + mode = dolby_vision_mode; + if (dolby_vision_policy_process( + &mode, FORMAT_HLG)) { + 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_hlg); + +int dolby_vision_check_hdr10plus(struct vframe_s *vf) +{ + int mode; + + if (is_hdr10plus_frame(vf) && !dolby_vision_on) { + /* dovi source, but dovi not enabled */ + mode = dolby_vision_mode; + if (dolby_vision_policy_process( + &mode, FORMAT_HDR10PLUS)) { + 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_hdr10plus); + int dolby_vision_check_hdr10(struct vframe_s *vf) { int mode; @@ -4567,28 +4922,6 @@ static u32 bt2020_white_point[2] = { 0.3127 * INORM + 0.5, 0.3290 * INORM + 0.5 }; -static int check_primaries(struct vframe_master_display_colour_s *p_mdc) -{ - if (!p_mdc->present_flag) - return 0; - if ((p_mdc->primaries[0][1] > p_mdc->primaries[1][1]) - && (p_mdc->primaries[0][1] > p_mdc->primaries[2][1]) - && (p_mdc->primaries[2][0] > p_mdc->primaries[0][0]) - && (p_mdc->primaries[2][0] > p_mdc->primaries[1][0])) { - /* reasonable g,b,r */ - return 2; - } else if ((p_mdc->primaries[0][0] > p_mdc->primaries[1][0]) - && (p_mdc->primaries[0][0] > p_mdc->primaries[2][0]) - && (p_mdc->primaries[1][1] > p_mdc->primaries[0][1]) - && (p_mdc->primaries[1][1] > p_mdc->primaries[2][1])) { - /* reasonable r,g,b */ - return 1; - } - /* source not usable, use standard bt2020 */ - return 0; -} - - void prepare_hdr10_param( struct vframe_master_display_colour_s *p_mdc, struct hdr10_param_s *p_hdr10_param) @@ -4628,8 +4961,11 @@ void prepare_hdr10_param( return; } - primaries_type = check_primaries(p_mdc); + primaries_type = get_primaries_type(p_mdc); if (primaries_type == 2) { + /* GBR -> RGB as dolby will swap back to GBR + * in send_hdmi_pkt + */ if ((p_hdr10_param-> max_display_mastering_luminance != p_mdc->luminance[0]) @@ -4677,6 +5013,9 @@ void prepare_hdr10_param( = p_mdc->white_point[1]; } } else if (primaries_type == 1) { + /* RGB -> RGB and dolby will swap to send as GBR + * in send_hdmi_pkt + */ if ((p_hdr10_param-> max_display_mastering_luminance != p_mdc->luminance[0]) @@ -4724,6 +5063,9 @@ void prepare_hdr10_param( = p_mdc->white_point[1]; } } else { + /* GBR -> RGB as dolby will swap back to GBR + * in send_hdmi_pkt + */ if ((p_hdr10_param-> min_display_mastering_luminance != min_lum) @@ -4876,13 +5218,15 @@ static int prepare_vsif_pkt( static u32 last_dst_format = FORMAT_SDR; static bool send_hdmi_pkt( enum signal_format_e dst_format, - const struct vinfo_s *vinfo) + const struct vinfo_s *vinfo, struct vframe_s *vf) { struct hdr_10_infoframe_s *p_hdr; int i; bool flag = false; + static int sdr_transition_delay; if (dst_format == FORMAT_HDR10) { + sdr_transition_delay = 0; p_hdr = &dovi_setting.hdr_info; hdr10_data.features = (1 << 29) /* video available */ @@ -4993,8 +5337,10 @@ static bool send_hdmi_pkt( #ifdef HDMI_SEND_ALL_PKT if (vinfo && vinfo->vout_device && vinfo->vout_device->fresh_tx_vsif_pkt) - vinfo->vout_device->fresh_tx_vsif_pkt(0, 0, NULL); + 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"); last_dst_format = dst_format; if (flag) { pr_dolby_dbg("Info frame for hdr10 changed:\n"); @@ -5019,6 +5365,7 @@ static bool send_hdmi_pkt( } else if (dst_format == FORMAT_DOVI) { struct dv_vsif_para vsif; + sdr_transition_delay = 0; memset(&vsif, 0, sizeof(vsif)); #ifdef V2_4 if (vinfo) @@ -5056,47 +5403,79 @@ static bool send_hdmi_pkt( EOTF_T_LL_MODE, dovi_setting.diagnostic_enable ? RGB_10_12BIT : YUV422_BIT12, - &vsif); + &vsif, false); else #endif vinfo->vout_device->fresh_tx_vsif_pkt( EOTF_T_DOLBYVISION, dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL - ? RGB_8BIT : YUV422_BIT12, &vsif); + ? 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"); last_dst_format = dst_format; } else if (last_dst_format != dst_format) { if (last_dst_format == FORMAT_HDR10) { - hdr10_data.features = - (1 << 29) /* video available */ - | (5 << 26) /* unspecified */ - | (0 << 25) /* limit */ - | (1 << 24) /* color available */ - | (1 << 16) /* bt709 */ - | (1 << 8) /* bt709 */ - | (1 << 0); /* bt709 */ - for (i = 0; i < 3; i++) { - hdr10_data.primaries[i][0] = 0; - hdr10_data.primaries[i][1] = 0; + sdr_transition_delay = 0; + if (!(vf && (is_hlg_frame(vf) || + is_hdr10plus_frame(vf)))) { + hdr10_data.features = + (1 << 29) /* video available */ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /* color available */ + | (1 << 16) /* bt709 */ + | (1 << 8) /* bt709 */ + | (1 << 0); /* bt709 */ + for (i = 0; i < 3; i++) { + hdr10_data.primaries[i][0] = 0; + hdr10_data.primaries[i][1] = 0; + } + hdr10_data.white_point[0] = 0; + hdr10_data.white_point[1] = 0; + hdr10_data.luminance[0] = 0; + hdr10_data.luminance[1] = 0; + hdr10_data.max_content = 0; + hdr10_data.max_frame_average = 0; + if (vinfo && vinfo->vout_device && + vinfo->vout_device->fresh_tx_hdr_pkt) + vinfo->vout_device->fresh_tx_hdr_pkt( + &hdr10_data); } - hdr10_data.white_point[0] = 0; - hdr10_data.white_point[1] = 0; - hdr10_data.luminance[0] = 0; - hdr10_data.luminance[1] = 0; - hdr10_data.max_content = 0; - hdr10_data.max_frame_average = 0; - if (vinfo && vinfo->vout_device && - vinfo->vout_device->fresh_tx_hdr_pkt) - vinfo->vout_device->fresh_tx_hdr_pkt( - &hdr10_data); + last_dst_format = dst_format; } else if (last_dst_format == FORMAT_DOVI) { if (vinfo && vinfo->vout_device && - vinfo->vout_device->fresh_tx_vsif_pkt) - vinfo->vout_device->fresh_tx_vsif_pkt( - 0, 0, NULL); + vinfo->vout_device->fresh_tx_vsif_pkt) { + if (vf && (is_hlg_frame(vf) || + is_hdr10plus_frame(vf))) { + /* HLG/HDR10+ case: first switch to SDR + * immediately. + */ + pr_info("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"); + 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"); + vinfo->vout_device->fresh_tx_vsif_pkt( + 0, 0, NULL, false); + } + sdr_transition_delay++; + } + } } - last_dst_format = dst_format; } return flag; } @@ -5115,10 +5494,12 @@ static int is_video_output_off(struct vframe_s *vf) null_vf_cnt++; else null_vf_cnt = 0; - if (null_vf_cnt > dolby_vision_wait_delay + 3) { + if (null_vf_cnt > dolby_vision_wait_delay + 1) { null_vf_cnt = 0; return 1; } + if (video_off_handled) + return 1; } else video_off_handled = 0; return 0; @@ -5209,6 +5590,8 @@ int dolby_vision_parse_metadata( u32 graphic_min = 50; /* 0.0001 */ u32 graphic_max = 100; /* 1 */ int ret_flags = 0; + static int bypass_frame = -1; + static int last_current_format; int ret = -1; bool mel_flag = false; @@ -5378,6 +5761,17 @@ int dolby_vision_parse_metadata( src_bdp = 10; req.dv_enhance_exist = 0; } + + if ((src_format != FORMAT_DOVI) + && is_hlg_frame(vf)) { + src_format = FORMAT_HLG; + } + + if ((src_format != FORMAT_DOVI) + && is_hdr10plus_frame(vf)) { + src_format = FORMAT_HDR10PLUS; + } + #ifdef V2_4 /* TODO: need 962e ? */ if ((src_format == FORMAT_SDR) @@ -5389,11 +5783,13 @@ int dolby_vision_parse_metadata( || (frame_count == 0)) && (toggle_mode == 1)) pr_info( - "DOLBY: frame %d pts %lld, src bdp: %d format: %s, aux_size:%d, enhance: %d\n", + "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" : - (req.dv_enhance_exist ? "DOVI (el meta)" : "SDR")), + (src_format == FORMAT_HLG ? "HLG" : + (src_format == FORMAT_HDR10PLUS ? "HDR10+" : + (req.dv_enhance_exist ? "DOVI (el meta)" : "SDR")))), req.aux_size, req.dv_enhance_exist); if ((src_format != FORMAT_DOVI) && !req.dv_enhance_exist) @@ -5491,8 +5887,9 @@ int dolby_vision_parse_metadata( else el_flag = tv_dovi_setting->el_flag; mel_flag = mel_mode; - pr_dolby_dbg("update el_flag %d, melFlag %d\n", - el_flag, mel_flag); + if (debug_dolby & 2) + pr_dolby_dbg("update el_flag %d, melFlag %d\n", + el_flag, mel_flag); meta_flag_bl = 0; } @@ -5549,12 +5946,41 @@ int dolby_vision_parse_metadata( dolby_vision_mode = current_mode; if (is_dolby_vision_stb_mode()) new_dovi_setting.mode_changed = 1; + pr_dolby_dbg("[dolby_vision_parse_metadata] output change from %d to %d(%d, %p, %d)\n", + dolby_vision_mode, current_mode, + toggle_mode, vf, src_format); + } + if (vf) { + update_src_format(check_format, vf); + last_current_format = check_format; + } + + if ((get_hdr_module_status(VD1_PATH) != HDR_MODULE_ON) + && (check_format == FORMAT_SDR)) { + /* insert 2 SDR frames before send DOVI */ + if (((dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) + || (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_IPT)) + && ((last_current_format == FORMAT_HLG) + || (last_current_format == FORMAT_HDR10PLUS))) { + bypass_frame = 0; + pr_dolby_dbg("[dolby_vision_parse_metadata] source transition from %d to %d\n", + last_current_format, check_format); + } + last_current_format = check_format; } + if ((bypass_frame >= 0) && (bypass_frame < MIN_TRANSITION_DELAY)) { + dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; + bypass_frame++; + } else + bypass_frame = -1; + if (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) { new_dovi_setting.video_width = 0; new_dovi_setting.video_height = 0; new_dovi_setting.mode_changed = 0; + if (get_hdr_module_status(VD1_PATH) == HDR_MODULE_BYPASS) + return 1; return -1; } @@ -5719,29 +6145,18 @@ int dolby_vision_parse_metadata( if (dolby_vision_graphic_max != 0) graphic_max = dolby_vision_graphic_max; else { - graphic_max = - dv_target_graphics_max[src_format][dst_format]; - if ((dolby_vision_flags & FLAG_FORCE_DOVI_LL) || - (dolby_vision_ll_policy >= DOLBY_VISION_LL_YUV422)) { + (dolby_vision_ll_policy >= DOLBY_VISION_LL_YUV422)) { graphic_max = - dv_target_graphics_LL_max[src_format][dst_format]; + dv_target_graphics_LL_max + [src_format][dst_format]; + } else { + graphic_max = + dv_target_graphics_max + [src_format][dst_format]; } } - if (is_graphics_output_off()) { - graphic_min = 0; - graphic_max = 0; - is_osd_off = true; - } else { - /* force reset core2 when osd off->on */ - /* TODO: 962e need ? */ - if (is_osd_off) - force_reset_core2 = true; - if (new_dovi_setting.mode_changed) - force_reset_core2 = true; - is_osd_off = false; - } if (dolby_vision_flags & FLAG_USE_SINK_MIN_MAX) { if (vinfo->vout_device->dv_info->ieeeoui == 0x00d046) { if (vinfo->vout_device->dv_info->ver == 0) { @@ -5795,6 +6210,9 @@ int dolby_vision_parse_metadata( } } + if (is_osd_off) + graphic_min = graphic_max = 0; + #ifdef V2_4 if ((src_format != dovi_setting.src_format) || (dst_format != dovi_setting.dst_format) || @@ -5897,6 +6315,14 @@ int dolby_vision_parse_metadata( new_dovi_setting.vsvdb_len = 0; } } + +#if 0 /* 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 & FLAG_PRIORITY_GRAPHIC)) @@ -6003,8 +6429,15 @@ int dolby_vision_parse_metadata( new_dovi_setting.video_height = h; dovi_setting_video_flag = video_frame; if (debug_dolby & 1) { + if (is_video_output_off(vf)) + pr_dolby_dbg("setting %d->%d(T:%d-%d), osd:%dx%d\n", + src_format, dst_format, + dolby_vision_target_min, + dolby_vision_target_max[src_format][dst_format], + 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", + 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], @@ -6012,7 +6445,7 @@ int dolby_vision_parse_metadata( 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", + 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], @@ -6027,7 +6460,8 @@ int dolby_vision_parse_metadata( if (flag < 0) { new_dovi_setting.video_width = 0; new_dovi_setting.video_height = 0; - pr_dolby_error("control_path() failed\n"); + pr_dolby_error("control_path(%d, %d) failed\n", + src_format, dst_format); } return -1; /* do nothing for this frame */ } @@ -6043,6 +6477,7 @@ int dolby_vision_wait_metadata(struct vframe_s *vf) struct vframe_s *el_vf; int ret = 0; unsigned int mode = dolby_vision_mode; + enum signal_format_e check_format; if (single_step_enable) { if (dolby_vision_flags & FLAG_SINGLE_STEP) @@ -6121,32 +6556,18 @@ int dolby_vision_wait_metadata(struct vframe_s *vf) if (!dolby_vision_wait_init && !dolby_vision_core1_on) { - if (is_dovi_frame(vf)) { - if (dolby_vision_policy_process( - &mode, FORMAT_DOVI)) { - if ((mode != DOLBY_VISION_OUTPUT_MODE_BYPASS) - && (dolby_vision_mode == - DOLBY_VISION_OUTPUT_MODE_BYPASS)) { - dolby_vision_wait_init = true; - dolby_vision_wait_count = - dolby_vision_wait_delay; - dolby_vision_wait_on = true; - } - } - } else if (is_hdr10_frame(vf)) { - if (dolby_vision_policy_process( - &mode, FORMAT_HDR10)) { - if ((mode != DOLBY_VISION_OUTPUT_MODE_BYPASS) - && (dolby_vision_mode == - DOLBY_VISION_OUTPUT_MODE_BYPASS)) { - dolby_vision_wait_init = true; - dolby_vision_wait_count = - dolby_vision_wait_delay; - dolby_vision_wait_on = true; - } - } - } else if (dolby_vision_policy_process( - &mode, FORMAT_SDR)) { + if (is_dovi_frame(vf)) + check_format = FORMAT_DOVI; + else if (is_hdr10_frame(vf)) + check_format = FORMAT_HDR10; + else if (is_hlg_frame(vf)) + check_format = FORMAT_HLG; + else if (is_hdr10plus_frame(vf)) + check_format = FORMAT_HDR10PLUS; + else + check_format = FORMAT_SDR; + if (dolby_vision_policy_process( + &mode, check_format)) { if ((mode != DOLBY_VISION_OUTPUT_MODE_BYPASS) && (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_BYPASS)) { @@ -6154,8 +6575,13 @@ int dolby_vision_wait_metadata(struct vframe_s *vf) dolby_vision_wait_count = dolby_vision_wait_delay; dolby_vision_wait_on = true; + pr_dolby_dbg("dolby_vision_need_wait src=%d mode=%d\n", + check_format, mode); } } + if (vf) + update_src_format(check_format, vf); + /* don't use run mode when sdr -> dv and vd1 not disable */ if (dolby_vision_wait_init && (READ_VPP_DV_REG(VPP_MISC) & (1<<10))) @@ -6240,7 +6666,6 @@ static void bypass_pps_path(u8 pps_state) } } -static unsigned int last_dolby_vision_policy; int dolby_vision_process(struct vframe_s *vf, u32 display_size, u8 pps_state) /* 0: no change, 1: pps enable, 2: pps disable */ { @@ -6250,6 +6675,8 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size, const struct vinfo_s *vinfo = get_current_vinfo(); bool reset_flag = false; bool force_set = false; + static int sdr_delay; + unsigned int mode; if (!is_meson_box() && !is_meson_txlx() && !is_meson_tm2()) return -1; @@ -6313,30 +6740,34 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size, && !video_off_handled) { dolby_vision_set_toggle_flag(1); frame_count = 0; + video_off_handled = 1; if (debug_dolby & 2) { - video_off_handled = 1; pr_dolby_dbg("video off\n"); } } - if (last_dolby_vision_policy != dolby_vision_policy) { - /* handle policy change */ + if (is_sink_cap_changed(vinfo)) { + if (vf) + dolby_vision_parse_metadata(vf, 1, false); dolby_vision_set_toggle_flag(1); - last_dolby_vision_policy = dolby_vision_policy; } -#ifdef V2_4 - if (is_meson_txlx_stbmode() || is_meson_box() - || is_meson_tm2_stbmode() || force_stb_mode) { - if (last_dolby_vision_ll_policy - != dolby_vision_ll_policy) { - /* handle ll mode policy change */ - dolby_vision_set_toggle_flag(1); - } - } -#endif + /* only monitor dolby_vision_policy */ + /* other policy will be updated for video */ + if (is_policy_changed() & 1) + dolby_vision_set_toggle_flag(1); + if (is_graphic_changed()) + dolby_vision_set_toggle_flag(1); - if (!vf) { + 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)) { + 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( NULL, 1, false); @@ -6354,15 +6785,43 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size, } } if (dolby_vision_status != BYPASS_PROCESS) { - enable_dolby_vision(0); - if (vinfo && - !is_meson_tvmode() && - !force_stb_mode) - send_hdmi_pkt(FORMAT_SDR, vinfo); + if (vinfo && !is_meson_tvmode() && + !force_stb_mode) { + if (vf && is_hdr10plus_frame(vf)) { + /* disable dolby immediately */ + pr_info("Dolby bypass: HDR10+: Switched to SDR first\n"); + send_hdmi_pkt(FORMAT_SDR, vinfo, vf); + enable_dolby_vision(0); + } else if (vf && is_hlg_frame(vf)) { + /* disable dolby immediately */ + pr_info("Dolby bypass: HLG: Switched to SDR first\n"); + send_hdmi_pkt(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); + send_hdmi_pkt(FORMAT_SDR, vinfo, vf); + enable_dolby_vision(0); + } else { + send_hdmi_pkt(FORMAT_SDR, vinfo, vf); + if (sdr_delay >= MAX_TRANSITION_DELAY) { + pr_info("Dolby bypass: Done - Switched to SDR\n"); + enable_dolby_vision(0); + sdr_delay = 0; + } + sdr_delay++; + } + } else + enable_dolby_vision(0); + if (dolby_vision_flags & FLAG_TOGGLE_FRAME) dolby_vision_flags &= ~FLAG_TOGGLE_FRAME; } return 0; + } else if (sdr_delay != 0) { + /* in case mode change to a mode requiring dolby block */ + sdr_delay = 0; } if ((dolby_vision_flags & FLAG_CERTIFICAION) @@ -6456,7 +6915,8 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size, /* send HDMI packet according to dst_format */ if (vinfo && !force_stb_mode) send_hdmi_pkt( - dovi_setting.dst_format, vinfo); + dovi_setting.dst_format, + vinfo, vf); update_dolby_vision_status( dovi_setting.src_format); } @@ -6561,6 +7021,13 @@ bool is_dolby_vision_on(void) } EXPORT_SYMBOL(is_dolby_vision_on); +bool is_dolby_vision_video_on(void) +{ + return dolby_vision_core1_on; +} +EXPORT_SYMBOL(is_dolby_vision_video_on); + + bool for_dolby_vision_certification(void) { return is_dolby_vision_on() && @@ -6624,6 +7091,12 @@ bool is_dolby_vision_el_disable(void) } EXPORT_SYMBOL(is_dolby_vision_el_disable); +int get_dolby_vision_policy(void) +{ + return dolby_vision_policy; +} +EXPORT_SYMBOL(get_dolby_vision_policy); + int register_dv_functions(const struct dolby_vision_func_s *func) { int ret = -1; diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h index b3da1b5..75b944404 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.h @@ -205,7 +205,9 @@ enum signal_format_e { FORMAT_HDR10 = 1, FORMAT_SDR = 2, FORMAT_DOVI_LL = 3, - FORMAT_SDR_2020 = 4 + FORMAT_HLG = 4, + FORMAT_HDR10PLUS = 5, + FORMAT_SDR_2020 = 6 }; enum priority_mode_e { @@ -532,6 +534,7 @@ struct dovi_setting_s { uint32_t vout_width; uint32_t vout_height; u8 vsvdb_tbl[32]; + u8 hdrdb_tbl[7]; struct ext_md_s ext_md; uint32_t vsvdb_len; uint32_t vsvdb_changed; diff --git a/drivers/amlogic/media/enhancement/amvecm/Makefile b/drivers/amlogic/media/enhancement/amvecm/Makefile index 4e258fb..07733fb 100644 --- a/drivers/amlogic/media/enhancement/amvecm/Makefile +++ b/drivers/amlogic/media/enhancement/amvecm/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) += am_vecm.o am_vecm-objs := amve.o am_vecm-objs += amcm.o am_vecm-objs += amcsc.o +am_vecm-objs += amcsc_pip.o am_vecm-objs += amvecm.o am_vecm-objs += keystone_correction.o am_vecm-objs += bitdepth.o diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.c b/drivers/amlogic/media/enhancement/amvecm/amcsc.c index 3efccde..e9c930b 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.c +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.c @@ -37,22 +37,41 @@ #include "../../osd/osd_rdma.h" #include "amcsc.h" +#include "amcsc_pip.h" #include "set_hdr2_v0.h" #include #include "hdr/am_hdr10_plus.h" #include "hdr/am_hdr10_plus_ootf.h" -#define pr_csc(fmt, args...)\ - do {\ - if (debug_csc)\ - pr_info(fmt, ## args);\ - } while (0) + +uint debug_csc; +module_param(debug_csc, uint, 0664); +MODULE_PARM_DESC(debug_csc, "\n debug_csc\n"); signed int vd1_contrast_offset; signed int saturation_offset; /*hdr------------------------------------*/ + +void hdr_osd_off(void) +{ + enum hdr_process_sel cur_hdr_process; + + cur_hdr_process = hdr_func(OSD1_HDR, HDR_BYPASS, get_current_vinfo()); + pr_csc(8, "am_vecm: module=OSD1_HDR, process=HDR_BYPASS(%d, %d)\n", + HDR_BYPASS, cur_hdr_process); +} + +void hdr_vd1_off(void) +{ + enum hdr_process_sel cur_hdr_process; + + cur_hdr_process = hdr_func(VD1_HDR, HDR_BYPASS, get_current_vinfo()); + pr_csc(8, "am_vecm: module=VD1_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) @@ -108,7 +127,7 @@ static ssize_t write_file_hdr_cfgosd( hdr_set_cfg_osd_100(val); - pr_info("hdr:en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100); + pr_info("en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100); return count; } @@ -272,10 +291,6 @@ static struct vframe_s *dbg_vf; static struct master_display_info_s dbg_hdr_send; static struct hdr_info receiver_hdr_info; -static uint debug_csc; -module_param(debug_csc, uint, 0664); -MODULE_PARM_DESC(debug_csc, "\n debug_csc\n"); - static bool print_lut_mtx; module_param(print_lut_mtx, bool, 0664); MODULE_PARM_DESC(print_lut_mtx, "\n print_lut_mtx\n"); @@ -307,9 +322,15 @@ static int wb_val[10] = { module_param_array(wb_val, int, &num_wb_val, 0664); MODULE_PARM_DESC(wb_val, "\n white balance setting\n"); -static enum vframe_source_type_e pre_src_type = VFRAME_SOURCE_TYPE_COMP; -uint cur_csc_type = 0xffff; -module_param(cur_csc_type, uint, 0444); +static enum vframe_source_type_e pre_src_type[VD_PATH_MAX] = { + VFRAME_SOURCE_TYPE_COMP, + VFRAME_SOURCE_TYPE_COMP +}; + +static unsigned int vd_path_max = VD_PATH_MAX; + +uint cur_csc_type[VD_PATH_MAX] = {0xffff, 0xffff}; +module_param_array(cur_csc_type, uint, &vd_path_max, 0444); MODULE_PARM_DESC(cur_csc_type, "\n current color space convert type\n"); static uint hdmi_csc_type = 0xffff; @@ -320,36 +341,46 @@ 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 hdr_process_mode = 1; /* 0: hdr->hdr, 1:hdr->sdr */ -static uint cur_hdr_process_mode = 2; /* 0: hdr->hdr, 1:hdr->sdr */ -module_param(hdr_process_mode, uint, 0444); +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}; +module_param_array(hdr_process_mode, uint, &vd_path_max, 0444); MODULE_PARM_DESC(hdr_process_mode, "\n current hdr_process_mode\n"); -static uint hdr10_plus_process_mode; /* 0: bypass, 1:hdr10p->sdr */ -static uint cur_hdr10_plus_process_mode = 2; /* 0: bypass, 1:hdr10p->sdr */ +/* 0:bypass, 1:hdr10p->hdr, 2:hdr10p->sdr, 3:hdr10p->hlg */ +uint hdr10_plus_process_mode[VD_PATH_MAX]; +uint cur_hdr10_plus_process_mode[VD_PATH_MAX] = {PROC_OFF, PROC_OFF}; +module_param_array(hdr10_plus_process_mode, uint, &vd_path_max, 0444); +MODULE_PARM_DESC(hdr10_plus_process_mode, "\n current hdr10_plus_process_mode\n"); /* 0: tx don't support hdr10+, 1: tx support hdr10+*/ -static uint tx_hdr10_plus_support; +uint tx_hdr10_plus_support; -/* 0: hlg->hlg, 1:hlg->hdr*/ -static uint hlg_process_mode = 1; -/* 0: hdr->hdr, 1:hdr->sdr 2:hlg->hdr*/ -static uint cur_hlg_process_mode = 2; -module_param(hlg_process_mode, uint, 0444); +/* 0: hlg->hlg, 1:hlg->sdr 2:hlg->hdr*/ +uint hlg_process_mode[VD_PATH_MAX]; +uint cur_hlg_process_mode[VD_PATH_MAX] = {PROC_OFF, PROC_OFF}; +module_param_array(hlg_process_mode, uint, &vd_path_max, 0444); MODULE_PARM_DESC(hlg_process_mode, "\n current hlg_process_mode\n"); -static uint force_pure_hlg; -module_param(force_pure_hlg, uint, 0664); +static uint force_pure_hlg[VD_PATH_MAX]; +module_param_array(force_pure_hlg, uint, &vd_path_max, 0664); MODULE_PARM_DESC(force_pure_hlg, "\n current force_pure_hlg\n"); uint sdr_mode; /* 0: sdr->sdr, 1:sdr->hdr, 2:auto */ -static uint sdr_process_mode = 2; /* 0: sdr->sdr, 1:sdr->hdr */ -static uint cur_sdr_process_mode = 2; /* 0: sdr->sdr, 1:sdr->hdr */ -static int sdr_saturation_offset = 20; /* 0: sdr->sdr, 1:sdr->hdr */ module_param(sdr_mode, uint, 0664); MODULE_PARM_DESC(sdr_mode, "\n set sdr_mode\n"); -module_param(sdr_process_mode, uint, 0444); + +static uint cur_sdr_mode; + +/* 0: sdr->sdr, 1:sdr->hdr, 2:sdr->hlg */ +uint sdr_process_mode[VD_PATH_MAX]; +uint cur_sdr_process_mode[VD_PATH_MAX] = {PROC_OFF, PROC_OFF}; +module_param_array(sdr_process_mode, uint, &vd_path_max, 0444); MODULE_PARM_DESC(sdr_process_mode, "\n current hdr_process_mode\n"); + +static int sdr_saturation_offset = 20; /* 0: sdr->sdr, 1:sdr->hdr */ module_param(sdr_saturation_offset, int, 0664); MODULE_PARM_DESC(sdr_saturation_offset, "\n add saturation\n"); @@ -361,13 +392,17 @@ static uint cur_hdr_support; module_param(cur_hdr_support, uint, 0664); MODULE_PARM_DESC(cur_hdr_support, "\n cur_hdr_support\n"); +static uint cur_colorimetry_support; +module_param(cur_colorimetry_support, uint, 0664); +MODULE_PARM_DESC(cur_colorimetry_support, "\n cur_colorimetry_support\n"); + static uint cur_hlg_support; module_param(cur_hlg_support, uint, 0664); MODULE_PARM_DESC(cur_hlg_support, "\n cur_hlg_support\n"); -static uint cur_output_mode; -module_param(cur_output_mode, uint, 0664); -MODULE_PARM_DESC(cur_output_mode, "\n cur_output_mode\n"); +static uint cur_color_fmt; +module_param(cur_color_fmt, uint, 0664); +MODULE_PARM_DESC(cur_color_fmt, "\n cur_color_fmt\n"); static uint range_control; module_param(range_control, uint, 0664); @@ -377,10 +412,32 @@ MODULE_PARM_DESC(range_control, "\n range_control 0:limit 1:full\n"); /* bit 1: use display primary,*/ /* bit 2: adjust contrast according to source lumin,*/ /* bit 3: adjust saturation according to source lumin */ -uint hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3); +/* bit 4: convert HLG to HDR if sink not supprot HLG but HDR */ +uint hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (1 << 4); 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]; +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; +} +EXPORT_SYMBOL(set_hdr_module_status); + +#define PROC_FLAG_FORCE_PROCESS 1 +static uint video_process_flags[VD_PATH_MAX]; +module_param_array(video_process_flags, uint, &vd_path_max, 0664); +MODULE_PARM_DESC(video_process_flags, "\n video_process_flags\n"); + static uint rdma_flag = (1 << VPP_MATRIX_OSD) | (1 << VPP_MATRIX_VD1) | @@ -680,7 +737,7 @@ static void load_knee_lut(int on) int final_knee_setting[MAX_KNEE_SETTING]; if ((cur_knee_factor != knee_factor) && (!lut_289_en) && (on)) { - pr_csc("Knee_factor changed from %d to %d\n", + pr_csc(1, "Knee_factor changed from %d to %d\n", cur_knee_factor, knee_factor); for (i = 0; i < MAX_KNEE_SETTING; i++) { final_knee_setting[i] = @@ -703,8 +760,9 @@ static void load_knee_lut(int on) VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2 * j, value); if (j == 0) - pr_csc("xvycc_lut[%1d][%3d] = 0x%03x\n", - j, i, value); + pr_csc(1, + "xvycc_lut[%1d][%3d] = 0x%03x\n", + j, i, value); } for (i = 16; i < 272; i++) { k = 1 + ((i - 16) >> 3); @@ -726,8 +784,9 @@ static void load_knee_lut(int on) VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2 * j, value); if (j == 0) - pr_csc("xvycc_lut[%1d][%3d] = 0x%03x\n", - j, i, value); + pr_csc(1, + "xvycc_lut[%1d][%3d] = 0x%03x\n", + j, i, value); } for (i = 272; i < 289; i++) { k = MAX_KNEE_SETTING - 2; @@ -741,8 +800,9 @@ static void load_knee_lut(int on) VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2 * j, value); if (j == 0) - pr_csc("xvycc_lut[%1d][%3d] = 0x%03x\n", - j, i, value); + pr_csc(1, + "xvycc_lut[%1d][%3d] = 0x%03x\n", + j, i, value); } } cur_knee_factor = knee_factor; @@ -1906,25 +1966,25 @@ static void print_vpp_matrix(int m_select, int *s, int on) else return; - pr_csc("%s matrix %s:\n", matrix_name[m_select], + pr_csc(1, "%s matrix %s:\n", matrix_name[m_select], on ? "on" : "off"); if (size == MATRIX_5x3_COEF_SIZE) { - pr_csc( + pr_csc(1, "\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[0]), DECI(s[0]), FRAC(s[0]), SIGN(s[3]), DECI(s[3]), FRAC(s[3]), SIGN(s[4]), DECI(s[4]), FRAC(s[4]), SIGN(s[5]), DECI(s[5]), FRAC(s[5]), SIGN(s[18]), DECI(s[18]), FRAC(s[18])); - pr_csc( + pr_csc(1, "\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[1]), DECI(s[1]), FRAC(s[1]), SIGN(s[6]), DECI(s[6]), FRAC(s[6]), SIGN(s[7]), DECI(s[7]), FRAC(s[7]), SIGN(s[8]), DECI(s[8]), FRAC(s[8]), SIGN(s[19]), DECI(s[19]), FRAC(s[19])); - pr_csc( + pr_csc(1, "\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[2]), DECI(s[2]), FRAC(s[2]), SIGN(s[9]), DECI(s[9]), FRAC(s[9]), @@ -1932,34 +1992,34 @@ static void print_vpp_matrix(int m_select, int *s, int on) SIGN(s[11]), DECI(s[11]), FRAC(s[11]), SIGN(s[20]), DECI(s[20]), FRAC(s[20])); if (s[21]) { - pr_csc("\t\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", + pr_csc(1, "\t\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[12]), DECI(s[12]), FRAC(s[12]), SIGN(s[13]), DECI(s[13]), FRAC(s[13]), SIGN(s[14]), DECI(s[14]), FRAC(s[14])); - pr_csc("\t\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", + pr_csc(1, "\t\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[15]), DECI(s[15]), FRAC(s[15]), SIGN(s[16]), DECI(s[16]), FRAC(s[16]), SIGN(s[17]), DECI(s[17]), FRAC(s[17])); } if (s[22]) - pr_csc("\tright shift=%d\n", s[22]); + pr_csc(1, "\tright shift=%d\n", s[22]); } else { - pr_csc("\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", + pr_csc(1, "\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[0]), DECI(s[0]), FRAC(s[0]), SIGN(s[1]), DECI(s[1]), FRAC(s[1]), SIGN(s[2]), DECI(s[2]), FRAC(s[2])); - pr_csc("\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", + pr_csc(1, "\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[3]), DECI(s[3]), FRAC(s[3]), SIGN(s[4]), DECI(s[4]), FRAC(s[4]), SIGN(s[5]), DECI(s[5]), FRAC(s[5])); - pr_csc("\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", + pr_csc(1, "\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n", SIGN(s[6]), DECI(s[6]), FRAC(s[6]), SIGN(s[7]), DECI(s[7]), FRAC(s[7]), SIGN(s[8]), DECI(s[8]), FRAC(s[8])); if (s[9]) - pr_csc("\tright shift=%d\n", s[9]); + pr_csc(1, "\tright shift=%d\n", s[9]); } - pr_csc("\n"); + pr_csc(1, "\n"); } static int *cur_osd_mtx = RGB709_to_YUV709l_coeff; @@ -2661,12 +2721,12 @@ static void print_vpp_lut( WRITE_VPP_REG(addr_port, 61); data = READ_VPP_REG(data_port); b_map[OSD_OETF_LUT_SIZE - 1] = data & 0xffff; - pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); + pr_csc(1, "%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); for (i = 0; i < OSD_OETF_LUT_SIZE; i++) { - pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n", + pr_csc(1, "\t[%d] = 0x%04x 0x%04x 0x%04x\n", i, r_map[i], g_map[i], b_map[i]); } - pr_csc("\n"); + pr_csc(1, "\n"); } else if (lut_sel == VPP_LUT_OSD_EOTF) { WRITE_VPP_REG(addr_port, 0); for (i = 0; i < 16; i++) { @@ -2689,12 +2749,12 @@ static void print_vpp_lut( } data = READ_VPP_REG(data_port); b_map[EOTF_LUT_SIZE - 1] = data & 0xffff; - pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); + pr_csc(1, "%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); for (i = 0; i < EOTF_LUT_SIZE; i++) { - pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n", + pr_csc(1, "\t[%d] = 0x%04x 0x%04x 0x%04x\n", i, r_map[i], g_map[i], b_map[i]); } - pr_csc("\n"); + pr_csc(1, "\n"); } else if (lut_sel == VPP_LUT_EOTF) { WRITE_VPP_REG(addr_port, 0); for (i = 0; i < 16; i++) { @@ -2717,12 +2777,12 @@ static void print_vpp_lut( } data = READ_VPP_REG(data_port); b_map[EOTF_LUT_SIZE - 1] = data & 0xffff; - pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); + pr_csc(1, "%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); for (i = 0; i < EOTF_LUT_SIZE; i++) { - pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n", + pr_csc(1, "\t[%d] = 0x%04x 0x%04x 0x%04x\n", i, r_map[i], g_map[i], b_map[i]); } - pr_csc("\n"); + pr_csc(1, "\n"); } else if (lut_sel == VPP_LUT_OETF) { WRITE_VPP_REG(ctrl_port, 0x0); WRITE_VPP_REG(addr_port, 0); @@ -2734,17 +2794,17 @@ static void print_vpp_lut( WRITE_VPP_REG(addr_port + 4, 0); for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++) b_map[i] = READ_VPP_REG(data_port + 4) & 0x3ff; - pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); + pr_csc(1, "%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++) { - pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n", + pr_csc(1, "\t[%d] = 0x%04x 0x%04x 0x%04x\n", i, r_map[i], g_map[i], b_map[i]); } - pr_csc("\n"); + pr_csc(1, "\n"); if (on) WRITE_VPP_REG(ctrl_port, 0x7f); } else if (lut_sel == VPP_LUT_INV_EOTF) { WRITE_VPP_REG_BITS(ctrl_port, 0, 12, 3); - pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); + pr_csc(1, "%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off"); for (i = 0; i < EOTF_INV_LUT_NEG2048_SIZE + EOTF_INV_LUT_SIZE + EOTF_INV_LUT_1024_SIZE; @@ -2752,12 +2812,12 @@ static void print_vpp_lut( WRITE_VPP_REG(addr_port, i); data = READ_VPP_REG(data_port) & 0xfff; if (data & 0x800) - pr_csc("\t[%d] = %d\n", + pr_csc(1, "\t[%d] = %d\n", i, -(~(data|0xfffff000) + 1)); else - pr_csc("\t[%d] = %d\n", i, data); + pr_csc(1, "\t[%d] = %d\n", i, data); } - pr_csc("\n"); + pr_csc(1, "\n"); if (on) WRITE_VPP_REG_BITS(ctrl_port, 1<<2, 12, 3); } @@ -3364,40 +3424,46 @@ static void vpp_set_matrix3( cur_csc_mode = csc_mode; } -static uint cur_signal_type = 0xffffffff; -module_param(cur_signal_type, uint, 0664); +static uint cur_signal_type[VD_PATH_MAX] = { + 0xffffffff, + 0xffffffff +}; +module_param_array(cur_signal_type, uint, &vd_path_max, 0664); MODULE_PARM_DESC(cur_signal_type, "\n cur_signal_type\n"); -static struct vframe_master_display_colour_s cur_master_display_colour = { - 0, +static struct vframe_master_display_colour_s +cur_master_display_colour[VD_PATH_MAX] = { { + 0, + { + {0, 0}, + {0, 0}, + {0, 0}, + }, {0, 0}, - {0, 0}, - {0, 0}, + {0, 0} }, - {0, 0}, - {0, 0} + { + 0, + { + {0, 0}, + {0, 0}, + {0, 0}, + }, + {0, 0}, + {0, 0} + } }; -#define SIG_CS_CHG 0x01 -#define SIG_SRC_CHG 0x02 -#define SIG_PRI_INFO 0x04 -#define SIG_KNEE_FACTOR 0x08 -#define SIG_HDR_MODE 0x10 -#define SIG_HDR_SUPPORT 0x20 -#define SIG_WB_CHG 0x40 -#define SIG_HLG_MODE 0x80 -#define SIG_HLG_SUPPORT 0x100 -#define SIG_OP_CHG 0x200 -#define SIG_SRC_OUTPUT_CHG 0x400/*for box*/ -#define SIG_HDR10_PLUS_MODE 0x800 - -unsigned int pre_vd1_mtx_sel = VPP_MATRIX_NULL; -module_param(pre_vd1_mtx_sel, uint, 0664); +unsigned int pre_vd1_mtx_sel[VD_PATH_MAX] = { + VPP_MATRIX_NULL, + VPP_MATRIX_NULL, +}; +module_param_array(pre_vd1_mtx_sel, uint, &vd_path_max, 0664); MODULE_PARM_DESC(pre_vd1_mtx_sel, "\n pre_vd1_mtx_sel\n"); unsigned int vd1_mtx_sel = VPP_MATRIX_NULL; static int src_timing_outputmode_changed(struct vframe_s *vf, - struct vinfo_s *vinfo) + struct vinfo_s *vinfo, enum vd_path_e vd_path) { unsigned int width, height; @@ -3420,15 +3486,229 @@ static int src_timing_outputmode_changed(struct vframe_s *vf, else vd1_mtx_sel = VPP_MATRIX_NULL; - if (pre_vd1_mtx_sel != vd1_mtx_sel) { - pre_vd1_mtx_sel = vd1_mtx_sel; + if (pre_vd1_mtx_sel[vd_path] != vd1_mtx_sel) { + pre_vd1_mtx_sel[vd_path] = vd1_mtx_sel; return 1; } return 0; } -int signal_type_changed(struct vframe_s *vf, struct vinfo_s *vinfo) +static void print_primaries_info(struct vframe_master_display_colour_s *p) +{ + int i, j; + + if (!p->present_flag & 1) { + pr_csc(1, "\tmaster display color not available"); + return; + } + if (p->present_flag & 0x20) + pr_csc(1, "\tcolor primaries in GBR\n"); + else if (p->present_flag & 0x10) + pr_csc(1, "\tcolor primaries in RGB\n"); + else + pr_csc(1, "\tcolor primaries not available use default 2020\n"); + for (i = 0; i < 3; i++) + for (j = 0; j < 2; j++) + pr_csc(1, + "\t\tprimaries[%1d][%1d] = %04x\n", + i, j, + p->primaries[i][j]); + pr_csc(1, "\t\twhite_point = (%04x, %04x)\n", + p->white_point[0], p->white_point[1]); + pr_csc(1, "\t\tmax, min luminance = %08x, %08x\n", + p->luminance[0], p->luminance[1]); +} + +static uint cur_vd_signal_type = 0xffffffff; +void get_cur_vd_signal_type(enum vd_path_e vd_path) +{ + cur_vd_signal_type = cur_signal_type[vd_path]; +} + +int get_primaries_type(struct vframe_master_display_colour_s *p_mdc) +{ + if (!p_mdc->present_flag) + return 0; + +#if 0 + /* revisit if needed */ + /* check endian by white point */ + /* need to fix by container parser */ + if (((p_mdc->white_point[0] & 0x00f0) == 0x30) + && ((p_mdc->white_point[1] & 0x00f0) == 0x40) + && (((p_mdc->white_point[0] & 0xf000) != 0x3000) + || ((p_mdc->white_point[1] & 0xf000) != 0x4000))) { + for (i = 0; i < 2; i++) + p_mdc->white_point[i] = + ((p_mdc->white_point[i] & 0xff) << 8) | + ((p_mdc->white_point[i] & 0xff00) >> 8); + + for (i = 0; i < 3; i++) + for (j = 0; j < 2; j++) + p_mdc->primaries[i][j] = + ((p_mdc->primaries[i][j] & 0xff) << 8) | + ((p_mdc->primaries[i][j] & 0xff00) >> 8); + if (p_mdc->luminance[0] < 1000 * 10000) + p_mdc->luminance[0] = 1000 * 10000; + else if (p_mdc->luminance[0] > 10000 * 10000) + p_mdc->luminance[0] = 10000 * 10000; + if (p_mdc->luminance[1] > 100) + p_mdc->luminance[1] = 100; + else if (p_mdc->luminance[1] < 50) + p_mdc->luminance[1] = 50; + //pr_csc(1, "master_display_colour endian wrong!\n"); + } +#endif + + if ((p_mdc->primaries[0][1] > p_mdc->primaries[1][1]) + && (p_mdc->primaries[0][1] > p_mdc->primaries[2][1]) + && (p_mdc->primaries[2][0] > p_mdc->primaries[0][0]) + && (p_mdc->primaries[2][0] > p_mdc->primaries[1][0])) { + /* reasonable g,b,r */ + return 2; + } else if ((p_mdc->primaries[0][0] > p_mdc->primaries[1][0]) + && (p_mdc->primaries[0][0] > p_mdc->primaries[2][0]) + && (p_mdc->primaries[1][1] > p_mdc->primaries[0][1]) + && (p_mdc->primaries[1][1] > p_mdc->primaries[2][1])) { + /* reasonable r,g,b */ + return 1; + } + /* source not usable, use standard bt2020 */ + return 0; +} +EXPORT_SYMBOL(get_primaries_type); + +int hdr10_primaries_changed( + struct vframe_master_display_colour_s *p_mdc, + struct vframe_master_display_colour_s *p_hdr10_param) +{ + struct vframe_content_light_level_s *p_cll = + &p_mdc->content_light_level; + uint8_t flag = 0; + uint32_t max_lum = 1000 * 10000; + uint32_t min_lum = 50; + int primaries_type = 0; + int i, j; + + primaries_type = get_primaries_type(p_mdc); + if (primaries_type == 0) { + if ((p_hdr10_param->luminance[0] + != max_lum) + || (p_hdr10_param->luminance[1] + != min_lum)) { + flag |= 1; + p_hdr10_param->luminance[0] + = max_lum; + p_hdr10_param->luminance[1] + = min_lum; + } + for (i = 0; i < 2; i++) { + if (p_hdr10_param->white_point[i] + != bt2020_white_point[i]) { + flag |= 4; + p_hdr10_param-> + white_point[i] = + bt2020_white_point[i]; + } + } + for (i = 0; i < 3; i++) { + /* GBR -> GBR */ + for (j = 0; j < 2; j++) { + if (p_hdr10_param-> + primaries[i][j] + != p_mdc-> + primaries[i][j]) { + p_hdr10_param-> + primaries[i][j] + = p_mdc-> + primaries[i][j]; + flag |= 2; + } + } + } + p_hdr10_param->present_flag = 1; + } else { + for (i = 0; i < 2; i++) { + if (p_hdr10_param->luminance[i] + != p_mdc->luminance[i]) { + flag |= 1; + p_hdr10_param-> + luminance[i] + = p_mdc->luminance[i]; + } + if (p_hdr10_param->white_point[i] + != p_mdc->white_point[i]) { + flag |= 4; + p_hdr10_param-> + white_point[i] = + p_mdc->white_point[i]; + } + } + if (primaries_type == 1) { + /* RGB -> GBR */ + for (i = 0; i < 3; i++) { + for (j = 0; j < 2; j++) { + if (p_hdr10_param-> + primaries[i][j] + != p_mdc-> + primaries[(i + 2) % 3][j]) { + p_hdr10_param-> + primaries[i][j] = p_mdc-> + primaries[(i + 2) % 3][j]; + flag |= 2; + } + } + } + p_hdr10_param->present_flag = 0x21; + } else if (primaries_type == 2) { + /* GBR -> GBR */ + for (i = 0; i < 3; i++) { + for (j = 0; j < 2; j++) { + if (p_hdr10_param-> + primaries[i][j] + != p_mdc-> + primaries[i][j]) { + p_hdr10_param-> + primaries[i][j] + = p_mdc-> + primaries[i][j]; + flag |= 2; + } + } + } + p_hdr10_param->present_flag = 0x11; + } + } + + if (p_cll->present_flag) { + if ((p_hdr10_param->content_light_level.max_content + != p_cll->max_content) + || (p_hdr10_param->content_light_level.max_pic_average + != p_cll->max_pic_average)) + flag |= 8; + if (flag & 8) { + p_hdr10_param->content_light_level.max_content + = p_cll->max_content; + p_hdr10_param->content_light_level.max_pic_average + = p_cll->max_pic_average; + } + p_hdr10_param->content_light_level.present_flag = 1; + } else { + if ((p_hdr10_param->content_light_level.max_content != 0) + || (p_hdr10_param->content_light_level.max_pic_average != 0)) { + p_hdr10_param->content_light_level.max_content = 0; + p_hdr10_param->content_light_level.max_pic_average = 0; + } + if (p_hdr10_param->content_light_level.present_flag) + flag |= 8; + p_hdr10_param->content_light_level.present_flag = 0; + } + return flag; +} + +int signal_type_changed(struct vframe_s *vf, + struct vinfo_s *vinfo, enum vd_path_e vd_path) { u32 signal_type = 0; u32 default_signal_type; @@ -3437,6 +3717,7 @@ int signal_type_changed(struct vframe_s *vf, struct vinfo_s *vinfo) struct vframe_master_display_colour_s *p_cur; struct vframe_master_display_colour_s *p_new; struct vframe_master_display_colour_s cus; + int ret; if (!vf) return 0; @@ -3493,7 +3774,7 @@ int signal_type_changed(struct vframe_s *vf, struct vinfo_s *vinfo) signal_type = default_signal_type; p_new = &vf->prop.master_display_colour; - p_cur = &cur_master_display_colour; + p_cur = &cur_master_display_colour[vd_path]; /* customer overwrite */ if (customer_master_display_en && ((p_new->present_flag & 0x80000000) == 0)) { @@ -3539,125 +3820,107 @@ int signal_type_changed(struct vframe_s *vf, struct vinfo_s *vinfo) /*vf->signal_type, signal_type);*/ } - if (p_new->present_flag & 1) { - for (i = 0; i < 3; i++) - for (j = 0; j < 2; j++) { - if (p_cur->primaries[i][j] - != p_new->primaries[i][j]) - change_flag |= SIG_PRI_INFO; - p_cur->primaries[i][j] - = p_new->primaries[i][j]; - } - for (i = 0; i < 2; i++) { - if (p_cur->white_point[i] - != p_new->white_point[i]) - change_flag |= SIG_PRI_INFO; - p_cur->white_point[i] - = p_new->white_point[i]; - } - for (i = 0; i < 2; i++) { - if (p_cur->luminance[i] - != p_new->luminance[i]) - change_flag |= SIG_PRI_INFO; - p_cur->luminance[i] - = p_new->luminance[i]; - } - if (p_cur->content_light_level.present_flag != - p_new->content_light_level.present_flag) { - change_flag |= SIG_PRI_INFO; - p_cur->content_light_level.present_flag = - p_new->content_light_level.present_flag; - } - if (p_cur->content_light_level.max_content != - p_new->content_light_level.max_content) { - change_flag |= SIG_PRI_INFO; - p_cur->content_light_level.max_content = - p_new->content_light_level.max_content; - } - if (p_cur->content_light_level.max_pic_average != - p_new->content_light_level.max_pic_average) { - change_flag |= SIG_PRI_INFO; - p_cur->content_light_level.max_pic_average = - p_new->content_light_level.max_pic_average; - } - if (!p_cur->present_flag) { - p_cur->present_flag = 1; - change_flag |= SIG_PRI_INFO; - } - } else if (p_cur->present_flag) { - p_cur->present_flag = 0; + 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); + print_primaries_info(p_cur); } - if (change_flag & SIG_PRI_INFO) - pr_csc("Master_display_colour changed.\n"); - - if (signal_type != cur_signal_type) { - pr_csc("Signal type changed from 0x%x to 0x%x.\n", - cur_signal_type, signal_type); + if (signal_type != cur_signal_type[vd_path]) { + pr_csc(1, "vd%d Signal type changed from 0x%x to 0x%x.\n", + vd_path + 1, + cur_signal_type[vd_path], + signal_type); change_flag |= SIG_CS_CHG; - cur_signal_type = signal_type; + cur_signal_type[vd_path] = signal_type; } - if (pre_src_type != vf->source_type) { - pr_csc("Signal source changed from 0x%x to 0x%x.\n", - pre_src_type, vf->source_type); + if (pre_src_type[vd_path] != vf->source_type) { + pr_csc(1, "vd%d Signal source changed from 0x%x to 0x%x.\n", + vd_path + 1, pre_src_type[vd_path], vf->source_type); change_flag |= SIG_SRC_CHG; - pre_src_type = vf->source_type; + pre_src_type[vd_path] = vf->source_type; } if (cur_knee_factor != knee_factor) { - pr_csc("Knee factor changed.\n"); + pr_csc(1, "vd%d Knee factor changed.\n", vd_path + 1); change_flag |= SIG_KNEE_FACTOR; cur_knee_factor = knee_factor; } - if (cur_hdr_process_mode != hdr_process_mode) { - pr_csc("HDR mode changed.\n"); - change_flag |= SIG_HDR_MODE; - } - if (cur_hlg_process_mode != hlg_process_mode) { - pr_csc("HLG mode changed.\n"); - change_flag |= SIG_HLG_MODE; - } - if (cur_sdr_process_mode != sdr_process_mode) { - pr_csc("SDR mode changed.\n"); - change_flag |= SIG_HDR_MODE; + if (!is_dolby_vision_on() || vd_path != VD1_PATH) { + if (cur_hdr_process_mode[vd_path] + != hdr_process_mode[vd_path]) { + pr_csc(1, "vd%d HDR mode changed %d %d.\n", vd_path + 1, + cur_hdr_process_mode[vd_path], + hdr_process_mode[vd_path]); + change_flag |= SIG_HDR_MODE; + } + if (cur_hlg_process_mode[vd_path] + != hlg_process_mode[vd_path]) { + pr_csc(1, "vd%d HLG mode changed %d %d.\n", vd_path + 1, + cur_hlg_process_mode[vd_path], + hlg_process_mode[vd_path]); + change_flag |= SIG_HLG_MODE; + } + if (cur_sdr_process_mode[vd_path] + != sdr_process_mode[vd_path]) { + pr_csc(1, "vd%d SDR mode changed %d %d.\n", vd_path + 1, + cur_sdr_process_mode[vd_path], + sdr_process_mode[vd_path]); + change_flag |= SIG_HDR_MODE; + } + if (cur_hdr10_plus_process_mode[vd_path] + != hdr10_plus_process_mode[vd_path]) { + pr_csc(1, "vd%d HDR10+ mode changed %d %d.\n", + vd_path + 1, + cur_hdr10_plus_process_mode[vd_path], + hdr10_plus_process_mode[vd_path]); + change_flag |= SIG_HDR10_PLUS_MODE; + } } - if (cur_hdr_support != (vinfo->hdr_info.hdr_support & 0x4)) { - pr_csc("Tx HDR support changed.\n"); + + if (cur_hdr_support + != (vinfo->hdr_info.hdr_support & 0x4)) { + pr_csc(1, "Tx HDR support changed.\n"); change_flag |= SIG_HDR_SUPPORT; - cur_hdr_support = vinfo->hdr_info.hdr_support & 0x4; + cur_hdr_support = + vinfo->hdr_info.hdr_support & 0x4; } - if (cur_output_mode != vinfo->viu_color_fmt) { - pr_csc("output mode changed.\n"); + if (cur_colorimetry_support != (vinfo->hdr_info.colorimetry_support)) { + pr_csc(1, "Tx colorimetry support changed.\n"); + change_flag |= SIG_COLORIMETRY_SUPPORT; + cur_colorimetry_support = vinfo->hdr_info.colorimetry_support; + } + if (cur_color_fmt != vinfo->viu_color_fmt) { + pr_csc(1, "color format changed.\n"); change_flag |= SIG_OP_CHG; - cur_output_mode = vinfo->viu_color_fmt; + cur_color_fmt = vinfo->viu_color_fmt; } if (cur_hlg_support != (vinfo->hdr_info.hdr_support & 0x8)) { - pr_csc("Tx HLG support changed.\n"); + pr_csc(1, "Tx HLG support changed.\n"); change_flag |= SIG_HLG_SUPPORT; cur_hlg_support = vinfo->hdr_info.hdr_support & 0x8; } - if (cur_hdr10_plus_process_mode != hdr10_plus_process_mode) { - pr_csc("HDR10 plus mode changed.\n"); - change_flag |= SIG_HDR10_PLUS_MODE; - cur_hdr10_plus_process_mode = hdr10_plus_process_mode; - } - if ((cur_eye_protect_mode != wb_val[0]) || (cur_eye_protect_mode == 1)) { - pr_csc(" eye protect mode changed.\n"); + pr_csc(1, "eye protect mode changed.\n"); change_flag |= SIG_WB_CHG; } - if (src_timing_outputmode_changed(vf, vinfo)) { - pr_csc(" source timing output mode changed.\n"); + if (src_timing_outputmode_changed(vf, vinfo, vd_path)) { + pr_csc(1, "vd%d source timing output mode changed.\n", + vd_path + 1); change_flag |= SIG_SRC_OUTPUT_CHG; } + return change_flag; } -#define signal_range ((cur_signal_type >> 25) & 1) -#define signal_color_primaries ((cur_signal_type >> 16) & 0xff) -#define signal_transfer_characteristic ((cur_signal_type >> 8) & 0xff) +#define signal_format ((cur_vd_signal_type >> 26) & 7) +#define signal_range ((cur_vd_signal_type >> 25) & 1) +#define signal_color_primaries ((cur_vd_signal_type >> 16) & 0xff) +#define signal_transfer_characteristic ((cur_vd_signal_type >> 8) & 0xff) enum vpp_matrix_csc_e get_csc_type(void) { enum vpp_matrix_csc_e csc_type = VPP_MATRIX_NULL; @@ -3679,36 +3942,44 @@ enum vpp_matrix_csc_e get_csc_type(void) if (signal_transfer_characteristic == 16) { /* smpte st-2084 */ if (signal_color_primaries != 9) - pr_csc("\tWARNING: non-standard HDR!!!\n"); + pr_csc(1, "\tWARNING: non-standard HDR!!!\n"); csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; } else if (signal_transfer_characteristic == 14) { /* bt2020-10 */ - pr_csc("\tWARNING: bt2020-10 HDR!!!\n"); + pr_csc(1, "\tWARNING: bt2020-10 HDR!!!\n"); csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; } else if (signal_transfer_characteristic == 15) { /* bt2020-12 */ - pr_csc("\tWARNING: bt2020-12 HDR!!!\n"); + pr_csc(1, "\tWARNING: bt2020-12 HDR!!!\n"); if (signal_range == 0) csc_type = VPP_MATRIX_YUV709_RGB; else csc_type = VPP_MATRIX_YUV709F_RGB; } else if (signal_transfer_characteristic == 18) { /* bt2020-12 */ - pr_csc("\tWARNING: HLG!!!\n"); + /* pr_csc(1, "\tHLG!!!\n"); */ csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; } else if (signal_transfer_characteristic == 0x30) { - pr_csc("\tWARNING: HDR10 PLUS!!!\n"); - csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC; + if (signal_color_primaries == 9) { + /* pr_csc(1, "\tHDR10+!!!\n"); */ + csc_type = + VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC; + } else { + pr_csc(1, + "\tWARNING: non-standard HDR10+!!!\n"); + csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; + } } else { /* unknown transfer characteristic */ - pr_csc("\tWARNING: unknown HDR!!!\n"); + pr_csc(1, "\tWARNING: unknown HDR!!!\n"); if (signal_range == 0) csc_type = VPP_MATRIX_YUV709_RGB; else csc_type = VPP_MATRIX_YUV709F_RGB; } } else { - pr_csc("\tWARNING: unsupported colour space!!!\n"); + if (signal_format == 0) + pr_csc(1, "\tWARNING: unknown colour space!!!\n"); if (signal_range == 0) csc_type = VPP_MATRIX_YUV601_RGB; else @@ -3731,11 +4002,15 @@ static int get_hdr_type(void) void get_hdr_source_type(void) { - if ((signal_transfer_characteristic == 18) || - (signal_transfer_characteristic == 14)) + if (((signal_transfer_characteristic == 14) || + (signal_transfer_characteristic == 18)) && + (signal_color_primaries == 9)) hdr_source_type = HLG_SOURCE; - else if ((signal_color_primaries == 9) || - (signal_transfer_characteristic == 16)) + else if ((signal_transfer_characteristic == 0x30) + && (signal_color_primaries == 9)) + hdr_source_type = HDR10PLUS_SOURCE; + else if ((signal_transfer_characteristic == 16) + || (signal_color_primaries == 9)) hdr_source_type = HDR10_SOURCE; else hdr_source_type = SDR_SOURCE; @@ -3949,13 +4224,13 @@ static void cal_mtx_seting( m->right_shift = right_shift; } N2C(in, ibl, obl); - pr_csc("\tHDR color convert matrix:\n"); + pr_csc(1, "\tHDR color convert matrix:\n"); for (i = 0; i < 3; i++) { m->pre_offset[i] = 0; for (j = 0; j < 3; j++) m->matrix[i][j] = in[j][i]; m->offset[i] = 0; - pr_csc("\t\t%04x %04x %04x\n", + pr_csc(1, "\t\t%04x %04x %04x\n", (int)(m->matrix[i][0] & 0xffff), (int)(m->matrix[i][1] & 0xffff), (int)(m->matrix[i][2] & 0xffff)); @@ -4163,22 +4438,6 @@ static int calculate_contrast_adj(int max_lumin) return target_contrast - vd1_contrast; } -static void print_primaries_info(struct vframe_master_display_colour_s *p) -{ - int i, j; - - for (i = 0; i < 3; i++) - for (j = 0; j < 2; j++) - pr_csc( - "\t\tprimaries[%1d][%1d] = %04x\n", - i, j, - p->primaries[i][j]); - pr_csc("\t\twhite_point = (%04x, %04x)\n", - p->white_point[0], p->white_point[1]); - pr_csc("\t\tmax,min luminance = %08x, %08x\n", - p->luminance[0], p->luminance[1]); -} - static void amvecm_cp_hdr_info(struct master_display_info_s *hdr_data, struct vframe_master_display_colour_s *p) { @@ -4353,7 +4612,8 @@ static void vpp_lut_curve_set(enum vpp_lut_sel_e lut_sel, static int hdr_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *master_info) + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) { int need_adjust_contrast_saturation = 0; int max_lumin = 10000; @@ -4398,13 +4658,13 @@ static int hdr_process( int i, j; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { - hdr_func(OSD1_HDR, HDR_BYPASS); - hdr_func(VD1_HDR, HDR_SDR); + hdr_func(OSD1_HDR, HDR_BYPASS, vinfo); + hdr_func(VD1_HDR, HDR_SDR, vinfo); return need_adjust_contrast_saturation; } if (master_info->present_flag & 1) { - pr_csc("\tMaster_display_colour available.\n"); + pr_csc(1, "\tMaster_display_colour available.\n"); print_primaries_info(master_info); /* for VIDEO */ csc_type = @@ -4421,7 +4681,7 @@ static int hdr_process( need_adjust_contrast_saturation |= 1; } else { /* use bt2020 primaries */ - pr_csc("\tNo master_display_colour.\n"); + pr_csc(1, "\tNo master_display_colour.\n"); /* for VIDEO */ csc_type = prepare_customer_matrix( @@ -4599,7 +4859,8 @@ static int hdr_process( static int hlg_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *master_info) + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) { int need_adjust_contrast_saturation = 0; int max_lumin = 10000; @@ -4644,13 +4905,13 @@ static int hlg_process( int i, j; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { - hdr_func(VD1_HDR, HLG_SDR); - hdr_func(OSD1_HDR, HDR_BYPASS); + hdr_func(VD1_HDR, HLG_SDR, vinfo); + hdr_func(OSD1_HDR, HDR_BYPASS, vinfo); return need_adjust_contrast_saturation; } if (master_info->present_flag & 1) { - pr_csc("\tMaster_display_colour available.\n"); + pr_csc(1, "\tMaster_display_colour available.\n"); print_primaries_info(master_info); /* for VIDEO */ csc_type = @@ -4667,7 +4928,7 @@ static int hlg_process( need_adjust_contrast_saturation |= 1; } else { /* use bt2020 primaries */ - pr_csc("\tNo master_display_colour.\n"); + pr_csc(1, "\tNo master_display_colour.\n"); /* for VIDEO */ csc_type = prepare_customer_matrix( @@ -4839,7 +5100,8 @@ static int hlg_process( static void bypass_hdr_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *master_info) + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) { struct matrix_s osd_m = { {0, 0, 0}, @@ -4863,17 +5125,17 @@ static void bypass_hdr_process( int i, j; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { - hdr_func(VD1_HDR, HDR_BYPASS); + hdr_func(VD1_HDR, HDR_BYPASS, vinfo); if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && ((vinfo->hdr_info.hdr_support & 0xc) && (vinfo->viu_color_fmt != COLOR_FMT_RGB444))) { if (get_hdr_type() & HLG_FLAG) - hdr_func(OSD1_HDR, SDR_HLG); + hdr_func(OSD1_HDR, SDR_HLG, vinfo); else - hdr_func(OSD1_HDR, SDR_HDR); - pr_csc("\t osd sdr->hdr/hlg\n"); + hdr_func(OSD1_HDR, SDR_HDR, vinfo); + pr_csc(1, "\t osd sdr->hdr/hlg\n"); } else - hdr_func(OSD1_HDR, HDR_BYPASS); + hdr_func(OSD1_HDR, HDR_BYPASS, vinfo); return; } /*vpp matrix mux read*/ @@ -4919,14 +5181,15 @@ static void bypass_hdr_process( } /* osd eotf matrix 709->2020 */ if (master_info->present_flag & 1) { - pr_csc("\tMaster_display_colour available.\n"); + pr_csc(1, + "\tMaster_display_colour available.\n"); print_primaries_info(master_info); prepare_customer_matrix( &master_info->primaries, &master_info->white_point, vinfo, &osd_m, 1); } else { - pr_csc("\tNo master_display_colour.\n"); + pr_csc(1, "\tNo master_display_colour.\n"); prepare_customer_matrix( &bt2020_primaries, &bt2020_white_point, @@ -5083,7 +5346,7 @@ static void bypass_hdr_process( CSC_ON); } /* xvycc inv lut */ - if (sdr_process_mode && + if (sdr_process_mode[vd_path] && (csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) && ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL))) @@ -5154,7 +5417,7 @@ static void bypass_hdr_process( load_knee_lut(CSC_OFF); /* xvycc inv lut */ - if (sdr_process_mode) + if (sdr_process_mode[vd_path]) set_vpp_lut(VPP_LUT_INV_EOTF, NULL, NULL, @@ -5186,7 +5449,8 @@ static void bypass_hdr_process( static void set_bt2020csc_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *master_info) + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) { struct matrix_s osd_m = { {0, 0, 0}, @@ -5238,14 +5502,15 @@ static void set_bt2020csc_process( /* osd eotf matrix 709->2020 */ if (master_info->present_flag & 1) { - pr_csc("\tMaster_display_colour available.\n"); + pr_csc(1, + "\tMaster_display_colour available.\n"); print_primaries_info(master_info); prepare_customer_matrix( &master_info->primaries, &master_info->white_point, vinfo, &osd_m, 1); } else { - pr_csc("\tNo master_display_colour.\n"); + pr_csc(1, "\tNo master_display_colour.\n"); prepare_customer_matrix( &bt2020_primaries, &bt2020_white_point, @@ -5388,7 +5653,7 @@ static void set_bt2020csc_process( CSC_ON); } /* xvycc inv lut */ - if (sdr_process_mode && + if (sdr_process_mode[vd_path] && (csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) && ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL))) @@ -5453,7 +5718,7 @@ static void set_bt2020csc_process( load_knee_lut(CSC_OFF); /* xvycc inv lut */ - if (sdr_process_mode) + if (sdr_process_mode[vd_path]) set_vpp_lut(VPP_LUT_INV_EOTF, NULL, NULL, @@ -5485,7 +5750,8 @@ static void set_bt2020csc_process( static void hlg_hdr_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *master_info) + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) { struct matrix_s osd_m = { {0, 0, 0}, @@ -5509,8 +5775,8 @@ static void hlg_hdr_process( int i, j; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { - hdr_func(VD1_HDR, HLG_HDR); - hdr_func(OSD1_HDR, SDR_HDR); + hdr_func(VD1_HDR, HLG_HDR, vinfo); + hdr_func(OSD1_HDR, SDR_HDR, vinfo); return; } /*vpp matrix mux read*/ @@ -5543,14 +5809,15 @@ static void hlg_hdr_process( /* osd eotf matrix 709->2020 */ if (master_info->present_flag & 1) { - pr_csc("\tMaster_display_colour available.\n"); + pr_csc(1, + "\tMaster_display_colour available.\n"); print_primaries_info(master_info); prepare_customer_matrix( &master_info->primaries, &master_info->white_point, vinfo, &osd_m, 1); } else { - pr_csc("\tNo master_display_colour.\n"); + pr_csc(1, "\tNo master_display_colour.\n"); prepare_customer_matrix( &bt2020_primaries, &bt2020_white_point, @@ -5715,7 +5982,7 @@ static void hlg_hdr_process( load_knee_lut(CSC_OFF); /* xvycc inv lut */ - if (sdr_process_mode) + if (sdr_process_mode[vd_path]) set_vpp_lut(VPP_LUT_INV_EOTF, NULL, NULL, @@ -5747,12 +6014,13 @@ static void hlg_hdr_process( static void sdr_hdr_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *master_info) + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) { if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) { if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { - hdr_func(VD1_HDR, SDR_HDR); - hdr_func(OSD1_HDR, SDR_HDR); + hdr_func(VD1_HDR, SDR_HDR, vinfo); + hdr_func(OSD1_HDR, SDR_HDR, vinfo); return; } /*vpp matrix mux read*/ @@ -5839,12 +6107,13 @@ static void sdr_hdr_process( /*vpp matrix mux write*/ vpp_set_mtx_en_write(); } else - bypass_hdr_process(csc_type, vinfo, master_info); + bypass_hdr_process(csc_type, vinfo, master_info, vd_path); } static int vpp_eye_protection_process( enum vpp_matrix_csc_e csc_type, - struct vinfo_s *vinfo) + struct vinfo_s *vinfo, + enum vd_path_e vd_path) { cur_eye_protect_mode = wb_val[0]; memcpy(&video_rgb_ogo, wb_val, @@ -5853,10 +6122,10 @@ static int vpp_eye_protection_process( vpp_set_mtx_en_read(); /* only SDR need switch csc */ if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && - hdr_process_mode) + hdr_process_mode[vd_path]) return 0; if ((csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) && - sdr_process_mode) + sdr_process_mode[vd_path]) return 0; if (vinfo->viu_color_fmt == COLOR_FMT_RGB444) @@ -5912,7 +6181,7 @@ static int vpp_eye_protection_process( return 0; } -static void hdr_support_process(struct vinfo_s *vinfo) +static void hdr_support_process(struct vinfo_s *vinfo, enum vd_path_e vd_path) { /*check if hdmitx support hdr10+*/ if ((vinfo->hdr_info.hdr10plus_info.ieeeoui @@ -5929,65 +6198,101 @@ static void hdr_support_process(struct vinfo_s *vinfo) /*hdr_support & bit3 is hlg*/ if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT) && (vinfo->hdr_info.hdr_support & HLG_SUPPORT)) { - hdr_process_mode = 0; /* hdr->hdr*/ - hlg_process_mode = 0; /* hlg->hlg*/ + hdr_process_mode[vd_path] = PROC_BYPASS; /* hdr->hdr*/ + hlg_process_mode[vd_path] = PROC_BYPASS; /* hlg->hlg*/ } else if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT) && !(vinfo->hdr_info.hdr_support & HLG_SUPPORT)) { - hdr_process_mode = 0; /* hdr->hdr*/ - if (force_pure_hlg) - hlg_process_mode = 0; - else - hlg_process_mode = 1; /* hlg->hdr10*/ + hdr_process_mode[vd_path] = PROC_BYPASS; /* hdr->hdr*/ + if (force_pure_hlg[vd_path]) + hlg_process_mode[vd_path] = PROC_BYPASS; + else /* hlg->hdr10*/ + hlg_process_mode[vd_path] = PROC_MATCH; } else if (!(vinfo->hdr_info.hdr_support & HDR_SUPPORT) && (vinfo->hdr_info.hdr_support & HLG_SUPPORT)) { - hdr_process_mode = 1; - hlg_process_mode = 0; + hdr_process_mode[vd_path] = PROC_MATCH; + hlg_process_mode[vd_path] = PROC_BYPASS; } else { - hdr_process_mode = 1; - hlg_process_mode = 1; + hdr_process_mode[vd_path] = PROC_MATCH; + hlg_process_mode[vd_path] = PROC_MATCH; } if (tx_hdr10_plus_support) - hdr10_plus_process_mode = 0; + hdr10_plus_process_mode[vd_path] = PROC_BYPASS; else - hdr10_plus_process_mode = 1; + hdr10_plus_process_mode[vd_path] = PROC_MATCH; } else if (hdr_mode == 1) { - hdr_process_mode = 1; - hlg_process_mode = 1; - hdr10_plus_process_mode = 1; + hdr_process_mode[vd_path] = PROC_MATCH; + hlg_process_mode[vd_path] = PROC_MATCH; + hdr10_plus_process_mode[vd_path] = PROC_MATCH; } else { - hdr_process_mode = 0; - if (vinfo->hdr_info.hdr_support & HDR_SUPPORT) { - if ((vinfo->hdr_info.hdr_support & HLG_SUPPORT) || - (force_pure_hlg)) - hlg_process_mode = 0; - else - hlg_process_mode = 1; - } else - hlg_process_mode = 0; - - hdr10_plus_process_mode = 0; + if (vinfo->hdr_info.hdr_support & HDR_SUPPORT) + hdr_process_mode[vd_path] = PROC_BYPASS; + else + hdr_process_mode[vd_path] = PROC_MATCH; + if ((vinfo->hdr_info.hdr_support & HLG_SUPPORT) || + (force_pure_hlg[vd_path])) + hlg_process_mode[vd_path] = PROC_BYPASS; + else + hlg_process_mode[vd_path] = PROC_MATCH; + if (tx_hdr10_plus_support) + hdr10_plus_process_mode[vd_path] = PROC_BYPASS; + else + hdr10_plus_process_mode[vd_path] = PROC_MATCH; } if (sdr_mode == 2) { /* auto */ if ((vinfo->hdr_info.hdr_support & 0x4) && ((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) && (vinfo->viu_color_fmt != COLOR_FMT_RGB444))) - sdr_process_mode = 1; /*box sdr->hdr*/ + /*box sdr->hdr*/ + sdr_process_mode[vd_path] = PROC_SDR_TO_HDR; else if ((vinfo->viu_color_fmt == COLOR_FMT_RGB444) && ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL))) - sdr_process_mode = 1; /*tv sdr->hdr*/ + /*tv sdr->hdr*/ + sdr_process_mode[vd_path] = PROC_SDR_TO_HDR; else - sdr_process_mode = 0; /* sdr->sdr*/ + /* sdr->sdr*/ + sdr_process_mode[vd_path] = PROC_BYPASS; } else - sdr_process_mode = sdr_mode; /* force sdr->hdr */ + /* force sdr->hdr */ + sdr_process_mode[vd_path] = sdr_mode; +} +static enum hdr_type_e get_source_type(enum vd_path_e vd_path) +{ + get_cur_vd_signal_type(vd_path); + if (((signal_transfer_characteristic == 14) || + (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)) + return HDRTYPE_HDR10; + else + return HDRTYPE_SDR; +} + +static bool video_layer_wait_on[VD_PATH_MAX]; +bool is_video_layer_on(enum vd_path_e vd_path) +{ + bool video_on = + (vd_path == VD1_PATH) ? + get_video_enabled() : + get_videopip_enabled(); + + if (video_on) + video_layer_wait_on[vd_path] = false; + return video_on || + video_layer_wait_on[vd_path]; } static void hdr10_plus_metadata_update(struct vframe_s *vf, enum vpp_matrix_csc_e csc_type, - struct hdr10plus_para *hdmitx_hdr10plus_param) + struct hdr10plus_para *p) { if (!vf) return; @@ -5998,10 +6303,127 @@ static void hdr10_plus_metadata_update(struct vframe_s *vf, hdr10_plus_ootf_gen(); - if (tx_hdr10_plus_support) - hdr10_plus_hdmitx_vsif_parser(hdmitx_hdr10plus_param, - vf); + if (tx_hdr10_plus_support) { + hdr10_plus_hdmitx_vsif_parser(p, vf); + pr_csc(0x10, + "hdr10+ vsif: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + ((p->application_version & 0x3) << 6) | + ((p->targeted_max_lum & 0x1f) << 1), + p->average_maxrgb, + p->distribution_values[0], + p->distribution_values[1], + p->distribution_values[2], + p->distribution_values[3], + p->distribution_values[4], + p->distribution_values[5], + p->distribution_values[6], + p->distribution_values[7], + p->distribution_values[8], + ((p->num_bezier_curve_anchors & 0xf) << 4) | + ((p->knee_point_x >> 6) & 0xf), + ((p->knee_point_x & 0x3f) << 2) | + ((p->knee_point_y >> 8) & 0x3), + p->knee_point_y & 0xff, + p->bezier_curve_anchors[0], + p->bezier_curve_anchors[1], + p->bezier_curve_anchors[2], + p->bezier_curve_anchors[3], + p->bezier_curve_anchors[4], + p->bezier_curve_anchors[5], + p->bezier_curve_anchors[6], + p->bezier_curve_anchors[7], + p->bezier_curve_anchors[8], + ((p->graphics_overlay_flag & 0x1) << 7) | + ((p->no_delay_flag & 0x1) << 6)); + } +} + +static struct hdr10plus_para hdmitx_hdr10plus_params[VD_PATH_MAX]; +static int hdr10_plus_pkt_update; +static bool hdr10_plus_pkt_on; +static uint hdr10_plus_pkt_delay = 1; +static struct hdr10plus_para cur_hdr10plus_params; +static struct master_display_info_s cur_send_info; +module_param(hdr10_plus_pkt_delay, uint, 0664); + +uint get_hdr10_plus_pkt_delay(void) +{ + return hdr10_plus_pkt_delay; +} +EXPORT_SYMBOL(get_hdr10_plus_pkt_delay); + +void update_hdr10_plus_pkt(bool enable, + void *hdr10plus_params, + void *send_info) +{ + struct vinfo_s *vinfo = get_current_vinfo(); + struct vout_device_s *vdev = NULL; + + if (vinfo->vout_device) { + vdev = vinfo->vout_device; + if (!vdev) + return; + if (!vdev->fresh_tx_hdr_pkt) + return; + if (!vdev->fresh_tx_hdr10plus_pkt) + return; + } + + hdr10_plus_pkt_on = enable; + if (hdr10_plus_pkt_on) { + memcpy((void *)&cur_hdr10plus_params, hdr10plus_params, + sizeof(struct hdr10plus_para)); + memcpy((void *)&cur_send_info, send_info, + sizeof(struct master_display_info_s)); + hdr10_plus_pkt_update = HDRPLUS_PKT_UPDATE; + pr_csc(2, "update_hdr10_plus_pkt on\n"); + } else { + vdev->fresh_tx_hdr_pkt( + &cur_send_info); + vdev->fresh_tx_hdr10plus_pkt(0, + &cur_hdr10plus_params); + hdr10_plus_pkt_update = HDRPLUS_PKT_IDLE; + pr_csc(2, "update_hdr10_plus_pkt off\n"); + } +} +EXPORT_SYMBOL(update_hdr10_plus_pkt); + +void send_hdr10_plus_pkt(enum vd_path_e vd_path) +{ + struct vinfo_s *vinfo = get_current_vinfo(); + struct vout_device_s *vdev = NULL; + + if (vinfo->vout_device) { + vdev = vinfo->vout_device; + if (!vdev) + return; + if (!vdev->fresh_tx_hdr_pkt) + return; + if (!vdev->fresh_tx_hdr10plus_pkt) + return; + } + if (hdr10_plus_pkt_update == HDRPLUS_PKT_UPDATE) { + vdev->fresh_tx_hdr_pkt( + &cur_send_info); + vdev->fresh_tx_hdr10plus_pkt( + hdr10_plus_pkt_on, + &cur_hdr10plus_params); + if (get_hdr10_plus_pkt_delay() > 1) + hdr10_plus_pkt_update = HDRPLUS_PKT_REPEAT; + 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)) { + vdev->fresh_tx_hdr_pkt( + &cur_send_info); + vdev->fresh_tx_hdr10plus_pkt( + hdr10_plus_pkt_on, + &cur_hdr10plus_params); + pr_csc(2, "send_hdr10_plus_pkt repeat\n"); + } } +EXPORT_SYMBOL(send_hdr10_plus_pkt); static void hdr_tx_pkt_cb( struct vinfo_s *vinfo, @@ -6009,7 +6431,8 @@ static void hdr_tx_pkt_cb( enum vpp_matrix_csc_e csc_type, struct vframe_master_display_colour_s *p, int *hdmi_scs_type_changed, - struct hdr10plus_para *hdmitx_hdr10plus_param) + struct hdr10plus_para *hdmitx_hdr10plus_param, + enum vd_path_e vd_path) { struct vout_device_s *vdev = NULL; struct master_display_info_s send_info; @@ -6024,7 +6447,7 @@ static void hdr_tx_pkt_cb( /*hdr10 plus*/ (tx_hdr10_plus_support) || (signal_change_flag & SIG_HDR10_PLUS_MODE))) { - if (sdr_process_mode && + if (sdr_process_mode[vd_path] && (csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB)) { /* sdr source convert to hdr */ /* send hdr info */ @@ -6044,7 +6467,7 @@ static void hdr_tx_pkt_cb( vdev->fresh_tx_hdr_pkt(&send_info); } - if (cur_csc_type == + if (cur_csc_type[vd_path] == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) { if (vdev) { if (vdev->fresh_tx_hdr10plus_pkt) @@ -6057,8 +6480,8 @@ static void hdr_tx_pkt_cb( hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; *hdmi_scs_type_changed = 1; } - } else if ((hdr_process_mode == 0) && - (hlg_process_mode == 0) && + } else if ((hdr_process_mode[vd_path] == PROC_BYPASS) && + (hlg_process_mode[vd_path] == PROC_BYPASS) && (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) { /* source is hdr, send hdr info */ /* use the features to discribe source info */ @@ -6083,8 +6506,8 @@ static void hdr_tx_pkt_cb( hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; *hdmi_scs_type_changed = 1; } - } else if ((hdr_process_mode == 0) && - (hlg_process_mode == 1) && + } else if ((hdr_process_mode[vd_path] == PROC_BYPASS) && + (hlg_process_mode[vd_path] == PROC_MATCH) && (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) { /* source is hdr, send hdr info */ /* use the features to discribe source info */ @@ -6121,8 +6544,8 @@ static void hdr_tx_pkt_cb( hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; *hdmi_scs_type_changed = 1; } - } else if ((hdr_process_mode == 1) && - (hlg_process_mode == 0) && + } else if ((hdr_process_mode[vd_path] == PROC_MATCH) && + (hlg_process_mode[vd_path] == PROC_BYPASS) && (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) { /* source is hdr, send hdr info */ /* use the features to discribe source info */ @@ -6158,14 +6581,45 @@ static void hdr_tx_pkt_cb( hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB; *hdmi_scs_type_changed = 1; } - } else if ((hdr10_plus_process_mode == 0) && + } else if ((hdr10_plus_process_mode[vd_path] == 0) && (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)) { - /*source is hdr10 plus, send hdr10 plus info*/ + /* source is hdr10+, send hdr10 drm packet as well*/ + /* use the features to discribe source info */ + send_info.features = + (0 << 30) /*sdr output 709*/ + | (1 << 29) /*video available*/ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /*color available*/ + /* bt2020 */ + | (signal_color_primaries << 16) + | (16 << 8) /* Always HDR10 */ + | (10 << 0); /* bt2020c */ + amvecm_cp_hdr_info(&send_info, p); if (vdev) { - if (vdev->fresh_tx_hdr10plus_pkt) - vdev->fresh_tx_hdr10plus_pkt(1, - hdmitx_hdr10plus_param); + /* source is hdr10 plus, send hdr10 plus info */ + if (get_hdr10_plus_pkt_delay()) { + update_hdr10_plus_pkt(true, + hdmitx_hdr10plus_param, + &send_info); + } else { + /* send HDR10 DRM packet */ + if (vdev->fresh_tx_hdr_pkt) + vdev->fresh_tx_hdr_pkt( + &send_info); + /* send hdr10 plus info */ + if (vdev->fresh_tx_hdr10plus_pkt) + vdev->fresh_tx_hdr10plus_pkt(1, + hdmitx_hdr10plus_param); + } + } + if (hdmi_csc_type != + VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) { + hdmi_csc_type = + VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC; + *hdmi_scs_type_changed = 1; } + } else { /* sdr source send normal info*/ /* use the features to discribe source info */ @@ -6195,21 +6649,24 @@ static void hdr_tx_pkt_cb( | (1 << 8) /* bt709 */ | (1 << 0); /* bt709 */ amvecm_cp_hdr_info(&send_info, p); - if (cur_csc_type <= VPP_MATRIX_BT2020YUV_BT2020RGB) { + if (cur_csc_type[vd_path] <= + VPP_MATRIX_BT2020YUV_BT2020RGB) { if (vdev) { if (vdev->fresh_tx_hdr_pkt) vdev->fresh_tx_hdr_pkt( &send_info); } - } else if (cur_csc_type == + } else if (cur_csc_type[vd_path] == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) { if (vdev) { + if (vdev->fresh_tx_hdr_pkt) + vdev->fresh_tx_hdr_pkt( + &send_info); if (vdev->fresh_tx_hdr10plus_pkt) vdev->fresh_tx_hdr10plus_pkt(0, hdmitx_hdr10plus_param); } } - if (hdmi_csc_type != VPP_MATRIX_YUV709_RGB) { hdmi_csc_type = VPP_MATRIX_YUV709_RGB; *hdmi_scs_type_changed = 1; @@ -6223,14 +6680,15 @@ static void video_process( enum vpp_matrix_csc_e csc_type, int signal_change_flag, struct vinfo_s *vinfo, - struct vframe_master_display_colour_s *p) + struct vframe_master_display_colour_s *p, + enum vd_path_e vd_path) { int need_adjust_contrast_saturation = 0; /* decided by edid or panel info or user setting */ if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && - (hdr_process_mode == 1) && - (hlg_process_mode == 1)) { + (hdr_process_mode[vd_path] == PROC_MATCH) && + (hlg_process_mode[vd_path] == PROC_MATCH)) { /* hdr->sdr hlg->sdr */ if ((signal_change_flag & (SIG_CS_CHG | @@ -6240,22 +6698,27 @@ static void video_process( SIG_HDR_SUPPORT | SIG_HLG_MODE) ) || - (cur_csc_type < + (cur_csc_type[vd_path] < VPP_MATRIX_BT2020YUV_BT2020RGB)) { if (get_hdr_type() & HLG_FLAG) need_adjust_contrast_saturation = - hlg_process(csc_type, vinfo, p); + hlg_process(csc_type, vinfo, p, + vd_path); else need_adjust_contrast_saturation - = hdr_process(csc_type, vinfo, p); - pr_csc("hdr_process_mode = 0x%x\n" + = hdr_process( + csc_type, vinfo, p, vd_path); + pr_csc(1, "vd_path = %d\n" + "hdr_process_mode = 0x%x\n" "hlg_process_mode = 0x%x.\n", - hdr_process_mode, hlg_process_mode); + vd_path + 1, + hdr_process_mode[vd_path], + hlg_process_mode[vd_path]); } } else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && - (hdr_process_mode == 0) && - (hlg_process_mode == 1)) { - /* hdr->hdr hlg->hlg*/ + (hdr_process_mode[vd_path] == PROC_BYPASS) && + (hlg_process_mode[vd_path] == PROC_MATCH)) { + /* hdr->hdr hlg->hdr*/ if ((signal_change_flag & (SIG_CS_CHG | SIG_PRI_INFO | @@ -6264,18 +6727,22 @@ static void video_process( SIG_HDR_SUPPORT | SIG_HLG_MODE) ) || - (cur_csc_type < + (cur_csc_type[vd_path] < VPP_MATRIX_BT2020YUV_BT2020RGB)) { if (get_hdr_type() & HLG_FLAG) - hlg_hdr_process(csc_type, vinfo, p); + hlg_hdr_process(csc_type, vinfo, p, vd_path); else - bypass_hdr_process(csc_type, vinfo, p); - pr_csc("hdr_process_mode = 0x%x\n" - "hlg_process_mode = 0x%x.\n", - hdr_process_mode, hlg_process_mode); + bypass_hdr_process(csc_type, vinfo, p, vd_path); + pr_csc(1, "vd_path = %d\n" + "\thdr_process_mode = 0x%x\n" + "\thlg_process_mode = 0x%x.\n", + vd_path + 1, + hdr_process_mode[vd_path], + hlg_process_mode[vd_path]); } } else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && - (hdr_process_mode == 1) && (hlg_process_mode == 0)) { + (hdr_process_mode[vd_path] == PROC_MATCH) && + (hlg_process_mode[vd_path] == PROC_BYPASS)) { /* hdr->sdr hlg->hlg*/ if ((signal_change_flag & (SIG_CS_CHG | @@ -6285,19 +6752,25 @@ static void video_process( SIG_HDR_SUPPORT | SIG_HLG_MODE) ) || - (cur_csc_type < + (cur_csc_type[vd_path] < VPP_MATRIX_BT2020YUV_BT2020RGB)) { if (get_hdr_type() & HLG_FLAG) - bypass_hdr_process(csc_type, vinfo, p); + bypass_hdr_process(csc_type, vinfo, p, + vd_path); else need_adjust_contrast_saturation = - hdr_process(csc_type, vinfo, p); - pr_csc("hdr_process_mode = 0x%x\n" - "hlg_process_mode = 0x%x.\n", - hdr_process_mode, hlg_process_mode); + hdr_process(csc_type, vinfo, p, + vd_path); + pr_csc(1, "vd_path = %d\n" + "\thdr_process_mode = 0x%x\n" + "\thlg_process_mode = 0x%x.\n", + vd_path + 1, + hdr_process_mode[vd_path], + hlg_process_mode[vd_path]); } } else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && - (hdr_process_mode == 0) && (hlg_process_mode == 0)) { + (hdr_process_mode[vd_path] == PROC_BYPASS) && + (hlg_process_mode[vd_path] == PROC_BYPASS)) { /* hdr->hdr hlg->hlg*/ if ((signal_change_flag & (SIG_CS_CHG | @@ -6306,25 +6779,36 @@ static void video_process( SIG_HDR_MODE | SIG_HDR_SUPPORT | SIG_HLG_MODE)) || - (cur_csc_type < + (cur_csc_type[vd_path] < VPP_MATRIX_BT2020YUV_BT2020RGB)) { - bypass_hdr_process(csc_type, vinfo, p); - pr_csc("bypass_hdr_process: 0x%x, 0x%x.\n", - hdr_process_mode, hlg_process_mode); + bypass_hdr_process(csc_type, vinfo, p, + vd_path); + pr_csc(1, "vd_path = %d\n" + "bypass_hdr_process: 0x%x, 0x%x.\n", + vd_path + 1, + hdr_process_mode[vd_path], + hlg_process_mode[vd_path]); } - } else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) && - (hdr10_plus_process_mode == 1)) { + } else if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) { if ((signal_change_flag & SIG_HDR10_PLUS_MODE) || - (cur_csc_type != - VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)) - hdr_process(csc_type, vinfo, p); - /* hdr10_plus_process(vf); */ - pr_csc("hdr10_plus_process.\n"); + (cur_csc_type[vd_path] != + VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)) { + // TODO: hdr10_plus_process(vf, mode, vd_path); + if (hdr10_plus_process_mode[vd_path] == PROC_MATCH) { + hdr_process(csc_type, vinfo, p, vd_path); + /* hdr10_plus_process(vf); */ + } else { + bypass_hdr_process( + csc_type, vinfo, p, vd_path); + } + } + pr_csc(1, "vd_path = %d\nhdr10_plus_process.\n", + vd_path + 1); } else { if ((csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) && - sdr_process_mode) + sdr_process_mode[vd_path]) /* for gxl and gxm SDR to HDR process */ - sdr_hdr_process(csc_type, vinfo, p); + sdr_hdr_process(csc_type, vinfo, p, vd_path); else { /* for gxtvbb and gxl HDR bypass process */ if (((vinfo->hdr_info.hdr_support & @@ -6335,13 +6819,20 @@ static void video_process( VPP_MATRIX_BT2020YUV_BT2020RGB) && tx_op_color_primary) set_bt2020csc_process(csc_type, - vinfo, p); + vinfo, p, vd_path); else bypass_hdr_process(csc_type, - vinfo, p); - pr_csc("csc_type = 0x%x\n" - "sdr_process_mode = 0x%x.\n", - csc_type, sdr_process_mode); + vinfo, p, vd_path); + pr_csc(1, "vd_path = %d\n" + "\tcsc_type = 0x%x\n" + "\thdr_process_mode = %d.\n" + "\thlg_process_mode = %d.\n" + "\thdr10_plus_process_mode = %d.\n", + vd_path + 1, + csc_type, + hdr_process_mode[vd_path], + hlg_process_mode[vd_path], + hdr10_plus_process_mode[vd_path]); } } @@ -6353,20 +6844,35 @@ static void video_process( MATRIX_YUV709_RGB, MTX_ON); } - if (cur_hdr_process_mode != hdr_process_mode) { - cur_hdr_process_mode = hdr_process_mode; - pr_csc("hdr_process_mode changed to %d", - hdr_process_mode); + if (cur_hdr_process_mode[vd_path] != + hdr_process_mode[vd_path]) { + cur_hdr_process_mode[vd_path] = + hdr_process_mode[vd_path]; + pr_csc(1, "vd_path = %d\n" + "hdr_process_mode changed to %d\n", + vd_path + 1, hdr_process_mode[vd_path]); } - if (cur_sdr_process_mode != sdr_process_mode) { - cur_sdr_process_mode = sdr_process_mode; - pr_csc("sdr_process_mode changed to %d", - sdr_process_mode); + if (cur_sdr_process_mode[vd_path] != + sdr_process_mode[vd_path]) { + cur_sdr_process_mode[vd_path] = + sdr_process_mode[vd_path]; + pr_csc(1, "vd_path = %d\nsdr_process_mode changed to %d\n", + vd_path + 1, sdr_process_mode[vd_path]); } - if (cur_hlg_process_mode != hlg_process_mode) { - cur_hlg_process_mode = hlg_process_mode; - pr_csc("hlg_process_mode changed to %d", - hlg_process_mode); + if (cur_hlg_process_mode[vd_path] != + hlg_process_mode[vd_path]) { + cur_hlg_process_mode[vd_path] = + hlg_process_mode[vd_path]; + pr_csc(1, "vd_path = %d\nhlg_process_mode changed to %d\n", + vd_path + 1, hlg_process_mode[vd_path]); + } + if (cur_hdr10_plus_process_mode[vd_path] != + hdr10_plus_process_mode[vd_path]) { + cur_hdr10_plus_process_mode[vd_path] = + hdr10_plus_process_mode[vd_path]; + pr_csc(1, "vd_path = %d\n" + "hdr10_plus_process_mode changed to %d\n", + vd_path + 1, hdr10_plus_process_mode[vd_path]); } if (need_adjust_contrast_saturation & 1) { if (lut_289_en && @@ -6385,31 +6891,34 @@ static void video_process( } else { if (((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)) && - (sdr_process_mode == 1)) + (sdr_process_mode[vd_path] == PROC_SDR_TO_HDR)) saturation_offset = sdr_saturation_offset; else saturation_offset = 0; vecm_latch_flag |= FLAG_VADJ1_COLOR; } - if (cur_csc_type != csc_type) { - pr_csc("CSC from 0x%x to 0x%x.\n", - cur_csc_type, csc_type); - pr_csc("contrast offset = %d.\n", - vd1_contrast_offset); - pr_csc("saturation offset = %d.\n", - saturation_offset); - cur_csc_type = csc_type; + if (cur_csc_type[vd_path] != csc_type) { + pr_csc(1, "vd_path = %d\n" + "\tcsc from 0x%x to 0x%x.\n" + "contrast offset = %d.\n" + "saturation offset = %d.\n", + vd_path + 1, cur_csc_type[vd_path], csc_type, + vd1_contrast_offset, saturation_offset); + cur_csc_type[vd_path] = csc_type; + } } static int vpp_matrix_update( - struct vframe_s *vf, struct vinfo_s *vinfo, int flags) + struct vframe_s *vf, struct vinfo_s *vinfo, int flags, + enum vd_path_e vd_path) { enum vpp_matrix_csc_e csc_type = VPP_MATRIX_NULL; int signal_change_flag = 0; - struct vframe_master_display_colour_s *p = &cur_master_display_colour; + struct vframe_master_display_colour_s *p = + &cur_master_display_colour[vd_path]; int hdmi_scs_type_changed = 0; - struct hdr10plus_para hdmitx_hdr10plus_param; + bool hdr10p_meta_updated = false; if (vinfo == NULL) return 0; @@ -6418,25 +6927,78 @@ static int vpp_matrix_update( memcpy(&receiver_hdr_info, &vinfo->hdr_info, sizeof(struct hdr_info)); - hdr_support_process(vinfo); + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) || + (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)) + hdr_support_process(vinfo, vd_path); if (vf && vinfo) - signal_change_flag = signal_type_changed(vf, vinfo); + signal_change_flag = + signal_type_changed(vf, vinfo, vd_path); + get_cur_vd_signal_type(vd_path); if (force_csc_type != 0xff) csc_type = force_csc_type; else csc_type = get_csc_type(); - hdr10_plus_metadata_update(vf, csc_type, - &hdmitx_hdr10plus_param); - hdr_tx_pkt_cb(vinfo, - signal_change_flag, - csc_type, - p, - &hdmi_scs_type_changed, - &hdmitx_hdr10plus_param); + if (video_process_status[vd_path] == HDR_MODULE_BYPASS) { + if (is_video_layer_on(vd_path) && + (!is_dolby_vision_on() || (vd_path == VD2_PATH))) + video_process_status[vd_path] = HDR_MODULE_ON; + else + return 2; + } + + if (is_dolby_vision_on() && (vd_path == VD1_PATH)) + return 0; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && + (get_cpu_type() != MESON_CPU_MAJOR_ID_TL1)) { + enum hdr_type_e source_format[VD_PATH_MAX]; + enum vd_path_e oth_path = + (vd_path == VD1_PATH) ? VD2_PATH : VD1_PATH; + + 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) { + if (!is_video_layer_on(vd_path)) + video_layer_wait_on[vd_path] = true; + video_process_flags[oth_path] |= + PROC_FLAG_FORCE_PROCESS; + return 1; + } + } + + if ((vf != NULL) && (flags & CSC_FLAG_TOGGLE_FRAME)) { + hdr10_plus_metadata_update(vf, csc_type, + &hdmitx_hdr10plus_params[vd_path]); + hdr10p_meta_updated = true; + } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if ((vd_path == VD1_PATH) + || ((vd_path == VD2_PATH) + && !is_video_layer_on(VD1_PATH) + && is_video_layer_on(VD2_PATH))) + hdmi_packet_process(signal_change_flag, vinfo, p, + hdr10p_meta_updated ? + &hdmitx_hdr10plus_params[vd_path] : NULL, + vd_path); + } else { + if ((vd_path == VD1_PATH) + || ((vd_path == VD2_PATH) && !is_video_layer_on(VD1_PATH))) + hdr_tx_pkt_cb(vinfo, + signal_change_flag, + csc_type, + p, + &hdmi_scs_type_changed, + &hdmitx_hdr10plus_params[vd_path], + vd_path); + } if (hdmi_scs_type_changed && (flags & CSC_FLAG_CHECK_OUTPUT) && @@ -6447,38 +7009,47 @@ static int vpp_matrix_update( && ((flags & CSC_FLAG_TOGGLE_FRAME) == 0)) return 0; - if ((cur_csc_type != csc_type) + if ((cur_csc_type[vd_path] != csc_type) || (signal_change_flag & (SIG_CS_CHG | SIG_PRI_INFO | SIG_KNEE_FACTOR | SIG_HDR_MODE | SIG_HDR_SUPPORT | SIG_HLG_MODE | SIG_OP_CHG | - SIG_SRC_OUTPUT_CHG | SIG_HDR10_PLUS_MODE))) - video_process(vf, csc_type, signal_change_flag, vinfo, p); + SIG_SRC_OUTPUT_CHG | SIG_HDR10_PLUS_MODE | + SIG_SRC_CHG))) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && + (get_cpu_type() != MESON_CPU_MAJOR_ID_TL1)) + video_post_process(csc_type, vinfo, vd_path); + else + video_process(vf, csc_type, signal_change_flag, + vinfo, p, vd_path); + } /* eye protection mode */ if (signal_change_flag & SIG_WB_CHG) - vpp_eye_protection_process(csc_type, vinfo); + vpp_eye_protection_process(csc_type, vinfo, vd_path); return 0; } -static struct vframe_s *last_vf; -static int last_vf_signal_type; -static int null_vf_cnt; +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 prev_output_mode; +static int prev_color_fmt; static unsigned int fg_vf_sw_dbg; -unsigned int null_vf_max = 1; +unsigned int null_vf_max = 2; module_param(null_vf_max, uint, 0664); MODULE_PARM_DESC(null_vf_max, "\n null_vf_max\n"); int amvecm_matrix_process( - struct vframe_s *vf, struct vframe_s *vf_rpt, int flags) + struct vframe_s *vf, struct vframe_s *vf_rpt, int flags, + enum vd_path_e vd_path) { struct vframe_s fake_vframe; struct vinfo_s *vinfo = get_current_vinfo(); int toggle_frame; int i; + int ret; if ((get_cpu_type() < MESON_CPU_MAJOR_ID_GXTVBB) || is_meson_gxl_package_905M2() || (csc_en == 0)) @@ -6500,86 +7071,165 @@ int amvecm_matrix_process( CSC_ON); } - if (is_dolby_vision_on()) - return 0; + 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 (flags & CSC_FLAG_CHECK_OUTPUT) { - if (vpp_matrix_update(vf, vinfo, flags) == 1) { - pr_csc("hdr/sdr output changing ...\n"); + if ((vf != NULL) && (flags & CSC_FLAG_CHECK_OUTPUT)) { + ret = vpp_matrix_update(vf, vinfo, flags, vd_path); + if (ret == 1) { + pr_csc(2, "vd%d: hold frame when output changing\n", + vd_path + 1); return 1; + } else if (ret == 2) { + pr_csc(2, "vd%d: hold frame when video off\n", + vd_path + 1); + return 2; } - } - if (vf != NULL) { - if (debug_csc & 2) - pr_csc("new frame %x%s\n", - vf->signal_type, - get_video_enabled() ? " " : ", video off"); - vpp_matrix_update(vf, vinfo, flags); - last_vf = vf; - last_vf_signal_type = vf->signal_type; - null_vf_cnt = 0; + } else if ((vf != NULL) && (flags & CSC_FLAG_TOGGLE_FRAME)) { + if (is_video_layer_on(vd_path) || + video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) { + video_process_status[vd_path] = HDR_MODULE_ON; + vpp_matrix_update(vf, vinfo, flags, vd_path); + video_process_flags[vd_path] &= + ~PROC_FLAG_FORCE_PROCESS; + last_vf[vd_path] = vf; + 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", + vd_path + 1, + vf, vf->signal_type); + } else + pr_csc(2, "vd%d: skip process frame(%p) %x\n", + vd_path + 1, + vf, vf->signal_type); fg_vf_sw_dbg = 1; /* debug vframe info backup */ dbg_vf = vf; - } else if (vf_rpt != NULL) { - if (debug_csc & 2) - pr_csc("rpt frame\n"); - null_vf_cnt = 0; + } else if ((vf_rpt != NULL) && is_video_layer_on(vd_path)) { + if (video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) { + 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(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 (get_video_enabled() && (last_vf != NULL)) { - if (debug_csc & 2) - pr_csc("rpt frame local\n"); - null_vf_cnt = 0; + } 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); + null_vf_cnt[vd_path] = 0; fg_vf_sw_dbg = 3; } else { /* handle change between TV support/not support HDR */ if (prev_hdr_support != vinfo->hdr_info.hdr_support) { - null_vf_cnt = 0; + if ((vd_path == VD1_PATH) || + ((vd_path == VD2_PATH) && + is_video_layer_on(VD2_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); } /* handle change between output mode*/ - if (prev_output_mode != vinfo->viu_color_fmt) { - null_vf_cnt = 0; - prev_output_mode = vinfo->viu_color_fmt; + if (prev_color_fmt != vinfo->viu_color_fmt) { + if ((vd_path == VD1_PATH) || + ((vd_path == VD2_PATH) && + is_video_layer_on(VD2_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); } /* handle eye protect mode */ - if (cur_eye_protect_mode != wb_val[0]) - null_vf_cnt = 0; - if (csc_en & 0x10) + if ((cur_eye_protect_mode != wb_val[0]) + && (vd_path == VD1_PATH)) { + null_vf_cnt[vd_path] = 0; + pr_csc(2, "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; - /* when sdr mode change */ - if ((vinfo->hdr_info.hdr_support & 0x4) && + + /* 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 (((sdr_process_mode != 1) && (sdr_mode > 0)) - || ((sdr_process_mode > 0) && (sdr_mode == 0))) - null_vf_cnt = toggle_frame; - if ((null_vf_cnt == 0) || (null_vf_cnt == toggle_frame)) { - pr_csc("Fake SDR frame\n"); - /*send a faked vframe to switch matrix*/ - /*from 2020 to 601 when video disabled */ - fake_vframe.source_type = VFRAME_SOURCE_TYPE_OTHERS; - fake_vframe.signal_type = 0; - fake_vframe.width = 1920; - fake_vframe.height = 1080; - fake_vframe.prop.master_display_colour.present_flag - = 0x80000000; - if (null_vf_cnt == toggle_frame) - vpp_matrix_update( - &fake_vframe, vinfo, - CSC_FLAG_TOGGLE_FRAME); - else if (null_vf_cnt == 0) - vpp_matrix_update( - &fake_vframe, vinfo, - CSC_FLAG_CHECK_OUTPUT); - last_vf = NULL; + (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; + cur_sdr_mode = sdr_mode; + pr_csc(2, "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; + } + + 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 */ + fake_vframe.source_type = + VFRAME_SOURCE_TYPE_OTHERS; + fake_vframe.signal_type = 0; + fake_vframe.width = 1920; + fake_vframe.height = 1080; + 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); + } + 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 <= null_vf_max) - null_vf_cnt++; + if (null_vf_cnt[vd_path] <= null_vf_max) + null_vf_cnt[vd_path]++; } return 0; } @@ -6701,27 +7351,27 @@ hdr_dump: pr_err("customer_master_display_en:0x%x\n", customer_master_display_en); pr_err("hdr_mode:0x%x, hdr_process_mode:0x%x, cur_hdr_process_mode:0x%x\n", - hdr_mode, hdr_process_mode, cur_hdr_process_mode); + hdr_mode, hdr_process_mode[0], cur_hdr_process_mode[0]); pr_err("hlg_process_mode: 0x%x :0->hlg->hlg,1->hlg->sdr,2->hlg->hdr10\n", - hlg_process_mode); + hlg_process_mode[0]); pr_err("sdr_mode:0x%x, sdr_process_mode:0x%x, cur_sdr_process_mode:0x%x\n", - sdr_mode, sdr_process_mode, cur_sdr_process_mode); + sdr_mode, sdr_process_mode[0], cur_sdr_process_mode[0]); pr_err("hdr_flag:0x%x, fg_vf_sw_dbg:0x%x\n", hdr_flag, fg_vf_sw_dbg); pr_err("cur_signal_type:0x%x, cur_csc_mode:0x%x, cur_csc_type:0x%x\n", - cur_signal_type, cur_csc_mode, cur_csc_type); + cur_signal_type[0], cur_csc_mode, cur_csc_type[0]); pr_err("knee_lut_on:0x%x,knee_interpolation_mode:0x%x,cur_knee_factor:0x%x\n", knee_lut_on, knee_interpolation_mode, cur_knee_factor); pr_err("tx_hdr10_plus_support = 0x%x\n", tx_hdr10_plus_support); - pr_err("hdr10_plus_process_mode = 0x%x\n", hdr10_plus_process_mode); + pr_err("hdr10_plus_process_mode = 0x%x\n", hdr10_plus_process_mode[0]); //if (signal_transfer_characteristic == 0x30) - if (cur_csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) + if (cur_csc_type[0] == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) hdr10_plus_debug(); if ((receiver_hdr_info.hdr_support & 0xc) == 0) diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.h b/drivers/amlogic/media/enhancement/amvecm/amcsc.h index b0ccbc0..3839fdf 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.h +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.h @@ -18,6 +18,13 @@ #ifndef AM_CSC_H #define AM_CSC_H +extern uint debug_csc; +#define pr_csc(lvl, fmt, args...)\ + do {\ + if (debug_csc & lvl)\ + pr_info(fmt, ## args);\ + } while (0) + /* white balance value */ extern void ve_ogo_param_update(void); extern struct tcon_rgb_ogo_s video_rgb_ogo; @@ -75,6 +82,16 @@ enum mtx_en_e { OSD1_MTX_EN }; +enum output_format_e { + UNKNOWN_FMT = 0, + BT709, + BT2020, + BT2020_PQ, + BT2020_PQ_DYNAMIC, + BT2020_HLG, + BT2100_IPT +}; + #define POST_MTX_EN_MASK (1 << POST_MTX_EN) #define VD2_MTX_EN_MASK (1 << VD2_MTX_EN) #define VD1_MTX_EN_MASK (1 << VD1_MTX_EN) @@ -84,6 +101,21 @@ enum mtx_en_e { #define HDR_SUPPORT (1 << 2) #define HLG_SUPPORT (1 << 3) +#define SIG_CS_CHG 0x01 +#define SIG_SRC_CHG 0x02 +#define SIG_PRI_INFO 0x04 +#define SIG_KNEE_FACTOR 0x08 +#define SIG_HDR_MODE 0x10 +#define SIG_HDR_SUPPORT 0x20 +#define SIG_WB_CHG 0x40 +#define SIG_HLG_MODE 0x80 +#define SIG_HLG_SUPPORT 0x100 +#define SIG_OP_CHG 0x200 +#define SIG_SRC_OUTPUT_CHG 0x400/*for box*/ +#define SIG_HDR10_PLUS_MODE 0x800 +#define SIG_COLORIMETRY_SUPPORT 0x1000 +#define SIG_OUTPUT_MODE_CHG 0x2000 + #define LUT_289_SIZE 289 extern unsigned int lut_289_mapping[LUT_289_SIZE]; extern int dnlp_en; @@ -97,15 +129,36 @@ extern uint hdr_flag; extern int video_rgb_ogo_xvy_mtx_latch; extern int video_rgb_ogo_xvy_mtx; extern int tx_op_color_primary; -extern uint cur_csc_type; +extern uint cur_csc_type[VD_PATH_MAX]; + +/* 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]; + +/* 0: bypass, 1:hdr10p->hdr, 2:hdr10p->sdr, 3:hdr10p->hlg */ +extern uint hdr10_plus_process_mode[VD_PATH_MAX]; +extern uint cur_hdr10_plus_process_mode[VD_PATH_MAX]; + +/* 0: hlg->hlg, 1:hlg->sdr 2:hlg->hdr*/ +extern uint hlg_process_mode[VD_PATH_MAX]; +extern uint cur_hlg_process_mode[VD_PATH_MAX]; + +/* 0: sdr->sdr, 1:sdr->hdr, 2:sdr->hlg */ +extern uint sdr_process_mode[VD_PATH_MAX]; +extern uint cur_sdr_process_mode[VD_PATH_MAX]; +/* 0: tx don't support hdr10+, 1: tx support hdr10+*/ +extern uint tx_hdr10_plus_support; extern int amvecm_matrix_process( - struct vframe_s *vf, struct vframe_s *vf_rpt, int flags); + struct vframe_s *vf, struct vframe_s *vf_rpt, int flags, + enum vd_path_e vd_path); extern int amvecm_hdr_dbg(u32 sel); extern u32 get_video_enabled(void); +extern u32 get_videopip_enabled(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); /*hdr*/ /*#define DBG_BUF_SIZE (1024)*/ @@ -125,6 +178,44 @@ struct hdr_data_t { extern void hdr_init(struct hdr_data_t *phdr_data); 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); +extern bool is_video_layer_on(enum vd_path_e vd_path); + +#define HDR_MODULE_OFF 0 +#define HDR_MODULE_ON 1 +#define HDR_MODULE_BYPASS 2 +extern void set_hdr_module_status(enum vd_path_e vd_path, int status); +extern int get_hdr_module_status(enum vd_path_e vd_path); +extern int get_primaries_type(struct vframe_master_display_colour_s *p_mdc); + +#define PROC_BYPASS 0 +/* to backward compatible */ +#define PROC_MATCH 1 +#define PROC_OFF 4 +/* sdr */ +#define PROC_SDR_TO_HDR 1 +#define PROC_SDR_TO_HLG 2 +/* hdr */ +#define PROC_HDR_TO_SDR 1 +#define PROC_HDR_TO_HLG 2 +/* hlg */ +#define PROC_HLG_TO_SDR 1 +#define PROC_HLG_TO_HDR 2 +/* hdr+ */ +#define PROC_HDRP_TO_HDR 1 +#define PROC_HDRP_TO_SDR 2 +#define PROC_HDRP_TO_HLG 3 + +extern uint get_hdr10_plus_pkt_delay(void); +extern void update_hdr10_plus_pkt(bool enable, + void *hdr10plus_params, + void *send_info); +extern void send_hdr10_plus_pkt(enum vd_path_e vd_path); + +#define HDRPLUS_PKT_UPDATE 2 +#define HDRPLUS_PKT_REPEAT 1 +#define HDRPLUS_PKT_IDLE 0 #endif /* AM_CSC_H */ diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c new file mode 100644 index 0000000..2e8162d --- /dev/null +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c @@ -0,0 +1,929 @@ +/* + * drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include "amcsc.h" +#include "set_hdr2_v0.h" +#include "hdr/am_hdr10_plus.h" + +/* 0: follow sink, 1: follow source */ +static uint hdr_policy; +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; + +static const char *module_str[7] = { + "UNKNOWN", + "VD1", + "VD2", + "OSD1", + "VDIN0", + "VDIN1", + "DI" +}; + +static const char *process_str[15] = { + "UNKNOWN", + "HDR_BYPASS", + "HDR_SDR", + "SDR_HDR", + "HLG_BYPASS", + "HLG_SDR", + "HLG_HDR", + "SDR_HLG", + "SDR_IPT", + "HDR_IPT", + "HLG_IPT", + "HDR_HLG", + "RGB_YUV", + "RGB_HDR", + "RGB_HLG" +}; + +static const char *policy_str[3] = { + "follow_sink", + "follow_source", + "force_output" +}; + +static const char *input_str[7] = { + "NONE", + "HDR", + "HDR+", + "DOVI", + "PRIME", + "HLG", + "SDR" +}; + +/* output_format_e */ +static const char *output_str[7] = { + "UNKNOWN", + "709", + "2020", + "HDR", + "HDR+", + "HLG", + "IPT" +}; + +static const char *dv_output_str[6] = { + "IPT", + "TUNNEL", + "HDR10", + "SDR10", + "SDR8", + "BYPASS" +}; + +void hdr_proc( + enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct vinfo_s *vinfo) +{ + enum hdr_process_sel cur_hdr_process; + + cur_hdr_process = hdr_func( + module_sel, hdr_process_select, vinfo); + if (cur_hdr_process != hdr_process_select) + pr_csc(8, "am_vecm: module=%s, process=%s(%s)\n", + module_str[module_sel], + process_str[hdr_process_select], + process_str[cur_hdr_process]); + else + pr_csc(8, "am_vecm: hdr module=%s, process=%s\n", + module_str[module_sel], + process_str[hdr_process_select]); +} + +int hdr_policy_process( + struct vinfo_s *vinfo, + enum hdr_type_e *source_format, + enum vd_path_e vd_path) +{ + int change_flag = 0; + enum vd_path_e oth_path = + (vd_path == VD1_PATH) ? VD2_PATH : VD1_PATH; + int dv_policy = 0; + int dv_mode = 0; + bool hdr10_plus_support = + (vinfo->hdr_info.hdr10plus_info.ieeeoui + == HDR_PLUS_IEEE_OUI) && + (vinfo->hdr_info.hdr10plus_info.application_version + == 1); + + tx_hdr10_plus_support = hdr10_plus_support; + + cur_hdr_policy = 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; + } + } + + if ((get_hdr_module_status(vd_path) != HDR_MODULE_ON) + && is_dolby_vision_enable()) { + 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)) { + /* 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) { + /* vd1 bypass hdr+ when vd2 off */ + hdr10_plus_process_mode[vd_path] = PROC_BYPASS; + target_format[vd_path] = BT2020_PQ_DYNAMIC; + } else if (is_dolby_vision_on() && (vd_path == VD2_PATH)) { + /* vd2 *->ipt when vd1 dolby on */ + hdr_process_mode[vd_path] = PROC_MATCH; + hlg_process_mode[vd_path] = PROC_MATCH; + 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)) { + /* vd1 on and vd2 follow vd1 output */ + if (target_format[VD1_PATH] == BT2020_HLG) { + /* vd2 *->hlg when vd1 output hlg */ + sdr_process_mode[vd_path] = PROC_SDR_TO_HLG; + hdr_process_mode[vd_path] = PROC_HDR_TO_HLG; + hlg_process_mode[vd_path] = PROC_BYPASS; + hdr10_plus_process_mode[vd_path] = + 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)) { + /* vd2 *->hdr when vd1 output hdr/hdr+ */ + sdr_process_mode[vd_path] = PROC_SDR_TO_HDR; + hdr_process_mode[vd_path] = PROC_BYPASS; + hlg_process_mode[vd_path] = PROC_HLG_TO_HDR; + hdr10_plus_process_mode[vd_path] = + PROC_HDRP_TO_HDR; + target_format[vd_path] = BT2020_PQ; + } else { + /* vd2 *->sdr when vd1 output sdr */ + sdr_process_mode[vd_path] = PROC_BYPASS; + hdr_process_mode[vd_path] = PROC_HDR_TO_SDR; + hlg_process_mode[vd_path] = PROC_HLG_TO_SDR; + hdr10_plus_process_mode[vd_path] = + PROC_HDRP_TO_SDR; + if ((target_format[VD1_PATH] == BT2020) && + (source_format[vd_path] == HDRTYPE_HLG)) + target_format[vd_path] = BT2020; + 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)))) { + /* *->hdr */ + sdr_process_mode[vd_path] = PROC_SDR_TO_HDR; + hdr_process_mode[vd_path] = PROC_BYPASS; + hlg_process_mode[vd_path] = PROC_HLG_TO_HDR; + hdr10_plus_process_mode[vd_path] = + PROC_HDRP_TO_HDR; + target_format[vd_path] = BT2020_PQ; + } else { + /* *->sdr */ + sdr_process_mode[vd_path] = PROC_BYPASS; + hdr_process_mode[vd_path] = PROC_HDR_TO_SDR; + hlg_process_mode[vd_path] = PROC_HLG_TO_SDR; + hdr10_plus_process_mode[vd_path] = + PROC_HDRP_TO_SDR; +#if 0 + if ((vinfo->hdr_info.colorimetry_support + & SINK_SUPPORTS_BT2020) && + (source_format[vd_path] == HDRTYPE_HLG) && + !is_video_layer_on(oth_path)) + target_format[vd_path] = BT2020; + else + target_format[vd_path] = BT709; +#else + target_format[vd_path] = BT709; +#endif + } + } else if (cur_hdr_policy == 1) { + 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))) { + /* VD1(with/without VD2) */ + /* or VD2(without VD1) <= should switch to VD1 */ + switch (source_format[vd_path]) { + case HDRTYPE_SDR: + if (is_video_layer_on(oth_path)) { + 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 output hlg */ + /* 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; + } + } else { + /* sdr->sdr */ + sdr_process_mode[vd_path] = + PROC_BYPASS; + target_format[vd_path] = BT709; + } + break; + case HDRTYPE_HLG: + /* source HLG */ + if (is_video_layer_on(oth_path) + && ((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 (vinfo->hdr_info.hdr_support + & HLG_SUPPORT) { + /* hlg->hlg */ + hlg_process_mode[vd_path] = + PROC_BYPASS; + target_format[vd_path] = + BT2020_HLG; + } else if ((vinfo->hdr_info.hdr_support + & HDR_SUPPORT) && (hdr_flag & 0x10)) { + /* hlg->hdr */ + hlg_process_mode[vd_path] = + PROC_HLG_TO_HDR; + target_format[vd_path] = + BT2020_PQ; + } else { + /* hlg->sdr */ + hlg_process_mode[vd_path] = + PROC_HLG_TO_SDR; +#if 0 + if ((vinfo->hdr_info.colorimetry_support + & SINK_SUPPORTS_BT2020) && + !is_video_layer_on(oth_path)) + target_format[vd_path] = + BT2020; + else + target_format[vd_path] = + BT709; +#else + target_format[vd_path] = BT709; +#endif + } + break; + case HDRTYPE_HDR10: + /* source HDR10 */ + if (vinfo->hdr_info.hdr_support & HDR_SUPPORT) { + /* hdr bypass */ + hdr_process_mode[vd_path] = + PROC_BYPASS; + target_format[vd_path] = + BT2020_PQ; + } else if (vinfo->hdr_info.hdr_support + & HLG_SUPPORT) { + /* 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: + /* source HDR10+ */ + if (hdr10_plus_support + && !is_video_layer_on(oth_path)) { + /* hdr+ bypass */ + hdr10_plus_process_mode[vd_path] = + PROC_BYPASS; + target_format[vd_path] = + BT2020_PQ_DYNAMIC; + } else if (vinfo->hdr_info.hdr_support + & HDR_SUPPORT) { + /* hdr+->hdr */ + hdr10_plus_process_mode[vd_path] = + PROC_HDRP_TO_HDR; + target_format[vd_path] = BT2020_PQ; + } else if (vinfo->hdr_info.hdr_support + & HLG_SUPPORT) { + /* hdr+->hlg */ + hdr10_plus_process_mode[vd_path] = + PROC_HDRP_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; + } + } else { + /* VD2 with VD1 */ + 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; + } + } + } + } 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; + } + + /* update change flags */ + if (is_dolby_vision_on() + && (vd_path == VD1_PATH)) { + 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()], + dv_output_str[dv_mode]); + } else { + if (cur_hdr10_plus_process_mode[vd_path] + != hdr10_plus_process_mode[vd_path]) + change_flag |= SIG_HDR_MODE; + if (cur_hdr_process_mode[vd_path] + != hdr_process_mode[vd_path]) + change_flag |= SIG_HDR_MODE; + if (cur_hlg_process_mode[vd_path] + != hlg_process_mode[vd_path]) + change_flag |= SIG_HLG_MODE; + if (cur_sdr_process_mode[vd_path] + != sdr_process_mode[vd_path]) + change_flag |= SIG_HDR_MODE; + if (cur_source_format[vd_path] + != source_format[vd_path]) + change_flag |= SIG_SRC_CHG; + if (change_flag) + pr_csc(4, "am_vecm: vd%d: (%s) %s->%s (%s).\n", + vd_path + 1, + policy_str[cur_hdr_policy], + input_str[source_format[vd_path]], + output_str[target_format[vd_path]], + is_dolby_vision_on() ? + dv_output_str[dv_mode] : + output_str[output_format]); + } + 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)) { + 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])) { + pr_csc(4, "am_vecm: vd%d output mode not match %s %s.\n", + vd_path + 1, + output_str[target_format[vd_path]], + output_str[target_format[oth_path]]); + change_flag |= SIG_OUTPUT_MODE_CHG; + } + if (change_flag & SIG_OUTPUT_MODE_CHG) { + /* need change video process for another path */ + switch (cur_source_format[oth_path]) { + case HDRTYPE_HDR10PLUS: + cur_hdr10_plus_process_mode[oth_path] = + PROC_OFF; + break; + case HDRTYPE_HDR10: + cur_hdr_process_mode[oth_path] = PROC_OFF; + break; + case HDRTYPE_HLG: + cur_hlg_process_mode[oth_path] = PROC_OFF; + break; + case HDRTYPE_SDR: + cur_sdr_process_mode[oth_path] = PROC_OFF; + break; + default: + break; + } + } + return change_flag; +} + +static void prepare_hdr_info( + struct master_display_info_s *hdr_data, + struct vframe_master_display_colour_s *p) +{ + memset(hdr_data->primaries, 0, sizeof(hdr_data->primaries)); + if ((p->present_flag & 1) + && (((hdr_data->features >> 16) & 0xff) == 9)) { + memcpy(hdr_data->primaries, + p->primaries, + sizeof(u32)*6); + memcpy(hdr_data->white_point, + p->white_point, + sizeof(u32)*2); + hdr_data->luminance[0] = + p->luminance[0]; + hdr_data->luminance[1] = + p->luminance[1]; + if (p->content_light_level.present_flag == 1) { + hdr_data->max_content = + p->content_light_level.max_content; + hdr_data->max_frame_average = + p->content_light_level.max_pic_average; + } else { + hdr_data->max_content = 0; + hdr_data->max_frame_average = 0; + } + hdr_data->luminance[0] = hdr_data->luminance[0] / 10000; + hdr_data->present_flag = 1; + } +} + +void hdmi_packet_process( + int signal_change_flag, + struct vinfo_s *vinfo, + struct vframe_master_display_colour_s *p, + struct hdr10plus_para *hdmitx_hdr10plus_param, + enum vd_path_e vd_path) +{ + struct vout_device_s *vdev = NULL; + struct master_display_info_s send_info; + enum output_format_e cur_output_format = output_format; + + if (!vinfo) + return; + if (!vinfo->vout_device) { + pr_info("vinfo->vout_device is null, return\n"); + return; + } + vdev = vinfo->vout_device; + if (!vdev->fresh_tx_hdr_pkt) { + pr_info("vdev->fresh_tx_hdr_pkt is null, return\n"); + /* continue */ + } + + if ((target_format[vd_path] == cur_output_format) + && (cur_output_format != BT2020_PQ_DYNAMIC) + && ((cur_output_format == BT2020_PQ) && + !(signal_change_flag & SIG_PRI_INFO))) + return; + + /* clean hdr10plus packet when switch to others */ + if ((target_format[vd_path] != BT2020_PQ_DYNAMIC) + && (cur_output_format == BT2020_PQ_DYNAMIC)) { + if (get_hdr10_plus_pkt_delay()) { + update_hdr10_plus_pkt(false, + (void *)NULL, + (void *)NULL); + } else if (vdev->fresh_tx_hdr10plus_pkt) + vdev->fresh_tx_hdr10plus_pkt(0, + hdmitx_hdr10plus_param); + pr_csc(4, "am_vecm: vd%d hdmi clean hdr10+ pkt\n", + vd_path + 1); + } + + if (output_format != target_format[vd_path]) { + pr_csc(4, + "am_vecm: vd%d %s %s, vd2 %s %s, output_format %s => %s\n", + vd_path + 1, + is_video_layer_on(VD1_PATH) ? "on" : "off", + output_str[target_format[VD1_PATH]], + is_video_layer_on(VD2_PATH) ? "on" : "off", + output_str[target_format[VD2_PATH]], + output_str[cur_output_format], + output_str[target_format[vd_path]]); + output_format = target_format[vd_path]; + } + + switch (output_format) { + case BT709: + send_info.features = + /* default 709 limit */ + (0 << 30) /*sdr output 709*/ + | (1 << 29) /*video available*/ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /*color available*/ + | (1 << 16) /* bt709 */ + | (1 << 8) /* bt709 */ + | (1 << 0); /* bt709 */ + break; + case BT2020: + send_info.features = + /* default 709 full */ + (1 << 30) /*sdr output 709*/ + | (1 << 29) /*video available*/ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /*color available*/ + | (9 << 16) /* 2020 */ + | (1 << 8) /* bt709 */ + | (10 << 0); + break; + case BT2020_PQ: + send_info.features = + (0 << 30) /*sdr output 709*/ + | (1 << 29) /*video available*/ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /*color available*/ + | (9 << 16) + | (16 << 8) + | (10 << 0); /* bt2020c */ + break; + case BT2020_HLG: + send_info.features = + (0 << 30) /*sdr output 709*/ + | (1 << 29) /*video available*/ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /*color available*/ + | (9 << 16) + | (18 << 8) + | (10 << 0); + break; + case BT2020_PQ_DYNAMIC: + send_info.features = + (0 << 30) /*sdr output 709*/ + | (1 << 29) /*video available*/ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /*color available*/ + | (9 << 16) + | (16 << 8) /* Always HDR10 */ + | (10 << 0); /* bt2020c */ + break; + case UNKNOWN_FMT: + case BT2100_IPT: + /* handle by dolby vision */ + return; + } + + /* drm */ + prepare_hdr_info(&send_info, p); + + /* hdr10+ */ + if ((output_format == BT2020_PQ_DYNAMIC) + && hdmitx_hdr10plus_param) { + if (get_hdr10_plus_pkt_delay()) { + update_hdr10_plus_pkt(true, + (void *)hdmitx_hdr10plus_param, + (void *)&send_info); + } else { + if (vdev->fresh_tx_hdr_pkt) + vdev->fresh_tx_hdr_pkt(&send_info); + if (vdev->fresh_tx_hdr10plus_pkt) + vdev->fresh_tx_hdr10plus_pkt( + 1, hdmitx_hdr10plus_param); + } + return; + } + /* none hdr+ */ + if (vdev->fresh_tx_hdr_pkt) + vdev->fresh_tx_hdr_pkt(&send_info); +} + +void video_post_process( + enum vpp_matrix_csc_e csc_type, + struct vinfo_s *vinfo, + enum vd_path_e vd_path) +{ + switch (cur_source_format[vd_path]) { + case HDRTYPE_SDR: + if (vd_path == VD2_PATH && is_dolby_vision_on()) { + hdr_proc(VD2_HDR, SDR_IPT, vinfo); + } else if (sdr_process_mode[vd_path] == PROC_BYPASS) { + 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); + } else if (sdr_process_mode[vd_path] == PROC_SDR_TO_HDR) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, SDR_HDR, vinfo); + else + hdr_proc(VD2_HDR, SDR_HDR, vinfo); + hdr_proc(OSD1_HDR, SDR_HDR, vinfo); + } else if (sdr_process_mode[vd_path] == PROC_SDR_TO_HLG) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, SDR_HLG, vinfo); + else if (vd_path == VD2_PATH) + hdr_proc(VD2_HDR, SDR_HLG, vinfo); + hdr_proc(OSD1_HDR, SDR_HLG, vinfo); + } + break; + case HDRTYPE_HDR10: + if (vd_path == VD2_PATH && is_dolby_vision_on()) { + hdr_proc(VD2_HDR, HDR_IPT, vinfo); + } else if (hdr_process_mode[vd_path] == PROC_BYPASS) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_BYPASS, vinfo); + else + hdr_proc(VD2_HDR, HDR_BYPASS, vinfo); + hdr_proc(OSD1_HDR, SDR_HDR, vinfo); + } else if (hdr_process_mode[vd_path] == PROC_HDR_TO_SDR) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_SDR, vinfo); + else + hdr_proc(VD2_HDR, HDR_SDR, vinfo); + hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo); + } else if (hdr_process_mode[vd_path] == PROC_HDR_TO_HLG) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_HLG, vinfo); + else + hdr_proc(VD2_HDR, HDR_HLG, vinfo); + hdr_proc(OSD1_HDR, SDR_HLG, vinfo); + } + break; + case HDRTYPE_HLG: + if (vd_path == VD2_PATH && is_dolby_vision_on()) { + hdr_proc(VD2_HDR, HLG_IPT, vinfo); + } else if (hlg_process_mode[vd_path] == PROC_BYPASS) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_BYPASS, vinfo); + else + hdr_proc(VD2_HDR, HDR_BYPASS, vinfo); + hdr_proc(OSD1_HDR, SDR_HLG, vinfo); + } else if (hlg_process_mode[vd_path] == PROC_HLG_TO_SDR) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HLG_SDR, vinfo); + else + hdr_proc(VD2_HDR, HLG_SDR, vinfo); + hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo); + } else if (hlg_process_mode[vd_path] == PROC_HLG_TO_HDR) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HLG_HDR, vinfo); + else + hdr_proc(VD2_HDR, HLG_HDR, vinfo); + hdr_proc(OSD1_HDR, SDR_HDR, vinfo); + } + + break; + case HDRTYPE_HDR10PLUS: + if ((vd_path == VD2_PATH) && is_dolby_vision_on()) { + hdr_proc(VD2_HDR, HDR_IPT, vinfo); + } else if (hdr10_plus_process_mode[vd_path] == + PROC_BYPASS) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_BYPASS, vinfo); + else + hdr_proc(VD2_HDR, HDR_BYPASS, vinfo); + hdr_proc(OSD1_HDR, SDR_HDR, vinfo); + } else if (hdr10_plus_process_mode[vd_path] == + PROC_HDRP_TO_HDR) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_BYPASS, vinfo); + else + hdr_proc(VD2_HDR, HDR_BYPASS, vinfo); + hdr_proc(OSD1_HDR, SDR_HDR, vinfo); + } else if (hdr10_plus_process_mode[vd_path] == + PROC_HDRP_TO_SDR) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_SDR, vinfo); + else + hdr_proc(VD2_HDR, HDR_SDR, vinfo); + hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo); + } else if (hdr10_plus_process_mode[vd_path] == + PROC_HDRP_TO_HLG) { + if (vd_path == VD1_PATH) + hdr_proc(VD1_HDR, HDR_HLG, vinfo); + else + hdr_proc(VD2_HDR, HDR_HLG, vinfo); + hdr_proc(OSD1_HDR, SDR_HLG, vinfo); + } + + break; + default: + break; + } + + if (cur_sdr_process_mode[vd_path] != + sdr_process_mode[vd_path]) { + if (cur_source_format[vd_path] == HDRTYPE_SDR) + pr_csc(1, + "am_vecm: vd%d: sdr_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]; + } + if (cur_hdr_process_mode[vd_path] != + hdr_process_mode[vd_path]) { + if (cur_source_format[vd_path] == HDRTYPE_HDR10) + pr_csc(1, + "am_vecm: vd%d: hdr_process_mode %d to %d\n", + vd_path + 1, + cur_hdr_process_mode[vd_path], + hdr_process_mode[vd_path]); + cur_hdr_process_mode[vd_path] = + hdr_process_mode[vd_path]; + } + if (cur_hlg_process_mode[vd_path] != + hlg_process_mode[vd_path]) { + if (cur_source_format[vd_path] == HDRTYPE_HLG) + pr_csc(1, + "am_vecm: vd%d: hlg_process_mode %d to %d\n", + vd_path + 1, + cur_hlg_process_mode[vd_path], + hlg_process_mode[vd_path]); + cur_hlg_process_mode[vd_path] = + hlg_process_mode[vd_path]; + } + if (cur_hdr10_plus_process_mode[vd_path] != + hdr10_plus_process_mode[vd_path]) { + if (cur_source_format[vd_path] == HDRTYPE_HDR10PLUS) + pr_csc(1, + "am_vecm: vd%d: hdr10_plus_process_mode %d to %d\n", + vd_path + 1, + cur_hdr10_plus_process_mode[vd_path], + hdr10_plus_process_mode[vd_path]); + cur_hdr10_plus_process_mode[vd_path] = + hdr10_plus_process_mode[vd_path]; + } + if (cur_csc_type[vd_path] != csc_type) { + pr_csc(1, "am_vecm: vd%d: csc from 0x%x to 0x%x.\n", + vd_path + 1, cur_csc_type[vd_path], csc_type); + cur_csc_type[vd_path] = csc_type; + } +} diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.h b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.h new file mode 100644 index 0000000..84887f8 --- /dev/null +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.h @@ -0,0 +1,34 @@ +/* + * drivers/amlogic/media/enhancement/amvecm/amcsc_pip.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef AM_CSC_PIP_H +#define AM_CSC_PIP_H +extern int hdr_policy_process( + struct vinfo_s *vinfo, + enum hdr_type_e *source_format, + enum vd_path_e vd_path); +extern void hdmi_packet_process( + int signal_change_flag, + struct vinfo_s *vinfo, + struct vframe_master_display_colour_s *p, + struct hdr10plus_para *hdmitx_hdr10plus_param, + enum vd_path_e vd_path); +extern void video_post_process( + enum vpp_matrix_csc_e csc_type, + struct vinfo_s *vinfo, + enum vd_path_e vd_path); +#endif diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 194a037..8b6c2d5 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -183,7 +183,7 @@ unsigned int debug_game_mode_1; module_param(debug_game_mode_1, uint, 0664); MODULE_PARM_DESC(debug_game_mode_1, "\n debug_game_mode_1\n"); unsigned int pq_user_value; -enum hdr_type_e hdr_source_type = HDRTYPE_SDR; +enum hdr_type_e hdr_source_type = HDRTYPE_NONE; #define SR0_OFFSET 0xc00 #define SR1_OFFSET 0xc80 @@ -1078,44 +1078,59 @@ int amvecm_on_vs( unsigned int sps_w_in, unsigned int sps_h_in, unsigned int cm_in_w, - unsigned int cm_in_h) + unsigned int cm_in_h, + enum vd_path_e vd_path) { int result = 0; if (probe_ok == 0) return 0; #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (for_dolby_vision_certification()) + if (for_dolby_vision_certification() && (vd_path == VD1_PATH)) return 0; #endif - if (!dnlp_insmod_ok) + if (!dnlp_insmod_ok && vd_path == VD1_PATH) dnlp_alg_param_init(); + if (flags & CSC_FLAG_CHECK_OUTPUT) { - if (toggle_vf) - amvecm_fresh_overscan(toggle_vf); - else if (vf) - amvecm_fresh_overscan(vf); + if (vd_path == VD1_PATH) { + if (toggle_vf) + amvecm_fresh_overscan(toggle_vf); + else if (vf) + amvecm_fresh_overscan(vf); + } /* to test if output will change */ return amvecm_matrix_process( - toggle_vf, vf, flags); - } + toggle_vf, vf, flags, vd_path); + } else if (vd_path == VD1_PATH) + send_hdr10_plus_pkt(vd_path); if ((toggle_vf != NULL) || (vf != NULL)) { /* matrix adjust */ - result = amvecm_matrix_process(toggle_vf, vf, flags); - if (toggle_vf) { + result = amvecm_matrix_process( + toggle_vf, vf, flags, vd_path); + if (toggle_vf) ioctrl_get_hdr_metadata(toggle_vf); + + if (toggle_vf && vd_path == VD1_PATH) { lc_process(toggle_vf, sps_h_en, sps_v_en, sps_w_in, sps_h_in); amvecm_size_patch(cm_in_w, cm_in_h); } } else { - amvecm_reset_overscan(); - result = amvecm_matrix_process(NULL, NULL, flags); - ve_hist_gamma_reset(); - lc_process(NULL, sps_h_en, sps_v_en, - sps_w_in, sps_h_in); + if (vd_path == VD1_PATH) + amvecm_reset_overscan(); + result = amvecm_matrix_process( + NULL, NULL, flags, vd_path); + if (vd_path == VD1_PATH) { + ve_hist_gamma_reset(); + lc_process(NULL, sps_h_en, sps_v_en, + sps_w_in, sps_h_in); + } } + if (vd_path != VD1_PATH) + return result; + if (!is_dolby_vision_on()) get_hdr_source_type(); @@ -1617,7 +1632,8 @@ static long amvecm_ioctl(struct file *file, case AMVECM_IOC_G_CSCTYPE: argp = (void __user *)arg; if (copy_to_user(argp, - &cur_csc_type, sizeof(enum vpp_matrix_csc_e))) + &cur_csc_type[VD1_PATH], + sizeof(enum vpp_matrix_csc_e))) ret = -EFAULT; break; case AMVECM_IOC_G_COLOR_PRI: @@ -1628,7 +1644,7 @@ static long amvecm_ioctl(struct file *file, ret = -EFAULT; break; case AMVECM_IOC_S_CSCTYPE: - if (copy_from_user(&cur_csc_type, + if (copy_from_user(&cur_csc_type[VD1_PATH], (void __user *)arg, sizeof(enum vpp_matrix_csc_e))) { ret = -EFAULT; @@ -6781,7 +6797,7 @@ static int aml_vecm_probe(struct platform_device *pdev) if (is_meson_gxl_cpu() || is_meson_gxm_cpu()) hdr_flag = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); else - hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3); + hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (1 << 4); hdr_init(&amvecm_dev.hdr_d); aml_vecm_dt_parse(pdev); diff --git a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c index de81b10..5976b9e 100644 --- a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c +++ b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c @@ -638,6 +638,7 @@ void hdr10_plus_hdmitx_vsif_parser( int i; int kpx, kpy; int bz_cur_anchors[9]; + u32 maxrgb_99_percentiles = 0; memset(hdmitx_hdr10plus_param, 0, sizeof(struct hdr10plus_para)); @@ -702,7 +703,9 @@ void hdr10_plus_hdmitx_vsif_parser( hdmitx_hdr10plus_param->average_maxrgb = (u8)ave_maxrgb; for (i = 0; i < 9; i++) { - if (i == 2) { + if ((i == 2) && + /* V0 sei update */ + (hdmitx_hdr10plus_param->application_version != 0)) { distribution_values[i] = hdr_plus_sei.distribution_maxrgb_percentiles[0][i]; hdmitx_hdr10plus_param->distribution_values[i] = @@ -711,6 +714,14 @@ void hdr10_plus_hdmitx_vsif_parser( } distribution_values[i] = hdr_plus_sei.distribution_maxrgb_percentiles[0][i] / 10; + /* V0 sei update */ + if ((hdr_plus_sei.num_distribution_maxrgb_percentiles[0] == 10) + && (hdmitx_hdr10plus_param->application_version == 0) + && (i == 8)) { + maxrgb_99_percentiles = + hdr_plus_sei.distribution_maxrgb_percentiles[0][i + 1]; + distribution_values[i] = maxrgb_99_percentiles / 10; + } if (distribution_values[i] < (1 << 12)) { distribution_values[i] = (distribution_values[i] + (1 << 3)) >> 4; @@ -763,7 +774,7 @@ void hdr10_plus_hdmitx_vsif_parser( /*only video, don't include graphic*/ hdmitx_hdr10plus_param->graphics_overlay_flag = 0; /*metadata and video have no delay*/ - hdmitx_hdr10plus_param->no_delay_flag = 0; + hdmitx_hdr10plus_param->no_delay_flag = 1; memcpy(&dbg_hdr10plus_pkt, hdmitx_hdr10plus_param, sizeof(struct hdr10plus_para)); diff --git a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c index b5cd1f0..b39bdf0 100644 --- a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c +++ b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c @@ -21,9 +21,11 @@ #include #include #include +#include #include "set_hdr2_v0.h" #include "arch/vpp_hdr_regs.h" #include "arch/vpp_regs.h" +#include "arch/vpp_dolbyvision_regs.h" //#define HDR2_MODULE //#define HDR2_PRINT @@ -115,6 +117,27 @@ int eo_y_lut_hdr[143] = { module_param_array(eo_y_lut_hdr, int, &num_eo_y_lut_hdr, 0664); MODULE_PARM_DESC(eo_y_lut_hdr, "\n eo_y_lut_hdr\n"); +int eo_y_lut_pq[143] = { + 59392, 66560, 94208, 110592, 121984, 132160, 138816, 146432, + 151264, 156096, 161440, 165568, 168768, 172224, 175952, 179968, + 182240, 200680, 215102, 226400, 235271, 244625, 250984, 258029, + 264312, 269323, 275208, 280295, 284260, 288817, 294028, 297434, + 300794, 304586, 308851, 312465, 315139, 318120, 321437, 325119, + 328439, 330693, 333181, 335922, 338938, 342251, 344974, 346965, + 349143, 351524, 354124, 356960, 360050, 361931, 363762, 365751, + 367912, 370258, 372802, 375559, 377689, 379306, 381056, 382948, + 384994, 387204, 389591, 392167, 394081, 395581, 397197, 398940, + 400818, 402840, 405018, 407363, 409743, 411100, 412561, 414132, + 415820, 417636, 419588, 421685, 423939, 426172, 427472, 428869, + 430370, 431980, 433710, 435567, 437561, 439701, 441999, 443416, + 444740, 446160, 447685, 449321, 451078, 452962, 454986, 457157, + 459120, 460370, 461713, 463154, 464701, 466363, 468146, 470061, + 472118, 474326, 475917, 477191, 478560, 480031, 481611, 483309, + 485135, 487098, 489208, 491477, 492719, 494032, 495444, 496965, + 498601, 500363, 502261, 504304, 506506, 508391, 509670, 511049, + 512536, 514140, 515870, 517739, 519756, 521934, 524287 +}; + int eo_y_lut_hlg[143] = { 0, 169296, 202068, 221184, 234837, 246442, 253952, 262485, 267605, 273408, 279210, 282794, 286720, 290986, 295253, 297728, 300373, 319488, @@ -230,19 +253,21 @@ static int oe_y_lut_bypass[149] = { }; int oo_y_lut_hdr_hlg[149] = { - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 3917, 3776, 3662, 3565, 3410, 3288, 3188, 3104, 2968, 2862, 2775, - 2702, 2639, 2584, 2535, 2491, 2452, 2416, 2383, 2352, 2297, 2249, - 2207, 2169, 2134, 2103, 2074, 2047, 2000, 1958, 1921, 1888, 1858, - 1831, 1806, 1782, 1741, 1705, 1672, 1644, 1617, 1594, 1572, 1552, - 1515, 1484, 1456, 1431, 1408, 1387, 1368, 1351, 1319, 1292, 1267, - 1245, 1226, 1208, 1191, 1176, 1148, 1124, 1103, 1084, 1067, 1051, - 1037, 1023, 1000, 979, 960, 944, 929, 915, 903, 891, 870, 852, - 836, 822, 808, 797, 786, 776, 757, 742, 728, 715, 704, 693, 684, - 675, 659, 646, 633, 622, 613, 604, 595, 588, 581, 574, 568, 562, - 557, 551, 546, 542, 537, 533, 529, 525, 522, 518, 515, 512 + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3983, 3703, 3469, 3270, + 3098, 2948, 2816, 2698, 2592, 2409, 2257, 2127, 2016, 1918, + 1832, 1755, 1686, 1567, 1468, 1384, 1311, 1248, 1192, 1142, + 1097, 1020, 955, 900, 853, 812, 775, 743, 714, 663, + 621, 586, 555, 528, 504, 483, 464, 431, 404, 381, + 361, 343, 328, 314, 302, 281, 263, 248, 235, 223, + 213, 204, 196, 189, 182, 176, 171, 166, 161, 157, + 152, 149, 145, 142, 139, 136, 133, 130, 128 }; static int num_hdr_sdr_lut = 149; @@ -265,96 +290,180 @@ module_param_array(oo_y_lut_hdr_sdr, int, &num_hdr_sdr_lut, 0664); MODULE_PARM_DESC(oo_y_lut_hdr_sdr, "\n num_hdr_sdr_lut\n"); int oo_y_lut_bypass[149] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255 + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512 +}; + +/* HDR map to 4000 gain=512*4000/10000, 512 as 1.0 */ +int oo_y_lut_hdr_hdr_4000[149] = { + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205 +}; + +/* HDR map to 2500 gain=512*2500/10000, 512 as 1.0 */ +int oo_y_lut_hdr_hdr_2500[149] = { + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128 +}; + +/* HDR map to 1200 gain=512*1200/10000, 512 as 1.0 */ +int oo_y_lut_hdr_hdr_1200[149] = { + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61 }; int oo_y_lut_hlg_hdr[149] = { - 4, 8, 9, 11, 12, 14, 16, 19, 22, 23, 24, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 35, 36, 37, 38, 40, 42, 43, 44, 46, 48, 49, 51, - 53, 55, 57, 58, 61, 63, 65, 67, 70, 73, 75, 77, 79, 81, 82, 84, - 85, 86, 88, 89, 91, 93, 95, 96, 98, 99, 101, 102, 104, 107, 109, - 111, 112, 114, 116, 117, 120, 122, 125, 127, 129, 131, 133, 135, - 138, 141, 144, 146, 148, 151, 153, 155, 158, 162, 165, 168, 171, - 173, 176, 178, 182, 186, 190, 193, 196, 199, 202, 204, 209, 214, - 218, 222, 225, 229, 232, 235, 240, 245, 250, 255, 259, 263, 266, - 270, 276, 282, 288, 293, 297, 302, 306, 310, 317, 324, 330, 336, - 342, 347, 352, 356, 360, 365, 369, 372, 376, 380, 383, 386, 389, - 392, 395, 398, 401, 404, 407, 409 + 6, 10, 12, 13, 16, 18, 21, 24, 27, 29, + 30, 31, 32, 33, 34, 35, 36, 38, 39, 41, + 42, 44, 45, 47, 48, 50, 52, 54, 55, 58, + 60, 62, 64, 66, 69, 71, 73, 76, 79, 82, + 84, 88, 91, 94, 97, 99, 101, 103, 105, 106, + 108, 110, 111, 114, 116, 118, 120, 122, 124, 126, + 128, 131, 133, 136, 138, 141, 143, 145, 147, 150, + 153, 156, 159, 162, 164, 166, 168, 172, 176, 180, + 183, 186, 188, 191, 194, 198, 202, 206, 210, 213, + 216, 220, 222, 228, 233, 237, 241, 245, 249, 252, + 256, 262, 267, 272, 277, 282, 286, 290, 294, 301, + 307, 313, 318, 324, 328, 333, 337, 345, 353, 360, + 366, 372, 377, 383, 388, 397, 405, 413, 420, 427, + 433, 440, 445, 451, 456, 461, 466, 470, 475, 479, + 483, 487, 491, 494, 498, 502, 505, 508, 512 }; +/* SDR convert to 625 gain=512*625/10000 lumin HDR, 512 as 1.0 */ static int num_sdr_hdr_lut = 149; int oo_y_lut_sdr_hdr[149] = { - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38 + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32 }; module_param_array(oo_y_lut_sdr_hdr, int, &num_sdr_hdr_lut, 0664); MODULE_PARM_DESC(oo_y_lut_sdr_hdr, "\n num_sdr_hdr_lut\n"); -int oo_y_lut_hlg_sdr[149] = { - 245, 269, 275, 282, 288, 295, 302, 309, 316, 318, 320, 322, 323, - 326, 327, 329, 331, 333, 335, 337, 338, 341, 343, 345, 346, 349, - 351, 353, 354, 357, 359, 361, 362, 365, 367, 369, 371, 373, 376, - 378, 379, 382, 384, 386, 388, 390, 391, 392, 393, 394, 395, 396, - 397, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 412, - 413, 414, 415, 416, 417, 419, 420, 421, 422, 423, 424, 425, 427, - 428, 430, 431, 432, 433, 434, 435, 437, 438, 440, 441, 442, 443, - 444, 445, 447, 448, 450, 451, 452, 453, 454, 455, 457, 459, 460, - 462, 463, 464, 465, 466, 468, 469, 471, 472, 473, 475, 476, 477, - 479, 480, 482, 483, 484, 486, 487, 488, 490, 491, 493, 494, 496, - 497, 498, 499, 500, 501, 502, 503, 503, 504, 505, 506, 506, 507, - 508, 508, 509, 509, 510, 510 + +/* SDR convert to 100 gain=512*100/10000 lumin HDR, 512 as 1.0 */ +int oo_y_lut_sdr_hdr_100[149] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5 }; -int oo_y_lut_sdr_hlg[149] = { - 1060, 967, 946, 924, 903, 883, 863, 844, 825, 819, 814, 810, 806, - 800, 795, 791, 788, 782, 777, 773, 770, 764, 760, 756, 753, - 747, 743, 739, 736, 730, 726, 722, 719, 714, 710, 706, 703, - 698, 694, 690, 687, 682, 678, 674, 671, 669, 667, 664, 663, - 661, 659, 658, 656, 654, 651, 649, 648, 646, 644, 643, 641, - 639, 637, 635, 633, 631, 630, 628, 627, 625, 622, 620, 619, - 617, 616, 614, 613, 610, 608, 606, 605, 603, 602, 600, 599, - 597, 595, 593, 591, 590, 588, 587, 585, 583, 581, 579, 578, - 576, 575, 573, 572, 570, 568, 566, 565, 563, 562, 561, 559, - 557, 555, 554, 552, 550, 549, 548, 547, 545, 543, 541, 539, - 538, 537, 536, 534, 532, 530, 529, 527, 526, 525, 523, 522, - 521, 520, 519, 518, 518, 517, 516, 515, 515, 514, 513, 513, - 512, 512, 511, 511 +/* SDR convert to 250 gain=512*250/12000 lumin HDR, 512 as 1.0 */ +int oo_y_lut_sdr_hdr_250[149] = { + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12 +}; + +/* SDR convert to 310 gain=512*310/10000 lumin HDR, 512 as 1.0 */ +int oo_y_lut_sdr_hdr_300[149] = { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16 +}; + +int oo_y_lut_hlg_sdr[149] = { + 790, 749, 739, 729, 719, 709, 699, 690, 681, 678, + 675, 673, 671, 669, 666, 664, 662, 659, 657, 655, + 653, 651, 648, 646, 645, 642, 639, 638, 636, 633, + 631, 629, 627, 625, 622, 620, 619, 616, 614, 612, + 610, 608, 606, 604, 602, 601, 600, 598, 597, 596, + 596, 595, 594, 593, 591, 590, 589, 588, 588, 587, + 586, 585, 583, 582, 581, 580, 580, 579, 578, 577, + 576, 575, 574, 573, 572, 571, 570, 569, 568, 567, + 566, 565, 564, 563, 563, 561, 560, 559, 558, 557, + 556, 556, 555, 554, 553, 552, 551, 550, 549, 548, + 548, 546, 545, 544, 543, 542, 542, 541, 540, 539, + 538, 537, 536, 535, 534, 533, 533, 532, 530, 529, + 529, 528, 527, 526, 526, 524, 523, 522, 521, 521, + 520, 519, 519, 518, 517, 517, 516, 516, 515, 515, + 514, 514, 514, 513, 513, 512, 512, 512, 512 }; -int oo_y_lut_1[149] = { - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095 +int oo_y_lut_sdr_hlg[149] = { + 331, 349, 354, 359, 364, 369, 374, 379, 384, 386, + 387, 389, 390, 391, 393, 394, 395, 397, 398, 399, + 400, 402, 404, 405, 406, 408, 409, 410, 411, 413, + 415, 416, 417, 419, 420, 422, 423, 425, 426, 427, + 429, 430, 432, 433, 434, 435, 436, 437, 438, 439, + 439, 440, 440, 441, 442, 443, 444, 445, 445, 446, + 446, 447, 448, 449, 450, 451, 451, 452, 453, 454, + 455, 455, 456, 457, 458, 458, 459, 460, 461, 462, + 462, 463, 464, 464, 465, 466, 467, 468, 469, 469, + 470, 471, 471, 472, 473, 474, 475, 476, 477, 477, + 478, 479, 480, 481, 482, 482, 483, 484, 484, 486, + 487, 487, 488, 489, 490, 490, 491, 492, 493, 494, + 495, 496, 496, 497, 498, 499, 500, 501, 502, 503, + 503, 504, 505, 505, 506, 506, 507, 507, 508, 508, + 509, 509, 509, 510, 510, 511, 511, 511, 512 }; #else //HDR2_MODULE @@ -692,9 +801,14 @@ static uint in_luma = 1;/*1 as 100luminance*/ module_param(in_luma, uint, 0664); MODULE_PARM_DESC(in_luma, "\n in_luma\n"); -static uint adp_scal_shift = 10;/*1 as 100luminance*/ -module_param(adp_scal_shift, uint, 0664); -MODULE_PARM_DESC(adp_scal_shift, "\n adp_scal_shift\n"); +static uint adp_scal_y_shift = 10; /* 1.0 =1024 */ +module_param(adp_scal_y_shift, uint, 0664); +MODULE_PARM_DESC(adp_scal_y_shift, "\n adp_scal_y_shift\n"); + +#define X_SHFT 10 +static uint adp_scal_x_shift = X_SHFT; /* 1.0 = 1024 */ +module_param(adp_scal_x_shift, uint, 0664); +MODULE_PARM_DESC(adp_scal_x_shift, "\n adp_scal_x_shift\n"); static uint alpha_oe_a = 0x1; module_param(alpha_oe_a, uint, 0664); @@ -719,18 +833,45 @@ int ncl_2020_709[9] = { /* standard2020->dcip3-d65 8bit*/ int ncl_2020_p3[9] = { 368, -96, -16, -16, 275, -3, 1, -8, 263}; +int gamut_bypass_8bit[9] = { + 256, 0, 0, 0, 256, 0, 0, 0, 256}; /*for iptv special primary->709rgb*/ int ncl_sp_709[9] = { 2684, -489, -147, -201, 2266, -17, -29, -171, 2248}; +/* gamut bypass */ +int gamut_bypass[9] = {2048, 0, 0, 0, 2048, 0, 0, 0, 2048}; + /*int cl_2020_709[9] =*/ /*{-1775, 3867, -44, 3422, -1154, -220 ,-304, 43, 2309}; */ int ncl_709_2020[9] = {1285, 674, 89, 142, 1883, 23, 34, 180, 1834}; /*int cl_709_2020[9] =*/ /*{436, 1465, 148, 1285, 674, 89, 34, 180, 1834}; */ -/*int yrb2ycbcr_cl2020[15] =*/ - /*{876, 0, 0, -566, 0, 566, -902, 902, 0, -462, 0, 462, -521, 521, 0};*/ + + +/* 1688, 2146, 262, */ +/* 683, 2951, 462, */ +/* 99, 309, 3688, */ +/* 4096 as 1.0 */ +int rgb2lms_ncl2020[9] = { + 844, 1073, 131, + 342, 1475, 231, + 50, 154, 1844 +}; + +/* ncl_709_2020 * rgb2lms_ncl2020 */ +/* 606.133 1275.828 166.040 */ +/* 320.411 1489.315 238.273 */ +/* 72.384 320.413 1655.203 */ +int rgb709_to_lms2020[9] = { + 606, 1276, 166, + 321, 1489, 238, + 72, 320, 1656 +}; + +/* Ys coeff, 1.0 = 1024 */ +int ys_coef[3] = {269, 694, 61}; /* matrix coef */ int rgb2yuvpre[3] = {0, 0, 0}; @@ -741,29 +882,115 @@ int bypass_pre[3] = {0, 0, 0}; int bypass_pos[3] = {0, 0, 0}; /*matrix coef BT709*/ -int yuv2rgbmat[15] = { - 1197, 0, 0, 1197, 1851, 0, 1197, 0, 1163, 1197, 2271, 0, 1197, 0, 2011}; -int rgb2ycbcr[15] = { - 230, 594, 52, -125, -323, 448, 448, -412, -36, 0, 0, 0, 0, 0, 0}; -int rgb2ycbcr_ncl2020[15] = { - 230, 594, 52, -125, -323, 448, 448, -412, -36, 0, 0, 0, 0, 0, 0}; -int rgb2ycbcr_709[15] = { - 186, 627, 63, -103, -345, 448, 448, -407, -41, 0, 0, 0, 0, 0, 0}; -int ycbcr2rgb_709[15] = { - 1192, 0, 1836, 1192, -217, -546, 1192, 2166, 0, 0, 0, 0, 0, 0, 0}; -/*int yrb2ycbcr_cl2020[15] =*/ - /*{876, 0, 0, -566, 0, 566, -902, 902, 0, -462, 0, 462, -521, 521, 0};*/ -int ycbcr2rgb_ncl2020[15] = { - 1197, 0, 1726, 1197, -193, -669, 1197, 2202, 0, 0, 0, 0, 0, 0, 0}; -/*int ycbcr2yrb_cl2020[15] =*/ - /*{1197,0,0,1197,0,1163,1197,1851,0, 1197, 0, 2011, 1197, 2271, 0};*/ - -static int bypass_coeff[15] = { +int yuv2rgbmat[MTX_NUM_PARAM] = { + 1197, 0, 0, + 1197, 1851, 0, + 1197, 0, 1163, + 1197, 2271, 0, + 1197, 0, 2011, + 0 +}; + +int rgb2ycbcr[MTX_NUM_PARAM] = { + 230, 594, 52, + -125, -323, + 448, 448, -412, + -36, 0, 0, + 0, 0, 0, + 0 +}; + +int rgb2ycbcr_ncl2020[MTX_NUM_PARAM] = { + 230, 594, 52, + -125, -323, 448, + 448, -412, -36, + 0, 0, 0, + 0, 0, 0, + 0 +}; + +int rgb2ycbcr_709[MTX_NUM_PARAM] = { + 186, 627, 63, + -103, -345, 448, + 448, -407, -41, + 0, 0, 0, + 0, 0, 0, + 0 +}; + +int ycbcr2rgb_709[MTX_NUM_PARAM] = { + 1192, 0, 1836, + 1192, -217, -546, + 1192, 2166, + 0, 0, 0, + 0, 0, 0, + 0 +}; + +/* int yrb2ycbcr_cl2020[MTX_NUM_PARAM] = { */ +/* 876, 0, 0, */ +/* -566, 0, 566, */ +/* -902, 902, 0, */ +/* -462, 0, 462, */ +/* -521, 521, 0, */ +/* 0}; */ + +int ycbcr2rgb_ncl2020[MTX_NUM_PARAM] = { + 1197, 0, 1726, + 1197, -193, -669, + 1197, 2202, 0, + 0, 0, 0, + 0, 0, 0, + 0 +}; + +/* int ycbcr2yrb_cl2020[MTX_NUM_PARAM] = { */ +/* 1197, 0, 0, */ +/* 1197, 0, 1163, */ +/* 1197, 1851, 0, */ +/* 1197, 0, 2011, */ +/* 1197, 2271, 0, */ +/* 0 */ +/*}; */ + +/* int yrb2ycbcr_cl2020[MTX_NUM_PARAM] = { */ +/* 876, 0, 0, */ +/* -566, 0, 566, */ +/* -902, 902, 0, */ +/* -462, 0, 462, */ +/* -521, 521, 0, */ +/* 0 */ +/* }; */ + +/* [ 2048, 2048, 0], */ +/* [ 6610,-13613, 7003], */ +/* [17933,-17390, -543] / 4096 */ +/* int lms2ipt_ncl2020[MTX_NUM_PARAM] = { */ +/* 256, 256, 0, */ +/* 2242, -2174, -68, */ +/* 827, -1702, 875, */ +/* 0, 0, 0, */ +/* 0, 0, 0, */ +/* 7 << 5 */ +/* }; */ + + +int lms2ipt_ncl2020[MTX_NUM_PARAM] = { + 410, 410, 204, + 2281, -2484, 203, + 413, 183, -596, + 0, 0, 0, + 0, 0, 0, + 0 +}; + +static int bypass_coeff[MTX_NUM_PARAM] = { 1024, 0, 0, 0, 1024, 0, 0, 0, 1024, 0, 0, 0, 0, 0, 0, + 0 }; unsigned int _log2(unsigned int value) @@ -837,23 +1064,37 @@ void set_hdr_matrix( int c_gain_lim_coef[3]; int gmut_coef[3][3]; int gmut_shift; - int adpscl_enable[3]; + int adpscl_bypass[3]; int adpscl_alpha[3] = {0, 0, 0}; int adpscl_shift[3]; - int adpscl_ys_coef[3] = {0, 0, 0}; + int adpscl_ys_coef[3] = { + 269, + 694, + 61 + }; int adpscl_beta[3]; int adpscl_beta_s[3]; int i = 0; - int mtx[15] = { + int in_mtx[MTX_NUM_PARAM] = { 1024, 0, 0, 0, 1024, 0, 0, 0, 1024, 0, 0, 0, 0, 0, 0, + 0 }; - if (module_sel & VD1_HDR) { + int out_mtx[MTX_NUM_PARAM] = { + 1024, 0, 0, + 0, 1024, 0, + 0, 0, 1024, + 0, 0, 0, + 0, 0, 0, + 0 + }; + + if (module_sel == VD1_HDR) { MATRIXI_COEF00_01 = VD1_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF00_01 = VD1_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF02_10 = VD1_HDR2_MATRIXI_COEF02_10; @@ -905,59 +1146,59 @@ void set_hdr_matrix( GMUT_COEF4 = VD1_HDR2_GMUT_COEF4; hdr_ctrl = VD1_HDR2_CTRL; - } else if (module_sel & VD2_HDR) { - MATRIXI_COEF00_01 = VDIN1_HDR2_MATRIXI_COEF00_01; - MATRIXI_COEF00_01 = VDIN1_HDR2_MATRIXI_COEF00_01; - MATRIXI_COEF02_10 = VDIN1_HDR2_MATRIXI_COEF02_10; - MATRIXI_COEF11_12 = VDIN1_HDR2_MATRIXI_COEF11_12; - MATRIXI_COEF20_21 = VDIN1_HDR2_MATRIXI_COEF20_21; - MATRIXI_COEF22 = VDIN1_HDR2_MATRIXI_COEF22; - MATRIXI_COEF30_31 = VDIN1_HDR2_MATRIXI_COEF30_31; - MATRIXI_COEF32_40 = VDIN1_HDR2_MATRIXI_COEF32_40; - MATRIXI_COEF41_42 = VDIN1_HDR2_MATRIXI_COEF41_42; - MATRIXI_OFFSET0_1 = VDIN1_HDR2_MATRIXI_OFFSET0_1; - MATRIXI_OFFSET2 = VDIN1_HDR2_MATRIXI_OFFSET2; - MATRIXI_PRE_OFFSET0_1 = VDIN1_HDR2_MATRIXI_PRE_OFFSET0_1; - MATRIXI_PRE_OFFSET2 = VDIN1_HDR2_MATRIXI_PRE_OFFSET2; - MATRIXI_CLIP = VDIN1_HDR2_MATRIXI_CLIP; - MATRIXI_EN_CTRL = VDIN1_HDR2_MATRIXI_EN_CTRL; - - MATRIXO_COEF00_01 = VDIN1_HDR2_MATRIXO_COEF00_01; - MATRIXO_COEF00_01 = VDIN1_HDR2_MATRIXO_COEF00_01; - MATRIXO_COEF02_10 = VDIN1_HDR2_MATRIXO_COEF02_10; - MATRIXO_COEF11_12 = VDIN1_HDR2_MATRIXO_COEF11_12; - MATRIXO_COEF20_21 = VDIN1_HDR2_MATRIXO_COEF20_21; - MATRIXO_COEF22 = VDIN1_HDR2_MATRIXO_COEF22; - MATRIXO_COEF30_31 = VDIN1_HDR2_MATRIXO_COEF30_31; - MATRIXO_COEF32_40 = VDIN1_HDR2_MATRIXO_COEF32_40; - MATRIXO_COEF41_42 = VDIN1_HDR2_MATRIXO_COEF41_42; - MATRIXO_OFFSET0_1 = VDIN1_HDR2_MATRIXO_OFFSET0_1; - MATRIXO_OFFSET2 = VDIN1_HDR2_MATRIXO_OFFSET2; - MATRIXO_PRE_OFFSET0_1 = VDIN1_HDR2_MATRIXO_PRE_OFFSET0_1; - MATRIXO_PRE_OFFSET2 = VDIN1_HDR2_MATRIXO_PRE_OFFSET2; - MATRIXO_CLIP = VDIN1_HDR2_MATRIXO_CLIP; - MATRIXO_EN_CTRL = VDIN1_HDR2_MATRIXO_EN_CTRL; + } else if (module_sel == VD2_HDR) { + MATRIXI_COEF00_01 = VD2_HDR2_MATRIXI_COEF00_01; + MATRIXI_COEF00_01 = VD2_HDR2_MATRIXI_COEF00_01; + MATRIXI_COEF02_10 = VD2_HDR2_MATRIXI_COEF02_10; + MATRIXI_COEF11_12 = VD2_HDR2_MATRIXI_COEF11_12; + MATRIXI_COEF20_21 = VD2_HDR2_MATRIXI_COEF20_21; + MATRIXI_COEF22 = VD2_HDR2_MATRIXI_COEF22; + MATRIXI_COEF30_31 = VD2_HDR2_MATRIXI_COEF30_31; + MATRIXI_COEF32_40 = VD2_HDR2_MATRIXI_COEF32_40; + MATRIXI_COEF41_42 = VD2_HDR2_MATRIXI_COEF41_42; + MATRIXI_OFFSET0_1 = VD2_HDR2_MATRIXI_OFFSET0_1; + MATRIXI_OFFSET2 = VD2_HDR2_MATRIXI_OFFSET2; + MATRIXI_PRE_OFFSET0_1 = VD2_HDR2_MATRIXI_PRE_OFFSET0_1; + MATRIXI_PRE_OFFSET2 = VD2_HDR2_MATRIXI_PRE_OFFSET2; + MATRIXI_CLIP = VD2_HDR2_MATRIXI_CLIP; + MATRIXI_EN_CTRL = VD2_HDR2_MATRIXI_EN_CTRL; + + MATRIXO_COEF00_01 = VD2_HDR2_MATRIXO_COEF00_01; + MATRIXO_COEF00_01 = VD2_HDR2_MATRIXO_COEF00_01; + MATRIXO_COEF02_10 = VD2_HDR2_MATRIXO_COEF02_10; + MATRIXO_COEF11_12 = VD2_HDR2_MATRIXO_COEF11_12; + MATRIXO_COEF20_21 = VD2_HDR2_MATRIXO_COEF20_21; + MATRIXO_COEF22 = VD2_HDR2_MATRIXO_COEF22; + MATRIXO_COEF30_31 = VD2_HDR2_MATRIXO_COEF30_31; + MATRIXO_COEF32_40 = VD2_HDR2_MATRIXO_COEF32_40; + MATRIXO_COEF41_42 = VD2_HDR2_MATRIXO_COEF41_42; + MATRIXO_OFFSET0_1 = VD2_HDR2_MATRIXO_OFFSET0_1; + MATRIXO_OFFSET2 = VD2_HDR2_MATRIXO_OFFSET2; + MATRIXO_PRE_OFFSET0_1 = VD2_HDR2_MATRIXO_PRE_OFFSET0_1; + MATRIXO_PRE_OFFSET2 = VD2_HDR2_MATRIXO_PRE_OFFSET2; + MATRIXO_CLIP = VD2_HDR2_MATRIXO_CLIP; + MATRIXO_EN_CTRL = VD2_HDR2_MATRIXO_EN_CTRL; + + CGAIN_OFFT = VD2_HDR2_CGAIN_OFFT; + CGAIN_COEF0 = VD2_HDR2_CGAIN_COEF0; + CGAIN_COEF1 = VD2_HDR2_CGAIN_COEF1; + ADPS_CTRL = VD2_HDR2_ADPS_CTRL; + ADPS_ALPHA0 = VD2_HDR2_ADPS_ALPHA0; + ADPS_ALPHA1 = VD2_HDR2_ADPS_ALPHA1; + ADPS_BETA0 = VD2_HDR2_ADPS_BETA0; + ADPS_BETA1 = VD2_HDR2_ADPS_BETA1; + ADPS_BETA2 = VD2_HDR2_ADPS_BETA2; + ADPS_COEF0 = VD2_HDR2_ADPS_COEF0; + ADPS_COEF1 = VD2_HDR2_ADPS_COEF1; + GMUT_CTRL = VD2_HDR2_GMUT_CTRL; + GMUT_COEF0 = VD2_HDR2_GMUT_COEF0; + GMUT_COEF1 = VD2_HDR2_GMUT_COEF1; + GMUT_COEF2 = VD2_HDR2_GMUT_COEF2; + GMUT_COEF3 = VD2_HDR2_GMUT_COEF3; + GMUT_COEF4 = VD2_HDR2_GMUT_COEF4; - CGAIN_OFFT = VDIN1_HDR2_CGAIN_OFFT; - CGAIN_COEF0 = VDIN1_HDR2_CGAIN_COEF0; - CGAIN_COEF1 = VDIN1_HDR2_CGAIN_COEF1; - ADPS_CTRL = VDIN1_HDR2_ADPS_CTRL; - ADPS_ALPHA0 = VDIN1_HDR2_ADPS_ALPHA0; - ADPS_ALPHA1 = VDIN1_HDR2_ADPS_ALPHA1; - ADPS_BETA0 = VDIN1_HDR2_ADPS_BETA0; - ADPS_BETA1 = VDIN1_HDR2_ADPS_BETA1; - ADPS_BETA2 = VDIN1_HDR2_ADPS_BETA2; - ADPS_COEF0 = VDIN1_HDR2_ADPS_COEF0; - ADPS_COEF1 = VDIN1_HDR2_ADPS_COEF1; - GMUT_CTRL = VDIN1_HDR2_GMUT_CTRL; - GMUT_COEF0 = VDIN1_HDR2_GMUT_COEF0; - GMUT_COEF1 = VDIN1_HDR2_GMUT_COEF1; - GMUT_COEF2 = VDIN1_HDR2_GMUT_COEF2; - GMUT_COEF3 = VDIN1_HDR2_GMUT_COEF3; - GMUT_COEF4 = VDIN1_HDR2_GMUT_COEF4; - - hdr_ctrl = VDIN1_HDR2_CTRL; - } else if (module_sel & OSD1_HDR) { + hdr_ctrl = VD2_HDR2_CTRL; + } else if (module_sel == OSD1_HDR) { MATRIXI_COEF00_01 = OSD1_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF00_01 = OSD1_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF02_10 = OSD1_HDR2_MATRIXI_COEF02_10; @@ -1009,7 +1250,7 @@ void set_hdr_matrix( GMUT_COEF4 = OSD1_HDR2_GMUT_COEF4; hdr_ctrl = OSD1_HDR2_CTRL; - } else if (module_sel & DI_HDR) { + } else if (module_sel == DI_HDR) { MATRIXI_COEF00_01 = DI_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF00_01 = DI_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF02_10 = DI_HDR2_MATRIXI_COEF02_10; @@ -1061,7 +1302,7 @@ void set_hdr_matrix( GMUT_COEF4 = DI_HDR2_GMUT_COEF4; hdr_ctrl = DI_HDR2_CTRL; - } else if (module_sel & VDIN0_HDR) { + } else if (module_sel == VDIN0_HDR) { MATRIXI_COEF00_01 = VDIN0_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF00_01 = VDIN0_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF02_10 = VDIN0_HDR2_MATRIXI_COEF02_10; @@ -1113,7 +1354,7 @@ void set_hdr_matrix( GMUT_COEF4 = VDIN0_HDR2_GMUT_COEF4; hdr_ctrl = VDIN0_HDR2_CTRL; - } else if (module_sel & VDIN1_HDR) { + } else if (module_sel == VDIN1_HDR) { MATRIXI_COEF00_01 = VDIN1_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF00_01 = VDIN1_HDR2_MATRIXI_COEF00_01; MATRIXI_COEF02_10 = VDIN1_HDR2_MATRIXI_COEF02_10; @@ -1171,51 +1412,66 @@ void set_hdr_matrix( return; if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) + (module_sel == OSD1_HDR)) _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_on, 13, 1); else VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_on, 13, 1); - if (mtx_sel & HDR_IN_MTX) { - if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { - for (i = 0; i < 15; i++) - mtx[i] = hdr_mtx_param->mtx_in[i]; + if (mtx_sel == HDR_IN_MTX) { + for (i = 0; i < MTX_NUM_PARAM; i++) + in_mtx[i] = hdr_mtx_param->mtx_in[i]; - /*for rtl bug osd1 green line at the bottom*/ +#ifdef HDR2_PRINT + pr_info("hdr: in_mtx %d %d = %x,%x %x %x %x %x,%x\n", + hdr_mtx_param->mtx_on, + hdr_mtx_param->mtx_only, + (hdr_mtx_param->mtxi_pre_offset[0] << 16) | + (hdr_mtx_param->mtxi_pre_offset[1] & 0xFFF), + (in_mtx[0 * 3 + 0] << 16) | + (in_mtx[0 * 3 + 1] & 0x1FFF), + (in_mtx[0 * 3 + 2] << 16) | + (in_mtx[1 * 3 + 0] & 0x1FFF), + (in_mtx[1 * 3 + 1] << 16) | + (in_mtx[1 * 3 + 2] & 0x1FFF), + (in_mtx[2 * 3 + 0] << 16) | + (in_mtx[2 * 3 + 1] & 0x1FFF), + in_mtx[2 * 3 + 2], + (hdr_mtx_param->mtxi_pos_offset[0] << 16) | + (hdr_mtx_param->mtxi_pos_offset[1] & 0xFFF)); +#endif + + if ((is_meson_g12b_cpu() && is_meson_rev_b()) && + (module_sel == OSD1_HDR)) { + /* only enable in_mtx */ if ((hdr_mtx_param->mtx_only == MTX_ONLY) && (!hdr_mtx_param->mtx_on)) _VSYNC_WR_MPEG_REG(MATRIXI_EN_CTRL, 1); else _VSYNC_WR_MPEG_REG(MATRIXI_EN_CTRL, - hdr_mtx_param->mtx_on); - /*yuv in*/ + hdr_mtx_param->mtx_on); _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_on, 4, 1); - _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_only, 16, 1); - _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 0, 17, 1); - /*mtx in en*/ _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 1, 14, 1); _VSYNC_WR_MPEG_REG(MATRIXI_COEF00_01, - (mtx[0 * 3 + 0] << 16) | - (mtx[0 * 3 + 1] & 0x1FFF)); + (in_mtx[0 * 3 + 0] << 16) | + (in_mtx[0 * 3 + 1] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXI_COEF02_10, - (mtx[0 * 3 + 2] << 16) | - (mtx[1 * 3 + 0] & 0x1FFF)); + (in_mtx[0 * 3 + 2] << 16) | + (in_mtx[1 * 3 + 0] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXI_COEF11_12, - (mtx[1 * 3 + 1] << 16) | - (mtx[1 * 3 + 2] & 0x1FFF)); + (in_mtx[1 * 3 + 1] << 16) | + (in_mtx[1 * 3 + 2] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXI_COEF20_21, - (mtx[2 * 3 + 0] << 16) | - (mtx[2 * 3 + 1] & 0x1FFF)); + (in_mtx[2 * 3 + 0] << 16) | + (in_mtx[2 * 3 + 1] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXI_COEF22, - mtx[2 * 3 + 2]); + in_mtx[2 * 3 + 2]); _VSYNC_WR_MPEG_REG(MATRIXI_OFFSET0_1, (hdr_mtx_param->mtxi_pos_offset[0] << 16) | (hdr_mtx_param->mtxi_pos_offset[1] & 0xFFF)); @@ -1229,35 +1485,33 @@ void set_hdr_matrix( return; } - for (i = 0; i < 15; i++) - mtx[i] = hdr_mtx_param->mtx_in[i]; - - /*for rtl bug osd1 green line at the bottom*/ if ((hdr_mtx_param->mtx_only == MTX_ONLY) && - (!hdr_mtx_param->mtx_on)) + (!hdr_mtx_param->mtx_on)) VSYNC_WR_MPEG_REG(MATRIXI_EN_CTRL, 1); else VSYNC_WR_MPEG_REG(MATRIXI_EN_CTRL, - hdr_mtx_param->mtx_on); - /*yuv in*/ - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_on, 4, 1); - - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_only, + hdr_mtx_param->mtx_on); + VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, + hdr_mtx_param->mtx_on, 4, 1); + VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, + hdr_mtx_param->mtx_only, 16, 1); - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 0, 17, 1); - /*mtx in en*/ VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 1, 14, 1); VSYNC_WR_MPEG_REG(MATRIXI_COEF00_01, - (mtx[0 * 3 + 0] << 16) | (mtx[0 * 3 + 1] & 0x1FFF)); + (in_mtx[0 * 3 + 0] << 16) | + (in_mtx[0 * 3 + 1] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXI_COEF02_10, - (mtx[0 * 3 + 2] << 16) | (mtx[1 * 3 + 0] & 0x1FFF)); + (in_mtx[0 * 3 + 2] << 16) | + (in_mtx[1 * 3 + 0] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXI_COEF11_12, - (mtx[1 * 3 + 1] << 16) | (mtx[1 * 3 + 2] & 0x1FFF)); + (in_mtx[1 * 3 + 1] << 16) | + (in_mtx[1 * 3 + 2] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXI_COEF20_21, - (mtx[2 * 3 + 0] << 16) | (mtx[2 * 3 + 1] & 0x1FFF)); + (in_mtx[2 * 3 + 0] << 16) | + (in_mtx[2 * 3 + 1] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXI_COEF22, - mtx[2 * 3 + 2]); + in_mtx[2 * 3 + 2]); VSYNC_WR_MPEG_REG(MATRIXI_OFFSET0_1, (hdr_mtx_param->mtxi_pos_offset[0] << 16) | (hdr_mtx_param->mtxi_pos_offset[1] & 0xFFF)); @@ -1268,79 +1522,100 @@ void set_hdr_matrix( (hdr_mtx_param->mtxi_pre_offset[1] & 0xFFF)); VSYNC_WR_MPEG_REG(MATRIXI_PRE_OFFSET2, hdr_mtx_param->mtxi_pre_offset[2]); - } else if (mtx_sel & HDR_GAMUT_MTX) { + } else if (mtx_sel == HDR_GAMUT_MTX) { for (i = 0; i < 9; i++) gmut_coef[i/3][i%3] = hdr_mtx_param->mtx_gamut[i]; - /*for g12a/g12b osd blend shift rtl bug*/ - if ((is_meson_g12a_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_a())) && - (hdr_mtx_param->p_sel & HDR_BYPASS) && - (module_sel & OSD1_HDR)) - gmut_shift = 10; - else if (hdr_mtx_param->p_sel & HDR_SDR) - /*work around for gamut bug*/ - gmut_shift = 0;/*11*/ + if (hdr_mtx_param->p_sel == HDR_SDR) + /* use integer mode for gamut coeff */ + gmut_shift = 0; else - /*default 11, set 12 avoid gamut overwrite*/ - gmut_shift = 12; + /* 2048 as 1.0 for gamut coeff */ + gmut_shift = 11; for (i = 0; i < 3; i++) c_gain_lim_coef[i] = hdr_mtx_param->mtx_cgain[i] << 2; - /*0, nolinear input, 1, max linear, 2, adpscl mode*/ - adpscl_mode = 1; + /* 0: adptive scaler mode(Ys); 1: max linear(RGB max) */ + /* 2: none linear Ys -- Do NOT use it */ + if (hdr_mtx_param->p_sel == HLG_HDR || + hdr_mtx_param->p_sel == HLG_SDR || + hdr_mtx_param->p_sel == HLG_IPT) + adpscl_mode = 0; + else + adpscl_mode = 1; + for (i = 0; i < 3; i++) { - if ((is_meson_g12a_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_a())) && - (hdr_mtx_param->p_sel & HDR_BYPASS) && - (module_sel & OSD1_HDR)) - adpscl_enable[i] = 1; + /* bypass adpscl for OSD rgb2yuv*/ + if ((hdr_mtx_param->p_sel == RGB_YUV + || hdr_mtx_param->mtx_only) + && (module_sel == OSD1_HDR)) + adpscl_bypass[i] = 1; + else + adpscl_bypass[i] = 0; + if (hdr_mtx_param->p_sel == HLG_HDR || + hdr_mtx_param->p_sel == HLG_IPT) + adpscl_alpha[i] = 1000 * + (1 << adp_scal_y_shift) / 10000; else - adpscl_enable[i] = 0; - if (hdr_mtx_param->p_sel & HDR_SDR) - adpscl_alpha[i] = - (1 << adp_scal_shift); - else if (hdr_mtx_param->p_sel & SDR_HDR) adpscl_alpha[i] = - (1 << adp_scal_shift); - else if (hdr_mtx_param->p_sel & HDR_BYPASS) - adpscl_alpha[i] = out_luma * - (1 << adp_scal_shift) / in_luma; - else if (hdr_mtx_param->p_sel & HLG_SDR) { - adpscl_alpha[i] = out_luma * - (1 << adp_scal_shift) / in_luma; - adpscl_mode = 2; - } else if (hdr_mtx_param->p_sel & HLG_HDR) - adpscl_alpha[i] = 1 * - (1 << adp_scal_shift) / in_luma; - else if (hdr_mtx_param->p_sel & SDR_HLG) - adpscl_alpha[i] = 10 * in_luma * - (1 << adp_scal_shift) / out_luma; - - adpscl_ys_coef[i] = - 1 << adp_scal_shift; + (1 << adp_scal_y_shift); + + if (adpscl_mode == 1) + adpscl_ys_coef[i] = + 1 << adp_scal_x_shift; + else + adpscl_ys_coef[i] = + ys_coef[i] >> (10 - adp_scal_x_shift); + + adpscl_beta_s[i] = 0; adpscl_beta[i] = 0; } /*shift0 is for x coordinate*/ - adpscl_shift[0] = adp_scal_shift; /*shift1 is for scale multiple*/ - if (hdr_mtx_param->p_sel & HDR_SDR) - adpscl_shift[1] = adp_scal_shift - - _log2((1 << adp_scal_shift) / oo_y_lut_hdr_sdr[148]); - else - adpscl_shift[1] = adp_scal_shift - 1; + if (hdr_mtx_param->p_sel == HDR_SDR) { + adpscl_shift[0] = adp_scal_x_shift - 1; + adpscl_shift[1] = OO_NOR - + _log2((1 << OO_NOR) / oo_y_lut_hdr_sdr[148] - 1); + } else if (hdr_mtx_param->p_sel == HDR_HLG) { + adpscl_shift[0] = adp_scal_x_shift; + adpscl_shift[1] = OO_NOR - + _log2((1 << OO_NOR) / oo_y_lut_hdr_hlg[148]); + } else { + adpscl_shift[0] = adp_scal_x_shift; + adpscl_shift[1] = OO_NOR; + } + /*shift2 is not used, set default*/ - adpscl_shift[2] = adp_scal_shift; + adpscl_shift[2] = adp_scal_y_shift; + +#ifdef HDR2_PRINT + pr_info("hdr: gamut_mtx %d mode %d shift %d = %x %x %x %x %x\n", + hdr_mtx_param->mtx_on, + hdr_mtx_param->mtx_gamut_mode, + gmut_shift, + (gmut_coef[0][1] & 0xffff) << 16 | + (gmut_coef[0][0] & 0xffff), + (gmut_coef[1][0] & 0xffff) << 16 | + (gmut_coef[0][2] & 0xffff), + (gmut_coef[1][2] & 0xffff) << 16 | + (gmut_coef[1][1] & 0xffff), + (gmut_coef[2][1] & 0xffff) << 16 | + (gmut_coef[2][0] & 0xffff), + gmut_coef[2][2] & 0xffff); + pr_info("hdr: adpscl bypass %d, x_shift %d, y_shift %d\n", + adpscl_bypass[0], adpscl_shift[0], adpscl_shift[1]); +#endif /*gamut mode: 1->gamut before ootf*/ /*2->gamut after ootf*/ /*other->disable gamut*/ if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { - _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 1, 6, 2); + (module_sel == OSD1_HDR)) { + _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, + hdr_mtx_param->mtx_gamut_mode, 6, 2); _VSYNC_WR_MPEG_REG(GMUT_CTRL, gmut_shift); _VSYNC_WR_MPEG_REG(GMUT_COEF0, @@ -1365,9 +1640,9 @@ void set_hdr_matrix( c_gain_lim_coef[2], 0, 12); _VSYNC_WR_MPEG_REG(ADPS_CTRL, - adpscl_enable[2] << 6 | - adpscl_enable[1] << 5 | - adpscl_enable[0] << 4 | + adpscl_bypass[2] << 6 | + adpscl_bypass[1] << 5 | + adpscl_bypass[0] << 4 | adpscl_mode); _VSYNC_WR_MPEG_REG(ADPS_ALPHA0, adpscl_alpha[1]<<16 | adpscl_alpha[0]); @@ -1387,11 +1662,10 @@ void set_hdr_matrix( adpscl_ys_coef[0]); _VSYNC_WR_MPEG_REG(ADPS_COEF1, adpscl_ys_coef[2]); - return; } - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 1, 6, 2); - + VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, + hdr_mtx_param->mtx_gamut_mode, 6, 2); VSYNC_WR_MPEG_REG(GMUT_CTRL, gmut_shift); VSYNC_WR_MPEG_REG(GMUT_COEF0, (gmut_coef[0][1] & 0xffff) << 16 | @@ -1411,19 +1685,21 @@ void set_hdr_matrix( VSYNC_WR_MPEG_REG(CGAIN_COEF0, c_gain_lim_coef[1] << 16 | c_gain_lim_coef[0]); - VSYNC_WR_MPEG_REG_BITS(CGAIN_COEF1, c_gain_lim_coef[2], - 0, 12); - - VSYNC_WR_MPEG_REG(ADPS_CTRL, adpscl_enable[2] << 6 | - adpscl_enable[1] << 5 | - adpscl_enable[0] << 4 | - adpscl_mode); + VSYNC_WR_MPEG_REG_BITS(CGAIN_COEF1, + c_gain_lim_coef[2], 0, 12); + + VSYNC_WR_MPEG_REG(ADPS_CTRL, + adpscl_bypass[2] << 6 | + adpscl_bypass[1] << 5 | + adpscl_bypass[0] << 4 | + adpscl_mode); VSYNC_WR_MPEG_REG(ADPS_ALPHA0, - adpscl_alpha[1]<<16 | adpscl_alpha[0]); - VSYNC_WR_MPEG_REG(ADPS_ALPHA1, adpscl_shift[0] << 24 | - adpscl_shift[1] << 20 | - adpscl_shift[2] << 16 | - adpscl_alpha[2]); + adpscl_alpha[1]<<16 | adpscl_alpha[0]); + VSYNC_WR_MPEG_REG(ADPS_ALPHA1, + adpscl_shift[0] << 24 | + adpscl_shift[1] << 20 | + adpscl_shift[2] << 16 | + adpscl_alpha[2]); VSYNC_WR_MPEG_REG(ADPS_BETA0, adpscl_beta_s[0] << 20 | adpscl_beta[0]); VSYNC_WR_MPEG_REG(ADPS_BETA1, @@ -1431,42 +1707,56 @@ void set_hdr_matrix( VSYNC_WR_MPEG_REG(ADPS_BETA2, adpscl_beta_s[2] << 20 | adpscl_beta[2]); VSYNC_WR_MPEG_REG(ADPS_COEF0, - adpscl_ys_coef[1] << 16 | adpscl_ys_coef[0]); - VSYNC_WR_MPEG_REG(ADPS_COEF1, adpscl_ys_coef[2]); - } else if (mtx_sel & HDR_OUT_MTX) { + adpscl_ys_coef[1] << 16 | + adpscl_ys_coef[0]); + VSYNC_WR_MPEG_REG(ADPS_COEF1, + adpscl_ys_coef[2]); + } else if (mtx_sel == HDR_OUT_MTX) { + for (i = 0; i < MTX_NUM_PARAM; i++) + out_mtx[i] = hdr_mtx_param->mtx_out[i]; +#ifdef HDR2_PRINT + pr_info("hdr: out_mtx %d %d = %x,%x %x %x %x %x,%x\n", + hdr_mtx_param->mtx_on, + hdr_mtx_param->mtx_only, + (hdr_mtx_param->mtxo_pre_offset[0] << 16) | + (hdr_mtx_param->mtxo_pre_offset[1] & 0xFFF), + (out_mtx[0 * 3 + 0] << 16) | + (out_mtx[0 * 3 + 1] & 0x1FFF), + (out_mtx[0 * 3 + 2] << 16) | + (out_mtx[1 * 3 + 0] & 0x1FFF), + (out_mtx[1 * 3 + 1] << 16) | + (out_mtx[1 * 3 + 2] & 0x1FFF), + (out_mtx[2 * 3 + 0] << 16) | + (out_mtx[2 * 3 + 1] & 0x1FFF), + out_mtx[2 * 3 + 2], + (hdr_mtx_param->mtxo_pos_offset[0] << 16) | + (hdr_mtx_param->mtxo_pos_offset[1] & 0xFFF)); +#endif + if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { - for (i = 0; i < 15; i++) - mtx[i] = hdr_mtx_param->mtx_out[i]; + (module_sel == OSD1_HDR)) { _VSYNC_WR_MPEG_REG(CGAIN_OFFT, (rgb2yuvpos[2] << 16) | rgb2yuvpos[1]); _VSYNC_WR_MPEG_REG(MATRIXO_EN_CTRL, hdr_mtx_param->mtx_on); - /*yuv in*/ - _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, - hdr_mtx_param->mtx_on, 4, 1); - - _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, - hdr_mtx_param->mtx_only, - 16, 1); _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 0, 17, 1); - /*mtx out en*/ _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 1, 15, 1); _VSYNC_WR_MPEG_REG(MATRIXO_COEF00_01, - (mtx[0 * 3 + 0] << 16) | - (mtx[0 * 3 + 1] & 0x1FFF)); + (out_mtx[0 * 3 + 0] << 16) | + (out_mtx[0 * 3 + 1] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXO_COEF02_10, - (mtx[0 * 3 + 2] << 16) | - (mtx[1 * 3 + 0] & 0x1FFF)); + (out_mtx[0 * 3 + 2] << 16) | + (out_mtx[1 * 3 + 0] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXO_COEF11_12, - (mtx[1 * 3 + 1] << 16) | - (mtx[1 * 3 + 2] & 0x1FFF)); + (out_mtx[1 * 3 + 1] << 16) | + (out_mtx[1 * 3 + 2] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXO_COEF20_21, - (mtx[2 * 3 + 0] << 16) | - (mtx[2 * 3 + 1] & 0x1FFF)); + (out_mtx[2 * 3 + 0] << 16) | + (out_mtx[2 * 3 + 1] & 0x1FFF)); _VSYNC_WR_MPEG_REG(MATRIXO_COEF22, - mtx[2 * 3 + 2]); + out_mtx[2 * 3 + 2]); + _VSYNC_WR_MPEG_REG(MATRIXO_OFFSET0_1, (hdr_mtx_param->mtxo_pos_offset[0] << 16) | (hdr_mtx_param->mtxo_pos_offset[1]&0xFFF)); @@ -1479,30 +1769,29 @@ void set_hdr_matrix( hdr_mtx_param->mtxo_pre_offset[2]); return; } - for (i = 0; i < 15; i++) - mtx[i] = hdr_mtx_param->mtx_out[i]; + VSYNC_WR_MPEG_REG(CGAIN_OFFT, (rgb2yuvpos[2] << 16) | rgb2yuvpos[1]); - VSYNC_WR_MPEG_REG(MATRIXO_EN_CTRL, hdr_mtx_param->mtx_on); - /*yuv in*/ - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_on, 4, 1); - - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_mtx_param->mtx_only, - 16, 1); + VSYNC_WR_MPEG_REG(MATRIXO_EN_CTRL, + hdr_mtx_param->mtx_on); VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 0, 17, 1); - /*mtx out en*/ VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 1, 15, 1); VSYNC_WR_MPEG_REG(MATRIXO_COEF00_01, - (mtx[0 * 3 + 0] << 16) | (mtx[0 * 3 + 1] & 0x1FFF)); + (out_mtx[0 * 3 + 0] << 16) | + (out_mtx[0 * 3 + 1] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXO_COEF02_10, - (mtx[0 * 3 + 2] << 16) | (mtx[1 * 3 + 0] & 0x1FFF)); + (out_mtx[0 * 3 + 2] << 16) | + (out_mtx[1 * 3 + 0] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXO_COEF11_12, - (mtx[1 * 3 + 1] << 16) | (mtx[1 * 3 + 2] & 0x1FFF)); + (out_mtx[1 * 3 + 1] << 16) | + (out_mtx[1 * 3 + 2] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXO_COEF20_21, - (mtx[2 * 3 + 0] << 16) | (mtx[2 * 3 + 1] & 0x1FFF)); + (out_mtx[2 * 3 + 0] << 16) | + (out_mtx[2 * 3 + 1] & 0x1FFF)); VSYNC_WR_MPEG_REG(MATRIXO_COEF22, - mtx[2 * 3 + 2]); + out_mtx[2 * 3 + 2]); + VSYNC_WR_MPEG_REG(MATRIXO_OFFSET0_1, (hdr_mtx_param->mtxo_pos_offset[0] << 16) | (hdr_mtx_param->mtxo_pos_offset[1]&0xFFF)); @@ -1526,27 +1815,27 @@ void set_eotf_lut( unsigned int hdr_ctrl = 0; unsigned int i = 0; - if (module_sel & VD1_HDR) { + if (module_sel == VD1_HDR) { eotf_lut_addr_port = VD1_EOTF_LUT_ADDR_PORT; eotf_lut_data_port = VD1_EOTF_LUT_DATA_PORT; hdr_ctrl = VD1_HDR2_CTRL; - } else if (module_sel & VD2_HDR) { + } else if (module_sel == VD2_HDR) { eotf_lut_addr_port = VD2_EOTF_LUT_ADDR_PORT; eotf_lut_data_port = VD2_EOTF_LUT_DATA_PORT; hdr_ctrl = VD2_HDR2_CTRL; - } else if (module_sel & OSD1_HDR) { + } else if (module_sel == OSD1_HDR) { eotf_lut_addr_port = OSD1_EOTF_LUT_ADDR_PORT; eotf_lut_data_port = OSD1_EOTF_LUT_DATA_PORT; hdr_ctrl = OSD1_HDR2_CTRL; - } else if (module_sel & DI_HDR) { + } else if (module_sel == DI_HDR) { eotf_lut_addr_port = DI_EOTF_LUT_ADDR_PORT; eotf_lut_data_port = DI_EOTF_LUT_DATA_PORT; hdr_ctrl = DI_HDR2_CTRL; - } else if (module_sel & VDIN0_HDR) { + } else if (module_sel == VDIN0_HDR) { eotf_lut_addr_port = VDIN0_EOTF_LUT_ADDR_PORT; eotf_lut_data_port = VDIN0_EOTF_LUT_DATA_PORT; hdr_ctrl = VDIN0_HDR2_CTRL; - } else if (module_sel & VDIN1_HDR) { + } else if (module_sel == VDIN1_HDR) { eotf_lut_addr_port = VDIN1_EOTF_LUT_ADDR_PORT; eotf_lut_data_port = VDIN1_EOTF_LUT_DATA_PORT; hdr_ctrl = VDIN1_HDR2_CTRL; @@ -1554,8 +1843,9 @@ void set_eotf_lut( for (i = 0; i < HDR2_EOTF_LUT_SIZE; i++) lut[i] = hdr_lut_param->eotf_lut[i]; + if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { + (module_sel == OSD1_HDR)) { _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->lut_on, 3, 1); if (!hdr_lut_param->lut_on) @@ -1586,27 +1876,27 @@ void set_ootf_lut( unsigned int hdr_ctrl = 0; unsigned int i = 0; - if (module_sel & VD1_HDR) { + if (module_sel == VD1_HDR) { ootf_lut_addr_port = VD1_OGAIN_LUT_ADDR_PORT; ootf_lut_data_port = VD1_OGAIN_LUT_DATA_PORT; hdr_ctrl = VD1_HDR2_CTRL; - } else if (module_sel & VD2_HDR) { + } else if (module_sel == VD2_HDR) { ootf_lut_addr_port = VD2_OGAIN_LUT_ADDR_PORT; ootf_lut_data_port = VD2_OGAIN_LUT_DATA_PORT; hdr_ctrl = VD2_HDR2_CTRL; - } else if (module_sel & OSD1_HDR) { + } else if (module_sel == OSD1_HDR) { ootf_lut_addr_port = OSD1_OGAIN_LUT_ADDR_PORT; ootf_lut_data_port = OSD1_OGAIN_LUT_DATA_PORT; hdr_ctrl = OSD1_HDR2_CTRL; - } else if (module_sel & DI_HDR) { + } else if (module_sel == DI_HDR) { ootf_lut_addr_port = DI_OGAIN_LUT_ADDR_PORT; ootf_lut_data_port = DI_OGAIN_LUT_DATA_PORT; hdr_ctrl = DI_HDR2_CTRL; - } else if (module_sel & VDIN0_HDR) { + } else if (module_sel == VDIN0_HDR) { ootf_lut_addr_port = VDIN0_OGAIN_LUT_ADDR_PORT; ootf_lut_data_port = VDIN0_OGAIN_LUT_DATA_PORT; hdr_ctrl = VDIN0_HDR2_CTRL; - } else if (module_sel & VDIN1_HDR) { + } else if (module_sel == VDIN1_HDR) { ootf_lut_addr_port = VDIN1_OGAIN_LUT_ADDR_PORT; ootf_lut_data_port = VDIN1_OGAIN_LUT_DATA_PORT; hdr_ctrl = VDIN1_HDR2_CTRL; @@ -1614,9 +1904,8 @@ void set_ootf_lut( for (i = 0; i < HDR2_OOTF_LUT_SIZE; i++) lut[i] = hdr_lut_param->ogain_lut[i]; - if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { + (module_sel == OSD1_HDR)) { _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->lut_on, 1, 1); if (!hdr_lut_param->lut_on) @@ -1631,7 +1920,6 @@ void set_ootf_lut( return; } - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->lut_on, 1, 1); if (!hdr_lut_param->lut_on) @@ -1655,27 +1943,27 @@ void set_oetf_lut( unsigned int hdr_ctrl = 0; unsigned int i = 0; - if (module_sel & VD1_HDR) { + if (module_sel == VD1_HDR) { oetf_lut_addr_port = VD1_OETF_LUT_ADDR_PORT; oetf_lut_data_port = VD1_OETF_LUT_DATA_PORT; hdr_ctrl = VD1_HDR2_CTRL; - } else if (module_sel & VD2_HDR) { + } else if (module_sel == VD2_HDR) { oetf_lut_addr_port = VD2_OETF_LUT_ADDR_PORT; oetf_lut_data_port = VD2_OETF_LUT_DATA_PORT; hdr_ctrl = VD2_HDR2_CTRL; - } else if (module_sel & OSD1_HDR) { + } else if (module_sel == OSD1_HDR) { oetf_lut_addr_port = OSD1_OETF_LUT_ADDR_PORT; oetf_lut_data_port = OSD1_OETF_LUT_DATA_PORT; hdr_ctrl = OSD1_HDR2_CTRL; - } else if (module_sel & DI_HDR) { + } else if (module_sel == DI_HDR) { oetf_lut_addr_port = DI_OETF_LUT_ADDR_PORT; oetf_lut_data_port = DI_OETF_LUT_DATA_PORT; hdr_ctrl = DI_HDR2_CTRL; - } else if (module_sel & VDIN0_HDR) { + } else if (module_sel == VDIN0_HDR) { oetf_lut_addr_port = VDIN0_OETF_LUT_ADDR_PORT; oetf_lut_data_port = VDIN0_OETF_LUT_DATA_PORT; hdr_ctrl = VDIN0_HDR2_CTRL; - } else if (module_sel & VDIN1_HDR) { + } else if (module_sel == VDIN1_HDR) { oetf_lut_addr_port = VDIN1_OETF_LUT_ADDR_PORT; oetf_lut_data_port = VDIN1_OETF_LUT_DATA_PORT; hdr_ctrl = VDIN1_HDR2_CTRL; @@ -1685,7 +1973,7 @@ void set_oetf_lut( lut[i] = hdr_lut_param->oetf_lut[i]; if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { + (module_sel == OSD1_HDR)) { _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->lut_on, 2, 1); if (!hdr_lut_param->lut_on) @@ -1709,7 +1997,6 @@ void set_oetf_lut( return; } - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->lut_on, 2, 1); if (!hdr_lut_param->lut_on) @@ -1743,32 +2030,32 @@ void set_c_gain( unsigned int cgain_coef1 = 0; unsigned int i = 0; - if (module_sel & VD1_HDR) { + if (module_sel == VD1_HDR) { cgain_lut_addr_port = VD1_CGAIN_LUT_ADDR_PORT; cgain_lut_data_port = VD1_CGAIN_LUT_DATA_PORT; hdr_ctrl = VD1_HDR2_CTRL; cgain_coef1 = VD1_HDR2_CGAIN_COEF1; - } else if (module_sel & VD2_HDR) { + } else if (module_sel == VD2_HDR) { cgain_lut_addr_port = VD2_CGAIN_LUT_ADDR_PORT; cgain_lut_data_port = VD2_CGAIN_LUT_DATA_PORT; hdr_ctrl = VD2_HDR2_CTRL; cgain_coef1 = VD2_HDR2_CGAIN_COEF1; - } else if (module_sel & OSD1_HDR) { + } else if (module_sel == OSD1_HDR) { cgain_lut_addr_port = OSD1_CGAIN_LUT_ADDR_PORT; cgain_lut_data_port = OSD1_CGAIN_LUT_DATA_PORT; hdr_ctrl = OSD1_HDR2_CTRL; cgain_coef1 = OSD1_HDR2_CGAIN_COEF1; - } else if (module_sel & DI_HDR) { + } else if (module_sel == DI_HDR) { cgain_lut_addr_port = DI_CGAIN_LUT_ADDR_PORT; cgain_lut_data_port = DI_CGAIN_LUT_DATA_PORT; hdr_ctrl = DI_HDR2_CTRL; cgain_coef1 = DI_HDR2_CGAIN_COEF1; - } else if (module_sel & VDIN0_HDR) { + } else if (module_sel == VDIN0_HDR) { cgain_lut_addr_port = VDIN0_CGAIN_LUT_ADDR_PORT; cgain_lut_data_port = VDIN0_CGAIN_LUT_DATA_PORT; hdr_ctrl = VDIN0_HDR2_CTRL; cgain_coef1 = VDIN0_HDR2_CGAIN_COEF1; - } else if (module_sel & VDIN1_HDR) { + } else if (module_sel == VDIN1_HDR) { cgain_lut_addr_port = VDIN1_CGAIN_LUT_ADDR_PORT; cgain_lut_data_port = VDIN1_CGAIN_LUT_DATA_PORT; hdr_ctrl = VDIN1_HDR2_CTRL; @@ -1781,12 +2068,21 @@ void set_c_gain( /*cgain mode: 0->y domin*/ /*cgain mode: 1->rgb domin, use r/g/b max*/ if ((is_meson_g12b_cpu() && is_meson_rev_b()) && - (module_sel & OSD1_HDR)) { + (module_sel == OSD1_HDR)) { _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, - hdr_lut_param->cgain_en, 12, 1); + 0, 12, 1); _VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->cgain_en, 0, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_SM1)) { + if (hdr_lut_param->bitdepth == 10) + _VSYNC_WR_MPEG_REG_BITS(cgain_coef1, + 0x400, 16, 13); + else if (hdr_lut_param->bitdepth == 12) + _VSYNC_WR_MPEG_REG_BITS(cgain_coef1, + 0x1000, 16, 13); + } + if (!hdr_lut_param->cgain_en) return; @@ -1797,16 +2093,18 @@ void set_c_gain( _VSYNC_WR_MPEG_REG(cgain_lut_data_port, lut[64]); return; } - - /*cgain mode force 0*/ - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, 0, 12, 1); - VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, hdr_lut_param->cgain_en, 0, 1); + VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, + 0, 12, 1); + VSYNC_WR_MPEG_REG_BITS(hdr_ctrl, + hdr_lut_param->cgain_en, 0, 1); if (cpu_after_eq(MESON_CPU_MAJOR_ID_SM1)) { if (hdr_lut_param->bitdepth == 10) - VSYNC_WR_MPEG_REG_BITS(cgain_coef1, 0x400, 16, 13); + VSYNC_WR_MPEG_REG_BITS(cgain_coef1, + 0x400, 16, 13); else if (hdr_lut_param->bitdepth == 12) - VSYNC_WR_MPEG_REG_BITS(cgain_coef1, 0x1000, 16, 13); + VSYNC_WR_MPEG_REG_BITS(cgain_coef1, + 0x1000, 16, 13); } if (!hdr_lut_param->cgain_en) @@ -1821,22 +2119,49 @@ void set_c_gain( struct hdr_proc_lut_param_s hdr_lut_param; -void hdr_func(enum hdr_module_sel module_sel, - enum hdr_process_sel hdr_process_select) +enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct vinfo_s *vinfo) { int bit_depth; unsigned int i = 0; struct hdr_proc_mtx_param_s hdr_mtx_param; + int output_mode; + bool mtx_only_mode = false; memset(&hdr_mtx_param, 0, sizeof(struct hdr_proc_mtx_param_s)); memset(&hdr_lut_param, 0, sizeof(struct hdr_proc_lut_param_s)); - if (module_sel & (VD1_HDR | VD2_HDR | OSD1_HDR)) + if ((module_sel == OSD1_HDR) + && (is_meson_g12() || is_meson_sm1_cpu() || is_meson_tl1_cpu())) { + /* turn off OSD mtx and use HDR for g12, sm1, tl1 */ + VSYNC_WR_MPEG_REG( + VPP_WRAP_OSD1_MATRIX_EN_CTRL, 0); + if (!is_dolby_vision_on()) { + if (hdr_process_select == HDR_BYPASS) + hdr_process_select = RGB_YUV; + else if (hdr_process_select == SDR_HDR) + hdr_process_select = RGB_HDR; + else if (hdr_process_select == SDR_HLG) + hdr_process_select = RGB_HLG; + /* use in_mtx for g12b rev b, sm1, tl1 */ + if (hdr_process_select == RGB_YUV + && (is_meson_sm1_cpu() || is_meson_tl1_cpu() + || (is_meson_g12b_cpu() && is_meson_rev_b()))) + mtx_only_mode = true; + } + } + + if (module_sel == VD1_HDR || + module_sel == VD2_HDR || + module_sel == OSD1_HDR) bit_depth = 12; - else if (module_sel & (VDIN0_HDR | VDIN1_HDR | DI_HDR)) + else if (module_sel == VDIN0_HDR + || module_sel == VDIN1_HDR + || module_sel == DI_HDR) bit_depth = 10; else - return; + return hdr_process_select; if (is_meson_tl1_cpu()) bit_depth = 10; @@ -1846,7 +2171,8 @@ void hdr_func(enum hdr_module_sel module_sel, sld_eotf, sld_oetf, hlg_eotf, hlg_oetf, ootf_gain, nolinear_cgain, hlg_gain}; - if (hdr_process_select & HDR_BYPASS) { + if (hdr_process_select == HDR_BYPASS + || hdr_process_select == HDR_OFF) { /*lut parameters*/ eotf_float_gen(hdr_lut_param.eotf_lut, fun[2]); oetf_float_gen(hdr_lut_param.oetf_lut, fun[1]); @@ -1854,7 +2180,7 @@ void hdr_func(enum hdr_module_sel module_sel, nolinear_lut_gen(hdr_lut_param.cgain_lut, fun[9]); hdr_lut_param.lut_on = LUT_OFF; hdr_lut_param.bitdepth = bit_depth; - } else if (hdr_process_select & HDR_SDR) { + } else if (hdr_process_select == HDR_SDR) { /*lut parameters*/ eotf_float_gen(hdr_lut_param.eotf_lut, fun[2]); oetf_float_gen(hdr_lut_param.oetf_lut, fun[1]); @@ -1862,7 +2188,7 @@ void hdr_func(enum hdr_module_sel module_sel, nolinear_lut_gen(hdr_lut_param.cgain_lut, fun[9]); hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; - } else if (hdr_process_select & SDR_HDR) { + } else if (hdr_process_select == SDR_HDR) { /*lut parameters*/ eotf_float_gen(hdr_lut_param.eotf_lut, fun[2]); oetf_float_gen(hdr_lut_param.oetf_lut, fun[1]); @@ -1871,59 +2197,45 @@ void hdr_func(enum hdr_module_sel module_sel, hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; } else - return; + return hdr_process_select; #else /*lut parameters*/ - if (hdr_process_select & HDR_BYPASS) { - /*for g12a/g12b osd blend shift rtl bug*/ - if ((is_meson_g12a_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_a())) && - (module_sel & OSD1_HDR)) { - for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { - hdr_lut_param.oetf_lut[i] = oe_y_lut_bypass[i]; - hdr_lut_param.ogain_lut[i] = oo_y_lut_bypass[i]; - if (i < HDR2_EOTF_LUT_SIZE) - hdr_lut_param.eotf_lut[i] = - eo_y_lut_bypass[i]; - if (i < HDR2_CGAIN_LUT_SIZE) - hdr_lut_param.cgain_lut[i] = - cgain_lut_bypass[i] - 1; - } - hdr_lut_param.lut_on = LUT_ON; - hdr_lut_param.bitdepth = bit_depth; - hdr_lut_param.cgain_en = LUT_ON; - } else { - for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { - hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; - hdr_lut_param.ogain_lut[i] = - oo_y_lut_hdr_sdr[i]; - if (i < HDR2_EOTF_LUT_SIZE) - hdr_lut_param.eotf_lut[i] = - eo_y_lut_hdr[i]; - if (i < HDR2_CGAIN_LUT_SIZE) - hdr_lut_param.cgain_lut[i] = - cgain_lut1[i] - 1; - } + if (hdr_process_select == RGB_YUV) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_bypass[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_bypass[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = + eo_y_lut_bypass[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; + } + hdr_lut_param.bitdepth = bit_depth; + if (mtx_only_mode) { hdr_lut_param.lut_on = LUT_OFF; - hdr_lut_param.bitdepth = bit_depth; hdr_lut_param.cgain_en = LUT_OFF; + } else { + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.cgain_en = LUT_ON; } - } else if (hdr_process_select & HDR_SDR) { + } else if (hdr_process_select == RGB_HDR) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { - hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; - hdr_lut_param.ogain_lut[i] = oo_y_lut_hdr_sdr[i]; + hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_sdr_hdr[i]; if (i < HDR2_EOTF_LUT_SIZE) - hdr_lut_param.eotf_lut[i] = eo_y_lut_hdr[i]; + hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i]; if (i < HDR2_CGAIN_LUT_SIZE) - hdr_lut_param.cgain_lut[i] = cgain_lut1[i] - 1; + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; } - hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.cgain_en = LUT_ON; - } else if (hdr_process_select & SDR_HDR) { + } else if (hdr_process_select == RGB_HLG) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { - hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; - hdr_lut_param.ogain_lut[i] = oo_y_lut_sdr_hdr[i]; + hdr_lut_param.oetf_lut[i] = oe_y_lut_hlg[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_sdr_hlg[i]; if (i < HDR2_EOTF_LUT_SIZE) hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i]; if (i < HDR2_CGAIN_LUT_SIZE) @@ -1932,26 +2244,48 @@ void hdr_func(enum hdr_module_sel module_sel, } hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; - /*for g12a/g12b osd blend shift rtl bug*/ - if ((is_meson_g12a_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_a())) && - (module_sel & OSD1_HDR)) - hdr_lut_param.cgain_en = LUT_ON; - else - hdr_lut_param.cgain_en = LUT_OFF; - } else if (hdr_process_select & HLG_BYPASS) { + hdr_lut_param.cgain_en = LUT_ON; + } else if (hdr_process_select == HDR_BYPASS + || hdr_process_select == HLG_BYPASS) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_bypass[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_bypass[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = + eo_y_lut_bypass[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; + } + hdr_lut_param.lut_on = LUT_OFF; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_OFF; + } else if (hdr_process_select == HDR_SDR) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; hdr_lut_param.ogain_lut[i] = oo_y_lut_hdr_sdr[i]; if (i < HDR2_EOTF_LUT_SIZE) - hdr_lut_param.eotf_lut[i] = eo_y_lut_hlg[i]; + hdr_lut_param.eotf_lut[i] = eo_y_lut_hdr[i]; if (i < HDR2_CGAIN_LUT_SIZE) hdr_lut_param.cgain_lut[i] = cgain_lut1[i] - 1; } - hdr_lut_param.lut_on = LUT_OFF; + hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; hdr_lut_param.cgain_en = LUT_OFF; - } else if (hdr_process_select & HLG_SDR) { + } else if (hdr_process_select == SDR_HDR) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_sdr_hdr[i]; + if (i < HDR2_EOTF_LUT_SIZE) + 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; + } + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_OFF; + } 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]; hdr_lut_param.ogain_lut[i] = oo_y_lut_hlg_sdr[i]; @@ -1962,8 +2296,8 @@ void hdr_func(enum hdr_module_sel module_sel, } hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; - hdr_lut_param.cgain_en = LUT_ON; - } else if (hdr_process_select & HLG_HDR) { + hdr_lut_param.cgain_en = LUT_OFF; + } else if (hdr_process_select == HLG_HDR) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; hdr_lut_param.ogain_lut[i] = oo_y_lut_hlg_hdr[i]; @@ -1975,7 +2309,7 @@ void hdr_func(enum hdr_module_sel module_sel, hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; hdr_lut_param.cgain_en = LUT_ON; - } else if (hdr_process_select & SDR_HLG) { + } else if (hdr_process_select == SDR_HLG) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { hdr_lut_param.oetf_lut[i] = oe_y_lut_hlg[i]; hdr_lut_param.ogain_lut[i] = oo_y_lut_sdr_hlg[i]; @@ -1987,57 +2321,138 @@ void hdr_func(enum hdr_module_sel module_sel, } hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; - /*for g12a/g12b osd blend shift rtl bug*/ - if ((is_meson_g12a_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_a())) && - (module_sel & OSD1_HDR)) - hdr_lut_param.cgain_en = LUT_ON; - else - hdr_lut_param.cgain_en = LUT_OFF; + hdr_lut_param.cgain_en = LUT_OFF; + } else if (hdr_process_select == SDR_IPT) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; + output_mode = get_dolby_vision_mode(); + if (output_mode == DOLBY_VISION_OUTPUT_MODE_SDR10 || + output_mode == DOLBY_VISION_OUTPUT_MODE_SDR8) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_sdr_hdr_250[i]; + else if (output_mode == DOLBY_VISION_OUTPUT_MODE_HDR10) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_sdr_hdr_250[i]; + else if (output_mode == DOLBY_VISION_OUTPUT_MODE_IPT || + output_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_sdr_hdr_300[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut0[i] - 1; + } + //pr_info("\t oo_gain = %lld of 512\n", + // hdr_lut_param.ogain_lut[0]); + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_ON; + } else if (hdr_process_select == HLG_IPT) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; + // hdr_lut_param.ogain_lut[i] = oo_y_lut_bypass[i]; + output_mode = get_dolby_vision_mode(); + if (output_mode == DOLBY_VISION_OUTPUT_MODE_SDR10 || + output_mode == DOLBY_VISION_OUTPUT_MODE_SDR8) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_hdr_hdr_1200[i]; + else if (output_mode == + DOLBY_VISION_OUTPUT_MODE_HDR10) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_hdr_hdr_2500[i]; + else if (output_mode == DOLBY_VISION_OUTPUT_MODE_IPT || + output_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_hdr_hdr_4000[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = eo_y_lut_hlg[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut0[i] - 1; + } + //pr_info("\t oo_gain = %lld of 512\n", + // hdr_lut_param.ogain_lut[0]); + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_ON; + } else if (hdr_process_select == HDR_IPT) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_hdr[i]; + output_mode = get_dolby_vision_mode(); + if (output_mode == DOLBY_VISION_OUTPUT_MODE_SDR10 || + output_mode == DOLBY_VISION_OUTPUT_MODE_SDR8) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_hdr_hdr_1200[i]; + else if (output_mode == DOLBY_VISION_OUTPUT_MODE_HDR10) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_bypass[i]; + else if (output_mode == DOLBY_VISION_OUTPUT_MODE_IPT || + output_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_bypass[i]; + if (i < HDR2_EOTF_LUT_SIZE) + 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; + } + //pr_info("\t oo_gain = %lld of 512\n", + // hdr_lut_param.ogain_lut[0]); + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_ON; + } else if (hdr_process_select == HDR_HLG) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_hlg[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_hdr_hlg[i]; + if (i < HDR2_EOTF_LUT_SIZE) + 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; + } + //pr_info("\t oo_gain = %lld of 512\n", + // hdr_lut_param.ogain_lut[0]); + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_OFF; } else - return; + return hdr_process_select; +#ifdef HDR2_PRINT + pr_info("hdr: oo_gain %d = %lld-%lld-%lld, c_gain %d = %lld-%lld-%lld\n", + hdr_lut_param.lut_on, + hdr_lut_param.ogain_lut[0], hdr_lut_param.ogain_lut[74], + hdr_lut_param.ogain_lut[148], + hdr_lut_param.cgain_en, + hdr_lut_param.cgain_lut[0], hdr_lut_param.cgain_lut[32], + hdr_lut_param.cgain_lut[64]); +#endif #endif /*mtx parameters*/ - if (hdr_process_select & (HDR_BYPASS | HLG_BYPASS)) { - hdr_mtx_param.mtx_only = HDR_ONLY; - /*for g12a/g12b osd blend shift rtl bug*/ - if ((is_meson_g12a_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_a())) && - (module_sel & OSD1_HDR)) { - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; - if (i < 9) - hdr_mtx_param.mtx_gamut[i] = - bypass_coeff[i]; - if (i < 3) { - hdr_mtx_param.mtxi_pre_offset[i] = - bypass_pre[i]; - hdr_mtx_param.mtxi_pos_offset[i] = - bypass_pos[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - rgb2yuvpre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = - rgb2yuvpos[i]; - } - } - hdr_mtx_param.mtx_on = MTX_ON; - hdr_mtx_param.p_sel = HDR_BYPASS; - } else if ((is_meson_sm1_cpu() || - is_meson_tl1_cpu() || - (is_meson_g12b_cpu() && is_meson_rev_b())) && - (module_sel & OSD1_HDR)) { - /*for rtl bug osd1 green line at the bottom*/ - for (i = 0; i < 15; i++) { + /* default pre/post in:yuv_rgb out:rgb_yuv */ + for (i = 0; i < 3; i++) { + hdr_mtx_param.mtxi_pre_offset[i] = + yuv2rgbpre[i]; + hdr_mtx_param.mtxi_pos_offset[i] = + yuv2rgbpos[i]; + hdr_mtx_param.mtxo_pre_offset[i] = + rgb2yuvpre[i]; + hdr_mtx_param.mtxo_pos_offset[i] = + rgb2yuvpos[i]; + } + + if (hdr_process_select == RGB_YUV) { + hdr_mtx_param.mtx_gamut_mode = 1; + if (mtx_only_mode) { + hdr_mtx_param.mtx_only = MTX_ONLY; + for (i = 0; i < MTX_NUM_PARAM; i++) { hdr_mtx_param.mtx_in[i] = rgb2ycbcr_709[i]; hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; hdr_mtx_param.mtx_out[i] = bypass_coeff[i]; if (i < 9) hdr_mtx_param.mtx_gamut[i] = - bypass_coeff[i]; + gamut_bypass[i]; if (i < 3) { hdr_mtx_param.mtxi_pre_offset[i] = rgb2yuvpre[i]; @@ -2050,180 +2465,182 @@ void hdr_func(enum hdr_module_sel module_sel, } } hdr_mtx_param.mtx_on = MTX_OFF; - hdr_mtx_param.p_sel = HDR_BYPASS; - hdr_mtx_param.mtx_only = MTX_ONLY; } else { - for (i = 0; i < 15; i++) { + hdr_mtx_param.mtx_only = HDR_ONLY; + for (i = 0; i < MTX_NUM_PARAM; i++) { hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_out[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; if (i < 9) hdr_mtx_param.mtx_gamut[i] = - bypass_coeff[i]; + gamut_bypass[i]; if (i < 3) { hdr_mtx_param.mtxi_pre_offset[i] = bypass_pre[i]; hdr_mtx_param.mtxi_pos_offset[i] = - bypass_pre[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - bypass_pre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = bypass_pos[i]; } } - hdr_mtx_param.mtx_on = MTX_OFF; - hdr_mtx_param.p_sel = HDR_BYPASS; + hdr_mtx_param.mtx_on = MTX_ON; } - } else if (hdr_process_select & (HDR_SDR | HLG_SDR)) { + hdr_mtx_param.p_sel = RGB_YUV; + } else if (hdr_process_select == RGB_HDR || + (hdr_process_select == RGB_HLG)) { + hdr_mtx_param.mtx_gamut_mode = 1; hdr_mtx_param.mtx_only = HDR_ONLY; - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; - hdr_mtx_param.mtx_cgain[i] = rgb2ycbcr_709[i]; - hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_ncl2020[i]; - hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; - if (i < 9) { - if (hdr_process_select & HLG_SDR) - hdr_mtx_param.mtx_gamut[i] = - ncl_2020_709[i]; - else - hdr_mtx_param.mtx_gamut[i] = - ncl_2020_p3[i]; - } + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_cgain[i] = + rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + ncl_709_2020[i]; if (i < 3) { hdr_mtx_param.mtxi_pre_offset[i] = - yuv2rgbpre[i]; + bypass_pre[i]; hdr_mtx_param.mtxi_pos_offset[i] = - yuv2rgbpos[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - rgb2yuvpre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = - rgb2yuvpos[i]; + bypass_pos[i]; } } hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = hdr_process_select; + } else if (hdr_process_select == HDR_BYPASS || + hdr_process_select == HLG_BYPASS) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 1; - if (hdr_process_select & HDR_SDR) - hdr_mtx_param.p_sel = HDR_SDR; - else if (hdr_process_select & HLG_SDR) - hdr_mtx_param.p_sel = HLG_SDR; - - } else if (hdr_process_select & SDR_HDR) { + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_out[i] = bypass_coeff[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + gamut_bypass[i]; + } + hdr_mtx_param.mtx_on = MTX_OFF; + hdr_mtx_param.p_sel = hdr_process_select; + } else if (hdr_process_select == HDR_SDR || + hdr_process_select == HLG_SDR) { hdr_mtx_param.mtx_only = HDR_ONLY; - if ((is_meson_sm1_cpu() || - is_meson_tl1_cpu() || - is_meson_g12b_cpu() || - is_meson_g12a_cpu()) && - (module_sel & OSD1_HDR)) { - /*for rtl bug osd1 green line at the bottom*/ - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_cgain[i] = - rgb2ycbcr_ncl2020[i]; - hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; - hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; - if (i < 9) + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; + hdr_mtx_param.mtx_cgain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; + if (i < 9) { + if (hdr_process_select == HLG_SDR) { hdr_mtx_param.mtx_gamut[i] = - ncl_709_2020[i]; - if (i < 3) { - hdr_mtx_param.mtxi_pre_offset[i] = - bypass_pre[i]; - hdr_mtx_param.mtxi_pos_offset[i] = - bypass_pos[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - rgb2yuvpre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = - rgb2yuvpos[i]; - } - } - } else { - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = ycbcr2rgb_709[i]; - hdr_mtx_param.mtx_cgain[i] = - rgb2ycbcr_ncl2020[i]; - hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; - hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; - if (i < 9) + ncl_2020_709[i]; + } else { hdr_mtx_param.mtx_gamut[i] = - ncl_709_2020[i]; - if (i < 3) { - hdr_mtx_param.mtxi_pre_offset[i] = - yuv2rgbpre[i]; - hdr_mtx_param.mtxi_pos_offset[i] = - yuv2rgbpos[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - rgb2yuvpre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = - rgb2yuvpos[i]; + ncl_2020_p3[i]; /* 1.0 = 256 */ } } } hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = hdr_process_select; + } else if (hdr_process_select == HDR_HLG) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; + hdr_mtx_param.mtx_cgain[i] = rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + gamut_bypass[i]; + } + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = HDR_HLG; + } else if (hdr_process_select == SDR_HDR) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_709[i]; + hdr_mtx_param.mtx_cgain[i] = + rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + ncl_709_2020[i]; + } + hdr_mtx_param.mtx_on = MTX_ON; hdr_mtx_param.p_sel = SDR_HDR; - } else if (hdr_process_select & HLG_HDR) { + } else if (hdr_process_select == HLG_HDR) { hdr_mtx_param.mtx_only = HDR_ONLY; - for (i = 0; i < 15; i++) { + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < MTX_NUM_PARAM; i++) { hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; if (i < 9) - hdr_mtx_param.mtx_gamut[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_gamut[i] = gamut_bypass[i]; } hdr_mtx_param.mtx_on = MTX_ON; hdr_mtx_param.p_sel = HLG_HDR; - } else if (hdr_process_select & SDR_HLG) { + } else if (hdr_process_select == SDR_HLG) { hdr_mtx_param.mtx_only = HDR_ONLY; - if ((is_meson_sm1_cpu() || - is_meson_tl1_cpu() || - is_meson_g12b_cpu() || - is_meson_g12a_cpu()) && - (module_sel & OSD1_HDR)) { - /*for rtl bug osd1 green line at the bottom*/ - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_cgain[i] = - rgb2ycbcr_ncl2020[i]; - hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; - hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; - if (i < 9) - hdr_mtx_param.mtx_gamut[i] = - ncl_709_2020[i]; - if (i < 3) { - hdr_mtx_param.mtxi_pre_offset[i] = - bypass_pre[i]; - hdr_mtx_param.mtxi_pos_offset[i] = - bypass_pos[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - rgb2yuvpre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = - rgb2yuvpos[i]; - } - } - } else { - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = ycbcr2rgb_709[i]; - hdr_mtx_param.mtx_cgain[i] = - rgb2ycbcr_ncl2020[i]; - hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; - hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; - if (i < 9) - hdr_mtx_param.mtx_gamut[i] = + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_709[i]; + hdr_mtx_param.mtx_cgain[i] = + rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = ncl_709_2020[i]; - if (i < 3) { - hdr_mtx_param.mtxi_pre_offset[i] = - yuv2rgbpre[i]; - hdr_mtx_param.mtxi_pos_offset[i] = - yuv2rgbpos[i]; - hdr_mtx_param.mtxo_pre_offset[i] = - rgb2yuvpre[i]; - hdr_mtx_param.mtxo_pos_offset[i] = - rgb2yuvpos[i]; - } - } } hdr_mtx_param.mtx_on = MTX_ON; hdr_mtx_param.p_sel = SDR_HLG; + } else if (hdr_process_select == SDR_IPT) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 2; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_709[i]; + hdr_mtx_param.mtx_cgain[i] = lms2ipt_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_out[i] = lms2ipt_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + rgb709_to_lms2020[i]; + } + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = SDR_IPT; + } else if (hdr_process_select == HLG_IPT) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 2; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; + hdr_mtx_param.mtx_cgain[i] = lms2ipt_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_out[i] = lms2ipt_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = rgb2lms_ncl2020[i]; + } + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = HLG_IPT; + } else if (hdr_process_select == HDR_IPT) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 2; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; + hdr_mtx_param.mtx_cgain[i] = lms2ipt_ncl2020[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_ncl2020[i]; + hdr_mtx_param.mtx_out[i] = lms2ipt_ncl2020[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = rgb2lms_ncl2020[i]; + } + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = HDR_IPT; } set_hdr_matrix(module_sel, HDR_IN_MTX, &hdr_mtx_param); @@ -2239,6 +2656,8 @@ void hdr_func(enum hdr_module_sel module_sel, set_hdr_matrix(module_sel, HDR_OUT_MTX, &hdr_mtx_param); set_c_gain(module_sel, &hdr_lut_param); + + return hdr_process_select; } /*G12A matrix setting*/ @@ -2261,7 +2680,7 @@ void mtx_setting(enum vpp_matrix_e mtx_sel, unsigned int matrix_pre_offset2 = 0; unsigned int matrix_en_ctrl = 0; - if (mtx_sel & VD1_MTX) { + if (mtx_sel == VD1_MTX) { matrix_coef00_01 = VPP_VD1_MATRIX_COEF00_01; matrix_coef02_10 = VPP_VD1_MATRIX_COEF02_10; matrix_coef11_12 = VPP_VD1_MATRIX_COEF11_12; @@ -2278,7 +2697,7 @@ void mtx_setting(enum vpp_matrix_e mtx_sel, matrix_en_ctrl = VPP_VD1_MATRIX_EN_CTRL; WRITE_VPP_REG_BITS(VPP_VD1_MATRIX_EN_CTRL, mtx_on, 0, 1); - } else if (mtx_sel & POST2_MTX) { + } else if (mtx_sel == POST2_MTX) { matrix_coef00_01 = VPP_POST2_MATRIX_COEF00_01; matrix_coef02_10 = VPP_POST2_MATRIX_COEF02_10; matrix_coef11_12 = VPP_POST2_MATRIX_COEF11_12; @@ -2295,7 +2714,7 @@ void mtx_setting(enum vpp_matrix_e mtx_sel, matrix_en_ctrl = VPP_POST2_MATRIX_EN_CTRL; WRITE_VPP_REG_BITS(VPP_POST2_MATRIX_EN_CTRL, mtx_on, 0, 1); - } else if (mtx_sel & POST_MTX) { + } else if (mtx_sel == POST_MTX) { matrix_coef00_01 = VPP_POST_MATRIX_COEF00_01; matrix_coef02_10 = VPP_POST_MATRIX_COEF02_10; matrix_coef11_12 = VPP_POST_MATRIX_COEF11_12; @@ -2344,15 +2763,3 @@ void mtx_setting(enum vpp_matrix_e mtx_sel, break; } } -/*for rtl bug osd1 green line at the bottom, used for dv*/ -void enable_osd1_mtx(unsigned int en) -{ - if (is_meson_g12b_cpu() && is_meson_rev_b()) - _VSYNC_WR_MPEG_REG_BITS(OSD1_HDR2_MATRIXI_EN_CTRL, en, 0, 1); - else if ((is_meson_g12b_cpu() && is_meson_rev_a()) || - is_meson_g12a_cpu()) - VSYNC_WR_MPEG_REG_BITS(OSD1_HDR2_MATRIXO_EN_CTRL, en, 0, 1); - else - VSYNC_WR_MPEG_REG_BITS(OSD1_HDR2_MATRIXI_EN_CTRL, en, 0, 1); -} -EXPORT_SYMBOL(enable_osd1_mtx); diff --git a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h index e570d85..4c15106 100644 --- a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h +++ b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h @@ -16,6 +16,7 @@ */ #include +#include #ifndef MAX #define MAX(x1, x2) (double)(x1 > x2 ? x1 : x2) @@ -50,43 +51,48 @@ int64_t FloatRev(int64_t iA); int64_t FloatCon(int64_t iA, int MOD); enum hdr_module_sel { - VD1_HDR = 0x1, - VD2_HDR = 0x2, - OSD1_HDR = 0x4, - VDIN0_HDR = 0x8, - VDIN1_HDR = 0x10, - DI_HDR = 0x20, + VD1_HDR = 1, + VD2_HDR = 2, + OSD1_HDR = 3, + VDIN0_HDR = 4, + VDIN1_HDR = 5, + DI_HDR = 6, HDR_MAX }; enum hdr_matrix_sel { - HDR_IN_MTX = 0x1, - HDR_GAMUT_MTX = 0x2, - HDR_OUT_MTX = 0x4, + HDR_IN_MTX = 1, + HDR_GAMUT_MTX = 2, + HDR_OUT_MTX = 3, HDR_MTX_MAX }; enum hdr_lut_sel { - HDR_EOTF_LUT = 0x1, - HDR_OOTF_LUT = 0x2, - HDR_OETF_LUT = 0x4, - HDR_CGAIN_LUT = 0x8, + HDR_EOTF_LUT = 1, + HDR_OOTF_LUT = 2, + HDR_OETF_LUT = 3, + HDR_CGAIN_LUT = 4, HDR_LUT_MAX }; enum hdr_process_sel { - HDR_BYPASS = 0x1, - HDR_SDR = 0x2, - SDR_HDR = 0x4, - HLG_BYPASS = 0x8, - HLG_SDR = 0x10, - HLG_HDR = 0x20, - SDR_HLG = 0X40, - HDRPLUS_SDR = 0x80, + HDR_BYPASS = 1, + HDR_SDR = 2, + SDR_HDR = 3, + HLG_BYPASS = 4, + HLG_SDR = 5, + HLG_HDR = 6, + SDR_HLG = 7, + SDR_IPT = 8, + HDR_IPT = 9, + HLG_IPT = 10, + HDR_HLG = 11, + RGB_YUV = 12, + RGB_HDR = 13, + RGB_HLG = 14, HDR_p_MAX }; - #define MTX_ON 1 #define MTX_OFF 0 @@ -101,13 +107,16 @@ enum hdr_process_sel { #define HDR2_OETF_LUT_SIZE 149 #define HDR2_CGAIN_LUT_SIZE 65 + +#define MTX_NUM_PARAM 16 struct hdr_proc_mtx_param_s { int mtx_only; - int mtx_in[15]; + int mtx_in[MTX_NUM_PARAM]; int mtx_gamut[9]; - int mtx_cgain[15]; - int mtx_ogain[15]; - int mtx_out[15]; + int mtx_gamut_mode; + int mtx_cgain[MTX_NUM_PARAM]; + int mtx_ogain[MTX_NUM_PARAM]; + int mtx_out[MTX_NUM_PARAM]; int mtxi_pre_offset[3]; int mtxi_pos_offset[3]; int mtxo_pre_offset[3]; @@ -116,6 +125,10 @@ struct hdr_proc_mtx_param_s { enum hdr_process_sel p_sel; }; +#define OO_BITS 12 +#define OO_GAIN_SHIFT 3 +#define OO_NOR (OO_BITS - OO_GAIN_SHIFT) + struct hdr_proc_lut_param_s { int64_t eotf_lut[143]; int64_t oetf_lut[149]; @@ -130,8 +143,9 @@ typedef int64_t(*MenuFun)(int64_t); void eotf_float_gen(int64_t *o_out, MenuFun eotf); void oetf_float_gen(int64_t *bin_e, MenuFun oetf); void nolinear_lut_gen(int64_t *bin_c, MenuFun cgain); -extern void hdr_func(enum hdr_module_sel module_sel, - enum hdr_process_sel hdr_process_select); +extern enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct vinfo_s *vinfo); /*G12A vpp matrix*/ enum vpp_matrix_e { VD1_MTX = 0x1, diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 4a1cace..18451d4 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -1009,11 +1009,13 @@ u32 get_video_enabled(void) { return video_enabled; } +EXPORT_SYMBOL(get_video_enabled); u32 get_videopip_enabled(void) { return video2_enabled; } +EXPORT_SYMBOL(get_videopip_enabled); /* show first frame*/ static bool show_first_frame_nosync; @@ -5995,7 +5997,7 @@ struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf) struct vframe_s *toggle_vf = NULL; int width_bl, width_el; int height_bl, height_el; - int ret = dolby_vision_update_metadata(vf); + int ret; if (!is_dolby_vision_el_disable() || for_dolby_vision_certification()) cur_dispbuf2 = dolby_vision_vf_peek_el(vf); @@ -6051,11 +6053,24 @@ struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf) ori2_end_y_lines = height_el - 1; } + + if (!get_video_enabled()) { + /* when video layer off */ + /* not need to update setting */ + dolby_vision_set_toggle_flag(0); + return NULL; + }; + + ret = dolby_vision_update_metadata(vf); if (ret == 0) { /* setting generated for this frame */ /* or DOVI in bypass mode */ toggle_vf = vf; dolby_vision_set_toggle_flag(1); + } else if (ret == 1) { + /* both dolby and hdr module bypass */ + toggle_vf = vf; + dolby_vision_set_toggle_flag(0); } else { /* fail generating setting for this frame */ toggle_vf = NULL; @@ -6572,6 +6587,7 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) int toggle_cnt; struct vframe_s *toggle_vf = NULL; struct vframe_s *toggle_frame = NULL; + struct vframe_s *toggle_pip_frame = NULL; int video1_off_req = 0; int video2_off_req = 0; struct vframe_s *cur_dispbuf_back = cur_dispbuf; @@ -6816,8 +6832,11 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) #endif #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION /* check video frame before VECM process */ - if (is_dolby_vision_enable() && vf) + if (is_dolby_vision_enable() && vf) { dolby_vision_check_hdr10(vf); + dolby_vision_check_hdr10plus(vf); + dolby_vision_check_hlg(vf); + } #endif #ifdef CONFIG_TVIN_VDIN /* patch for m8 4k2k wifidisplay bandwidth bottleneck */ @@ -7167,7 +7186,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) } #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) - refresh_on_vs(vf); if (amvecm_on_vs( (cur_dispbuf != &vf_local) ? cur_dispbuf : NULL, @@ -7177,7 +7195,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) 0, 0, 0, - 0) == 1) + 0, + VD1_PATH) == 1) break; #endif vsync_toggle_frame(vf, __LINE__); @@ -7262,7 +7281,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) break; #endif #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) - refresh_on_vs(vf); if (amvecm_on_vs( (cur_dispbuf != &vf_local) ? cur_dispbuf : NULL, @@ -7272,7 +7290,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) 0, 0, 0, - 0) == 1) + 0, + VD1_PATH) == 1) break; #endif vf = video_vf_get(); @@ -7319,7 +7338,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) } else vsync_toggle_frame(cur_dispbuf, __LINE__); - if (is_dolby_vision_enable()) { + if (is_dolby_vision_enable() + && is_dolby_vision_video_on()) { pause_vf = cur_dispbuf; video_pause_global = 1; } else { @@ -7331,8 +7351,10 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) && is_dolby_vision_enable()) { toggle_vf = pause_vf; dolby_vision_parse_metadata( - cur_dispbuf, 0, false); + cur_dispbuf, 2, false); dolby_vision_set_toggle_flag(1); + //use previous setting + //pr_info("DOLBY: pause frame %p\n", toggle_vf); } break; } @@ -7361,11 +7383,38 @@ SET_FILTER: pip_toggle_frame(cur_pipbuf); while (vf) { - vf = pip_vf_get(); - if (vf) { - if (!vf->frame_dirty) + if (!vf->frame_dirty) { + if (amvecm_on_vs( + vf, + vf, CSC_FLAG_CHECK_OUTPUT, + cur_frame_par ? + cur_frame_par->supsc1_hori_ratio + : 0, + cur_frame_par ? + cur_frame_par->supsc1_vert_ratio + : 0, + cur_frame_par ? + cur_frame_par->spsc1_w_in : + 0, + cur_frame_par ? + cur_frame_par->spsc1_h_in : + 0, + cur_frame_par ? + cur_frame_par->cm_input_w : + 0, + cur_frame_par ? + cur_frame_par->cm_input_h : + 0, + VD2_PATH) == 1) + break; + vf = pip_vf_get(); + if (vf) { pip_toggle_frame(vf); - else + toggle_pip_frame = vf; + } + } else { + vf = pip_vf_get(); + if (vf) pip_vf_put(vf); } vf = pip_vf_peek(); @@ -7379,29 +7428,62 @@ SET_FILTER: } #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) - amvecm_on_vs( - (cur_dispbuf != &vf_local) - ? cur_dispbuf : NULL, - toggle_frame, - toggle_frame ? CSC_FLAG_TOGGLE_FRAME : 0, - cur_frame_par ? - cur_frame_par->supsc1_hori_ratio : - 0, - cur_frame_par ? - cur_frame_par->supsc1_vert_ratio : - 0, - cur_frame_par ? - cur_frame_par->spsc1_w_in : - 0, - cur_frame_par ? - cur_frame_par->spsc1_h_in : - 0, - cur_frame_par ? - cur_frame_par->cm_input_w : - 0, - cur_frame_par ? - cur_frame_par->cm_input_h : - 0); + if (toggle_frame) + refresh_on_vs(toggle_frame); + else if (cur_dispbuf) + refresh_on_vs(cur_dispbuf); + + amvecm_on_vs( + (cur_dispbuf != &vf_local) + ? cur_dispbuf : NULL, + toggle_frame, + toggle_frame ? CSC_FLAG_TOGGLE_FRAME : 0, + cur_frame_par ? + cur_frame_par->supsc1_hori_ratio : + 0, + cur_frame_par ? + cur_frame_par->supsc1_vert_ratio : + 0, + cur_frame_par ? + cur_frame_par->spsc1_w_in : + 0, + cur_frame_par ? + cur_frame_par->spsc1_h_in : + 0, + cur_frame_par ? + cur_frame_par->cm_input_w : + 0, + cur_frame_par ? + cur_frame_par->cm_input_h : + 0, + VD1_PATH); + +#ifdef VIDEO_PIP + amvecm_on_vs( + (cur_pipbuf != &local_pip) + ? cur_pipbuf : NULL, + toggle_pip_frame, + toggle_pip_frame ? CSC_FLAG_TOGGLE_FRAME : 0, + cur_frame_par ? + cur_frame_par->supsc1_hori_ratio : + 0, + cur_frame_par ? + cur_frame_par->supsc1_vert_ratio : + 0, + cur_frame_par ? + cur_frame_par->spsc1_w_in : + 0, + cur_frame_par ? + cur_frame_par->spsc1_h_in : + 0, + cur_frame_par ? + cur_frame_par->cm_input_w : + 0, + cur_frame_par ? + cur_frame_par->cm_input_h : + 0, + VD2_PATH); +#endif #endif #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -7412,11 +7494,13 @@ SET_FILTER: /* force toggle when keeping frame after playing */ if ((cur_dispbuf == &vf_local) && !toggle_vf - && is_dolby_vision_on()) { + && is_dolby_vision_video_on() + && get_video_enabled()) { toggle_vf = cur_dispbuf; dolby_vision_parse_metadata( - cur_dispbuf, 2, false); + toggle_vf, 2, false); dolby_vision_set_toggle_flag(1); + //pr_info("DOLBY: keep frame %p", toggle_vf); } /* pause mode was moved to video display property */ #if 0 @@ -7473,7 +7557,8 @@ SET_FILTER: toggle_vf->compHeight : toggle_vf->height; frame_size = (h_size << 16) | v_size; } - dolby_vision_process(toggle_vf, frame_size, pps_state); + dolby_vision_process((cur_dispbuf != &vf_local) + ? cur_dispbuf : toggle_vf, frame_size, pps_state); dolby_vision_update_setting(); } #endif @@ -13059,6 +13144,12 @@ int vout_notify_callback(struct notifier_block *block, unsigned long cmd, vsync_pts_inc_scale_base = vinfo->sync_duration_num; 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 */ + if (is_dolby_vision_enable()) + dolby_vision_set_toggle_flag(1); +#endif break; case VOUT_EVENT_OSD_PREBLEND_ENABLE: break; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 54ea409..3841aae 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -73,13 +73,14 @@ static int set_disp_mode_auto(void); static void hdmitx_get_edid(struct hdmitx_dev *hdev); static void hdmitx_set_drm_pkt(struct master_display_info_s *data); static void hdmitx_set_vsif_pkt(enum eotf_type type, enum mode_type - tunnel_mode, struct dv_vsif_para *data); + tunnel_mode, struct dv_vsif_para *data, bool switch_to_sdr); static void hdmitx_set_hdr10plus_pkt(unsigned int flag, struct hdr10plus_para *data); static void hdmitx_set_emp_pkt(unsigned char *data, unsigned int type, unsigned int size); static int check_fbc_special(unsigned char *edid_dat); static struct vinfo_s *hdmitx_get_current_vinfo(void); +static void hdmitx_fmt_attr(struct hdmitx_dev *hdev); static DEFINE_MUTEX(setclk_mutex); static DEFINE_MUTEX(getedid_mutex); @@ -607,8 +608,12 @@ static ssize_t show_attr(struct device *dev, struct device_attribute *attr, char *buf) { int pos = 0; - - pos += snprintf(buf+pos, PAGE_SIZE, "%s\n\r", hdmitx_device.fmt_attr); + if (!memcmp(hdmitx_device.fmt_attr, "default,", 7)) { + memset(hdmitx_device.fmt_attr, 0, + sizeof(hdmitx_device.fmt_attr)); + hdmitx_fmt_attr(&hdmitx_device); + } + pos += snprintf(buf+pos, PAGE_SIZE, "%s\n", hdmitx_device.fmt_attr); return pos; } @@ -617,6 +622,14 @@ ssize_t store_attr(struct device *dev, { strncpy(hdmitx_device.fmt_attr, buf, sizeof(hdmitx_device.fmt_attr)); hdmitx_device.fmt_attr[15] = '\0'; + if (!memcmp(hdmitx_device.fmt_attr, "rgb", 3)) + hdmitx_device.para->cs = COLORSPACE_RGB444; + else if (!memcmp(hdmitx_device.fmt_attr, "422", 3)) + hdmitx_device.para->cs = COLORSPACE_YUV422; + else if (!memcmp(hdmitx_device.fmt_attr, "420", 3)) + hdmitx_device.para->cs = COLORSPACE_YUV420; + else + hdmitx_device.para->cs = COLORSPACE_YUV444; return count; } /*aud_mode attr*/ @@ -1387,7 +1400,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) } static void hdmitx_set_vsif_pkt(enum eotf_type type, - enum mode_type tunnel_mode, struct dv_vsif_para *data) + enum mode_type tunnel_mode, struct dv_vsif_para *data, bool signal_sdr) { struct hdmitx_dev *hdev = &hdmitx_device; struct dv_vsif_para para = {0}; @@ -1484,14 +1497,17 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, else hdev->HWOp.SetPacket( HDMI_PACKET_VEND, NULL, NULL); - hdev->HWOp.CntlConfig(hdev, - CONF_AVI_RGBYCC_INDIC, hdev->para->cs); - hdev->HWOp.CntlConfig(hdev, - CONF_AVI_Q01, RGB_RANGE_LIM); - hdev->HWOp.CntlConfig(hdev, - CONF_AVI_YQ01, YCC_RANGE_LIM); - hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, - CLR_AVI_BT2020);/*BT709*/ + if (signal_sdr) { + pr_info("hdmitx: H14b VSIF, switching signal to SDR\n"); + hdev->HWOp.CntlConfig(hdev, + CONF_AVI_RGBYCC_INDIC, hdev->para->cs); + hdev->HWOp.CntlConfig(hdev, + CONF_AVI_Q01, RGB_RANGE_DEFAULT); + hdev->HWOp.CntlConfig(hdev, + CONF_AVI_YQ01, YCC_RANGE_LIM); + hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020);/*BT709*/ + } } } @@ -1503,6 +1519,8 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, if (data == NULL) data = ¶ + len = 0x1b; + /*4k vsif package */ if ((vic == HDMI_3840x2160p30_16x9) || (vic == HDMI_3840x2160p25_16x9) || @@ -1513,14 +1531,13 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, switch (type) { case EOTF_T_DOLBYVISION: case EOTF_T_LL_MODE: - len = 0x1b; hdev->dv_src_feature = 1; break; case EOTF_T_HDR10: case EOTF_T_SDR: case EOTF_T_NULL: default: - len = 0x5; + hdev->dv_src_feature = 0; break; } @@ -1605,14 +1622,18 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } else hdev->HWOp.SetPacket( HDMI_PACKET_VEND, NULL, NULL); - hdev->HWOp.CntlConfig(hdev, - CONF_AVI_RGBYCC_INDIC, hdev->para->cs); - hdev->HWOp.CntlConfig(hdev, - CONF_AVI_Q01, RGB_RANGE_LIM); - hdev->HWOp.CntlConfig(hdev, - CONF_AVI_YQ01, YCC_RANGE_LIM); - hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, + + if (signal_sdr) { + pr_info("hdmitx: Dolby VSIF, switching signal to SDR\n"); + hdev->HWOp.CntlConfig(hdev, + CONF_AVI_RGBYCC_INDIC, hdev->para->cs); + hdev->HWOp.CntlConfig(hdev, + CONF_AVI_Q01, RGB_RANGE_DEFAULT); + hdev->HWOp.CntlConfig(hdev, + CONF_AVI_YQ01, YCC_RANGE_LIM); + hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, CLR_AVI_BT2020);/*BT709*/ + } } } } @@ -2049,7 +2070,7 @@ static ssize_t store_config(struct device *dev, data.features = 0x00091200; hdmitx_set_drm_pkt(&data); } else if (strncmp(buf, "vsif", 4) == 0) - hdmitx_set_vsif_pkt(buf[4] - '0', buf[5] == '1', NULL); + hdmitx_set_vsif_pkt(buf[4] - '0', buf[5] == '1', NULL, true); else if (strncmp(buf, "emp", 3) == 0) { if (hdmitx_device.chip_type >= MESON_CPU_ID_G12A) hdmitx_set_emp_pkt(NULL, 1, 1); @@ -4100,7 +4121,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) return; } /*after plugout, DV mode can't be supported*/ - hdmitx_set_vsif_pkt(0, 0, NULL); + hdmitx_set_vsif_pkt(0, 0, NULL, true); hdmitx_set_hdr10plus_pkt(0, NULL); hdev->ready = 0; if (hdev->repeater_tx) @@ -4271,7 +4292,7 @@ static int get_dt_vend_init_data(struct device_node *np, return 0; } -static void hdmitx_init_fmt_attr(struct hdmitx_dev *hdev) +static void hdmitx_fmt_attr(struct hdmitx_dev *hdev) { if (strlen(hdev->fmt_attr) >= 8) { pr_info(SYS "fmt_attr %s\n", hdev->fmt_attr); @@ -4317,6 +4338,20 @@ static void hdmitx_init_fmt_attr(struct hdmitx_dev *hdev) pr_info(SYS "fmt_attr %s\n", hdev->fmt_attr); } +static void hdmitx_init_fmt_attr(struct hdmitx_dev *hdev) +{ + if (strlen(hdev->fmt_attr) >= 8) { + pr_info(SYS "fmt_attr %s\n", hdev->fmt_attr); + return; + } + if ((hdev->para->cd == COLORDEPTH_RESERVED) && + (hdev->para->cs == COLORSPACE_RESERVED)) { + strcpy(hdev->fmt_attr, "default"); + } else + hdmitx_fmt_attr(hdev); + pr_info(SYS "fmt_attr %s\n", hdev->fmt_attr); +} + /* for notify to cec */ static BLOCKING_NOTIFIER_HEAD(hdmitx_event_notify_list); int hdmitx_event_notifier_regist(struct notifier_block *nb) diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h index b44d1e0..227cd6d 100644 --- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h +++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h @@ -23,9 +23,34 @@ #include +#define DOLBY_VISION_OUTPUT_MODE_IPT 0 +#define DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL 1 +#define DOLBY_VISION_OUTPUT_MODE_HDR10 2 +#define DOLBY_VISION_OUTPUT_MODE_SDR10 3 +#define DOLBY_VISION_OUTPUT_MODE_SDR8 4 +#define DOLBY_VISION_OUTPUT_MODE_BYPASS 5 + +/* STB: if sink support DV, always output DV*/ +/* else always output SDR/HDR */ +/* TV: when source is DV, convert to SDR */ +#define DOLBY_VISION_FOLLOW_SINK 0 + +/* STB: output DV only if source is DV*/ +/* and sink support DV*/ +/* else always output SDR/HDR */ +/* TV: when source is DV or HDR, convert to SDR */ +#define DOLBY_VISION_FOLLOW_SOURCE 1 + +/* STB: always follow dolby_vision_mode */ +/* TV: if set dolby_vision_mode to SDR8,*/ +/* convert all format to SDR by TV core,*/ +/* else bypass Dolby Vision */ +#define DOLBY_VISION_FORCE_OUTPUT_MODE 2 + extern void enable_dolby_vision(int enable); extern bool is_dolby_vision_enable(void); extern bool is_dolby_vision_on(void); +extern bool is_dolby_vision_video_on(void); extern bool for_dolby_vision_certification(void); extern void set_dolby_vision_mode(int mode); extern int get_dolby_vision_mode(void); @@ -60,6 +85,8 @@ extern void tv_dolby_vision_crc_clear(int flag); extern char *tv_dolby_vision_get_crc(u32 *len); extern void tv_dolby_vision_insert_crc(bool print); extern int dolby_vision_check_hdr10(struct vframe_s *vf); +extern int dolby_vision_check_hlg(struct vframe_s *vf); +extern int dolby_vision_check_hdr10plus(struct vframe_s *vf); extern void tv_dolby_vision_dma_table_modify( u32 tbl_id, uint64_t value); extern void tv_dolby_vision_efuse_info(void); @@ -75,6 +102,8 @@ extern int enable_rgb_to_yuv_matrix_for_dvll( 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); +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); #endif diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h index 68cc471..269f00e 100644 --- a/include/linux/amlogic/media/amvecm/amvecm.h +++ b/include/linux/amlogic/media/amvecm/amvecm.h @@ -97,9 +97,13 @@ #define MTX_BYPASS_RGB_OGO (1 << 0) #define MTX_RGB2YUVL_RGB_OGO (1 << 1) -#define SDR_SOURCE (1 << 0) -#define HDR10_SOURCE (1 << 1) -#define HLG_SOURCE (1 << 2) +#define UNKNOWN_SOURCE 0 +#define HDR10_SOURCE 1 +#define HDR10PLUS_SOURCE 2 +#define DOVI_SOURCE 3 +#define PRIMESL_SOURCE 4 +#define HLG_SOURCE 5 +#define SDR_SOURCE 6 enum cm_hist_e { CM_HUE_HIST = 0, @@ -270,11 +274,12 @@ enum vpp_matrix_csc_e { }; enum hdr_type_e { - HDRTYPE_NONE = 0, - HDRTYPE_SDR = 0x1, - HDRTYPE_HDR10 = 0x2, - HDRTYPE_HLG = 0x4, - HDRTYPE_MAX, + HDRTYPE_NONE = UNKNOWN_SOURCE, + HDRTYPE_SDR = SDR_SOURCE, + HDRTYPE_HDR10 = HDR10_SOURCE, + HDRTYPE_HLG = HLG_SOURCE, + HDRTYPE_HDR10PLUS = HDR10PLUS_SOURCE, + HDRTYPE_DOVI = DOVI_SOURCE }; enum vpp_transfer_characteristic_e { @@ -351,6 +356,12 @@ struct vecm_match_data_s { u32 vlk_pll_sel;/*independent panel pll and hdmitx pll*/ }; +enum vd_path_e { + VD1_PATH = 0, + VD2_PATH = 1, + VD_PATH_MAX = 2 +}; + /*overscan: *length 0~31bit :number of crop; *src_timing: bit31: on: load/save all crop @@ -464,7 +475,8 @@ extern int amvecm_on_vs( unsigned int sps_w_in, unsigned int sps_h_in, unsigned int cm_in_w, - unsigned int cm_in_h); + unsigned int cm_in_h, + enum vd_path_e vd_path); extern void refresh_on_vs(struct vframe_s *vf); extern void pc_mode_process(void); extern void pq_user_latch_process(void); diff --git a/include/linux/amlogic/media/vout/vinfo.h b/include/linux/amlogic/media/vout/vinfo.h index ee462b0..26294cb 100644 --- a/include/linux/amlogic/media/vout/vinfo.h +++ b/include/linux/amlogic/media/vout/vinfo.h @@ -102,6 +102,7 @@ struct hdr10_plus_info { struct hdr_info { /* RX EDID hdr support types */ u32 hdr_support; + unsigned char rawdata[7]; /* *dynamic_info[0] expresses type1's parameters certainly *dynamic_info[1] expresses type2's parameters certainly @@ -219,7 +220,8 @@ struct vout_device_s { const struct dv_info *dv_info; void (*fresh_tx_hdr_pkt)(struct master_display_info_s *data); void (*fresh_tx_vsif_pkt)(enum eotf_type type, - enum mode_type tunnel_mode, struct dv_vsif_para *data); + enum mode_type tunnel_mode, struct dv_vsif_para *data, + bool signal_sdr); void (*fresh_tx_hdr10plus_pkt)(unsigned int flag, struct hdr10plus_para *data); void (*fresh_tx_emp_pkt)(unsigned char *data, unsigned int type, -- 2.7.4