From bbc9d305edc0ca83faff2a14ca4f7ebececf706a Mon Sep 17 00:00:00 2001 From: Gaowei Zhao Date: Fri, 4 Aug 2023 15:11:27 +0800 Subject: [PATCH] hdmirx: support black pattern for t7~t5w [1/1] PD#SWPL-135529 Problem: Not responding to avmute Solution: set black pattern in vdin Verify: T7 Change-Id: I576696a2b36e761b89774212d824d0f7cde18938 Signed-off-by: Gaowei Zhao --- drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h | 3 +- drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c | 10 +++- drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h | 1 + drivers/media/vin/tvin/vdin/vdin_ctl.c | 66 +++++++++++++++++++-- drivers/media/vin/tvin/vdin/vdin_drv.c | 12 ++++ 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 9bb05f81d..c8d7a570c 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -116,7 +116,8 @@ /* 2023.05.24 fix 1366*768 identify to 1360*768 */ /* 2023.8.3 phy flow and aud pkt judge */ /* 2023.08.01 add t3x poweroff */ -#define RX_VER2 "ver.2023/8/7" +/* 2023.08.15 support black pattern for t7~t5w */ +#define RX_VER2 "ver.2023/08/15" #define PFIFO_SIZE 160 #define HDCP14_KEY_SIZE 368 diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c index e47920fb5..c38630b1c 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -5108,6 +5108,8 @@ void hdmirx_set_vp_mapping(enum colorspace_e cs, u8 port) */ void hdmirx_set_video_mute(bool mute, u8 port) { + static bool pre_mute_flag; + /* bluescreen cfg */ if (rx_info.chip_id >= CHIP_ID_T5M) { if (rx[port].pre.colorspace == E_COLOR_RGB) { @@ -5125,7 +5127,13 @@ void hdmirx_set_video_mute(bool mute, u8 port) hdmirx_wr_bits_top_common(TOP_OVID_OVERRIDE0, _BIT(30), mute); hdmirx_wr_bits_top_common_1(TOP_OVID_OVERRIDE0, _BIT(30), mute); } else if (rx_info.chip_id >= CHIP_ID_T7 && rx_info.chip_id < CHIP_ID_T5M) { - /* not support black pattern */ + if (mute && (rx_pkt_chk_attach_drm(port) || + rx[port].vs_info_details.dolby_vision_flag != DV_NULL)) + return; + if (mute != pre_mute_flag) { + vdin_set_black_pattern(mute); + pre_mute_flag = mute; + } } else { if (rx[port].pre.colorspace == E_COLOR_RGB) { hdmirx_wr_bits_dwc(DWC_HDMI_VM_CFG_CH2, MSK(16, 0), 0x00); diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h index f86a9c8ea..362e8cdad 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -3472,4 +3472,5 @@ void rx_edid_module_reset(void); u32 hdmirx_rd_top_common_1(u32 addr); void hdmirx_wr_bits_top_common_1(u32 addr, u32 mask, u32 value); void cor_init(u8 port); +void vdin_set_black_pattern(bool mute); #endif diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl.c b/drivers/media/vin/tvin/vdin/vdin_ctl.c index 7668d6f0f..88a8f0a57 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl.c @@ -1660,6 +1660,10 @@ vdin_set_color_matrix(enum vdin_matrix_sel_e matrix_sel, unsigned int offset, /*struct vdin_matrix_lup_s *matrix_tbl;*/ struct tvin_format_s *fmt_info = tvin_fmt_p; + if (!fmt_info) { + pr_err("%s fmt_info NULL\n", __func__); + return VDIN_MATRIX_NULL; + } switch (format_convert) { case VDIN_MATRIX_XXX_YUV_BLACK: matrix_csc = VDIN_MATRIX_XXX_YUV601_BLACK; @@ -5053,6 +5057,42 @@ bool vdin_is_convert_to_nv21(u32 format_convert) return false; } +static bool vdin_is_convert_to_yuv(u32 format_convert) +{ + if (format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || + format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444 || + format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || + format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || + format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422 || + format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) + return true; + else + return false; +} + +static bool vdin_is_convert_to_rgb(u32 format_convert) +{ + if (format_convert == VDIN_FORMAT_CONVERT_YUV_RGB || + format_convert == VDIN_FORMAT_CONVERT_YUV_GBR || + format_convert == VDIN_FORMAT_CONVERT_YUV_BRG || + format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) + return true; + else + return false; +} + +static bool vdin_is_rgb_input(enum tvin_color_fmt_e color_format) +{ + if (color_format == TVIN_RGB444 || + color_format == TVIN_BGGR || + color_format == TVIN_RGGB || + color_format == TVIN_GBRG || + color_format == TVIN_GRBG) + return true; + else + return false; +} + bool vdin_is_4k(struct vdin_dev_s *devp) { if (devp->h_active >= 2500 && devp->v_active >= 1400) @@ -6948,15 +6988,29 @@ void vdin_set_matrix_color(struct vdin_dev_s *devp) } else if (mode == 4) { wr(offset, VDIN_MATRIX_OFFSET0_1, 0x1ff01ff); wr(offset, VDIN_MATRIX_OFFSET2, 0x1ff); - } else { - wr(offset, VDIN_MATRIX_OFFSET0_1, 0x1ff010f); - wr(offset, VDIN_MATRIX_OFFSET2, 0x2ff); + } else if (mode == 5) { + if (vdin_dbg_en) + pr_info("format_convert:%d\n", devp->format_convert); + if (vdin_is_convert_to_rgb(devp->format_convert)) { + wr(offset, VDIN_MATRIX_OFFSET0_1, rd(offset, VDIN_MATRIX_OFFSET0_1) & + 0xfc00fc00); + wr(offset, VDIN_MATRIX_OFFSET2, rd(offset, VDIN_MATRIX_OFFSET0_1) & + 0xfffffc00); + } else if (vdin_is_convert_to_yuv(devp->format_convert)) { + wr(offset, VDIN_MATRIX_OFFSET0_1, 0x00000200); + wr(offset, VDIN_MATRIX_OFFSET2, 0x00000200); + } + devp->frame_drop_num = 1; } - if (mode) + if (mode) { wr(offset, VDIN_MATRIX_CTRL, 0x6); - else - wr(offset, VDIN_MATRIX_CTRL, 0x0); + } else { + if (vdin_is_rgb_input(devp->prop.color_format)) + vdin_set_matrix(devp); + else + wr(offset, VDIN_MATRIX_CTRL, 0x0); + } if (vdin_dbg_en) pr_info("%s offset:%d, md:%d\n", __func__, offset, mode); } diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.c b/drivers/media/vin/tvin/vdin/vdin_drv.c index a3cb4f0b6..dacdb0304 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/media/vin/tvin/vdin/vdin_drv.c @@ -1977,6 +1977,18 @@ int start_tvin_service(int no, struct vdin_parm_s *para) } EXPORT_SYMBOL(start_tvin_service); +void vdin_set_black_pattern(bool mute) +{ + struct vdin_dev_s *devp = vdin_devp[0]; + + if (mute) + devp->matrix_pattern_mode = 5; + else + devp->matrix_pattern_mode = 0; + vdin_set_matrix_color(devp); +} +EXPORT_SYMBOL(vdin_set_black_pattern); + /* *call vdin_stop_dec to stop the frontend *close frontend