diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 38c64bfc0..23886d4d8 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -137,7 +137,8 @@ /* 2023.8.25 gcp avmute issue */ /* 2023.08.28 fix t3x sound issue */ /* 2023 09 27 reduce phy power */ -#define RX_VER2 "ver.2023/9/27" +/* optimize afifo configuration */ +#define RX_VER2 "ver.2023/10/19" #define PFIFO_SIZE 160 #define HDCP14_KEY_SIZE 368 @@ -685,6 +686,7 @@ struct aud_info_s { int aud_packet_received; /* aud mute by gcp_avmute or aud_spflat mute */ bool aud_mute_en; + bool afifo_cfg; /* channel status */ unsigned char channel_status[CHANNEL_STATUS_SIZE]; unsigned char channel_status_bak[CHANNEL_STATUS_SIZE]; diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c index 1b09d1b6b..75ba4d6e1 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -107,7 +107,6 @@ int hbr_force_8ch; * SECURE_MODE:secure OS path */ int hdcp14_key_mode = NORMAL_MODE; -int aud_ch_map; int ignore_sscp_charerr = 1; int ignore_sscp_tmds = 1; int find_best_eq; @@ -1764,6 +1763,7 @@ void rx_get_aud_info(struct aud_info_s *audio_info, u8 port) ? false : true; audio_info->cts = hdmirx_rd_dwc(DWC_PDEC_ACR_CTS); audio_info->n = hdmirx_rd_dwc(DWC_PDEC_ACR_N); + audio_info->afifo_cfg = rx_get_afifo_cfg(); } if (audio_info->cts != 0) { if (rx[port].var.frl_rate == 0) { @@ -1942,32 +1942,37 @@ bool is_clk_stable(u8 port) return flag; } -void rx_afifo_store_all_subpkt(bool all_pkt) +void rx_afifo_store_valid(bool en, u8 port) { - static bool flag = true; - - if (rx_info.chip_id > CHIP_ID_T7) + if (rx_info.chip_id >= CHIP_ID_T7) return; - if (all_pkt) { + if (!en) { + hdmirx_wr_bits_dwc(DWC_AUD_FIFO_CTRL, + AFIF_SUBPACKETS, 0); + rx[port].aud_info.afifo_cfg = false; if (log_level & AUDIO_LOG) - rx_pr("afifo store all sub_pkts: %d\n", flag); - /* when afifo overflow, try afifo store - * configuration alternatively - */ - if (flag) - hdmirx_wr_bits_dwc(DWC_AUD_FIFO_CTRL, - AFIF_SUBPACKETS, 0); - else - hdmirx_wr_bits_dwc(DWC_AUD_FIFO_CTRL, - AFIF_SUBPACKETS, 1); - flag = !flag; + rx_pr("afifo store all\n"); } else { hdmirx_wr_bits_dwc(DWC_AUD_FIFO_CTRL, - AFIF_SUBPACKETS, 1); + AFIF_SUBPACKETS, 1); + rx[port].aud_info.afifo_cfg = true; + if (log_level & AUDIO_LOG) + rx_pr("afifo store valid\n"); } } +bool rx_get_afifo_cfg(void) +{ + if (rx_info.chip_id >= CHIP_ID_T7) + return true; + + if (hdmirx_rd_bits_dwc(DWC_AUD_FIFO_CTRL, AFIF_SUBPACKETS)) + return true; + else + return false; +} + void hdmirx_audio_disabled(u8 port) { if (rx_info.chip_id >= CHIP_ID_T7) @@ -1996,10 +2001,10 @@ u32 hdmirx_audio_fifo_rst(u8 port) udelay(1); hdmirx_wr_bits_cor(RX_PWD_SRST_PWD_IVCRX, _BIT(1), 0, port); } else { + hdmirx_wr_dwc(DWC_DMI_SW_RST, 0x10); hdmirx_wr_bits_dwc(DWC_AUD_FIFO_CTRL, AFIF_INIT, 1); //udelay(20); hdmirx_wr_bits_dwc(DWC_AUD_FIFO_CTRL, AFIF_INIT, 0); - hdmirx_wr_dwc(DWC_DMI_SW_RST, 0x10); } if (log_level & AUDIO_LOG) rx_pr("%s\n", __func__); @@ -3436,20 +3441,15 @@ int hdmirx_audio_init(void) data32 |= 8 << 0; /* min */ hdmirx_wr_dwc(DWC_AUD_FIFO_TH, data32); - /* recover to default value.*/ - /*remain code for some time.*/ - /*if no side effect then remove it */ - /* - *data32 = 0; - *data32 |= 1 << 16; - *data32 |= 0 << 0; - *hdmirx_wr_dwc(DWC_AUD_FIFO_CTRL, data32); - */ + data32 = 0; + data32 |= 1 << 16; + data32 |= 0 << 0; + hdmirx_wr_dwc(DWC_AUD_FIFO_CTRL, data32); data32 = 0; data32 |= 0 << 8; - data32 |= 1 << 7; - data32 |= aud_ch_map << 2; + data32 |= 0 << 7; + data32 |= 0 << 2; data32 |= 1 << 0; hdmirx_wr_dwc(DWC_AUD_CHEXTR_CTRL, data32); @@ -3738,17 +3738,32 @@ static void hdmirx_cor_reset(void) void rx_afifo_monitor(u8 port) { - if (rx_info.chip_id < CHIP_ID_T7) + if (rx[port].state != FSM_SIG_READY) return; - if (rx[rx_info.main_port].state != FSM_SIG_READY) + + if (rx_info.chip_id < CHIP_ID_T7) { + if (rx[port].aud_info.auds_layout || rx[port].aud_info.aud_hbr_rcv) { + if (rx[port].aud_info.afifo_cfg) { + dump_audio_status(port); + rx_afifo_store_valid(false, port); + hdmirx_audio_fifo_rst(port); + } + } else { + if (!rx[port].aud_info.afifo_cfg) { + dump_audio_status(port); + rx_afifo_store_valid(true, port); + hdmirx_audio_fifo_rst(port); + } + } return; + } + if (rx_afifo_dbg_en) { afifo_overflow_cnt = 0; afifo_underflow_cnt = 0; return; } - - rx[rx_info.main_port].afifo_sts = hdmirx_rd_cor(RX_INTR4_PWD_IVCRX, port) & 3; + rx[port].afifo_sts = hdmirx_rd_cor(RX_INTR4_PWD_IVCRX, port) & 3; hdmirx_wr_cor(RX_INTR4_PWD_IVCRX, 3, port); if (rx[rx_info.main_port].afifo_sts & 2) { afifo_overflow_cnt++; @@ -3841,7 +3856,7 @@ bool rx_special_func_en(void) return ret; #ifdef CVT_DEF_FIXED_HPD_PORT - if (rx.port == E_PORT0 && ((CVT_DEF_FIXED_HPD_PORT & (1 << E_PORT0)) != 0)) + if (rx_info.main_port == E_PORT0 && ((CVT_DEF_FIXED_HPD_PORT & (1 << E_PORT0)) != 0)) ret = true; if (rx_info.boot_flag && rx_info.main_port == E_PORT0) { @@ -4454,7 +4469,7 @@ bool is_aud_fifo_error(void) (OVERFL_STS | UNDERFL_STS)) && rx[rx_info.main_port].aud_info.aud_packet_received) { ret = true; - if (log_level & AUDIO_LOG) + if (log_level & DBG_LOG) rx_pr("afifo err\n"); } return ret; @@ -5324,22 +5339,6 @@ void hdmirx_config_audio(u8 port) /* set MCLK for I2S/SPDIF */ hdmirx_wr_cor(AAC_MCLK_SEL_AUD_IVCRX, 0x80, port); hdmirx_hbr2spdif(1, port); - } else { - /* if audio layout bit = 1, set audio channel map - * according to audio speaker allocation, if layout - * bit = 0, use ch1 & ch2 by default. - */ - if (rx[port].aud_info.aud_hbr_rcv && hbr_force_8ch) { - hdmirx_wr_dwc(DWC_AUD_CHEXTR_CTRL, 0xff); - if (log_level & AUDIO_LOG) - rx_pr("HBR rcv, force 8ch\n"); - } else if (rx[port].aud_info.auds_layout) { - hdmirx_wr_bits_dwc(DWC_AUD_CHEXTR_CTRL, - AUD_CH_MAP_CFG, - rx[port].aud_info.auds_ch_alloc); - } else { - hdmirx_wr_bits_dwc(DWC_AUD_CHEXTR_CTRL, AUD_CH_MAP_CFG, 0); - } } } diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h index 37fcd6037..c83d38ff1 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -660,7 +660,7 @@ #define DWC_AUD_FIFO_FILLSTS (0x250UL) /** Register address: audio output interface configuration */ #define DWC_AUD_CHEXTR_CTRL (0x254UL) -#define AUD_CH_MAP_CFG MSK(5, 2) +#define AUD_CH_MAP_CFG MSK(4, 2) /** Register address: audio mute control */ #define DWC_AUD_MUTE_CTRL (0x258UL) /** Manual/automatic audio mute control */ @@ -3184,7 +3184,6 @@ extern int aud_mute_sel; extern int pdec_ists_en; extern int pd_fifo_start_cnt; extern int md_ists_en; -extern int aud_ch_map; extern int hdcp14_key_mode; extern int ignore_sscp_charerr; extern int ignore_sscp_tmds; @@ -3313,8 +3312,9 @@ void esm_set_reset(bool reset); void esm_set_stable(bool stable); void rx_hpd_to_esm_handle(struct work_struct *work); unsigned int hdmirx_packet_fifo_rst(void); -void rx_afifo_store_all_subpkt(bool all_pkt); -unsigned int hdmirx_audio_fifo_rst(u8 port); +void rx_afifo_store_valid(bool en, u8 port); +bool rx_get_afifo_cfg(void); +u32 hdmirx_audio_fifo_rst(u8 port); void hdmirx_audio_disabled(u8 port); void hdmirx_phy_init(u8 port); void hdmirx_hw_config(u8 port); diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index cbda5ce55..26e2e64f5 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -825,24 +825,14 @@ static int rx_dwc_irq_handler(void) if (rx_get_bits(intr_aud_fifo, OVERFL) != 0) { if (log_level & 0x100) rx_pr("[irq] OVERFL\n"); - /* rx[port].irq_flag |= IRQ_AUD_FLAG; */ - /* when afifo overflow in multi-channel case(VG-877), - * then store all subpkts into afifo, 8ch in and 8ch out - */ - if (rx[port].aud_info.auds_layout) - rx_afifo_store_all_subpkt(true); - else - rx_afifo_store_all_subpkt(false); - //if (rx[port].aud_info.real_sr != 0) - error |= hdmirx_audio_fifo_rst(port); + if (rx[port].state == FSM_SIG_READY) + hdmirx_audio_fifo_rst(port); } if (rx_get_bits(intr_aud_fifo, UNDERFL) != 0) { if (log_level & 0x100) rx_pr("[irq] UNDERFL\n"); - /* rx[port].irq_flag |= IRQ_AUD_FLAG; */ - rx_afifo_store_all_subpkt(false); - //if (rx[port].aud_info.real_sr != 0) - error |= hdmirx_audio_fifo_rst(port); + if (rx[port].state == FSM_SIG_READY) + hdmirx_audio_fifo_rst(port); } } if (vsi_handle_flag) @@ -3808,7 +3798,6 @@ void rx_get_global_variable(const char *buf) pr_var(vdin_drop_frame_cnt, i++); pr_var(atmos_edid_update_hpd_en, i++); pr_var(suspend_pddq_sel, i++); - pr_var(aud_ch_map, i++); pr_var(hdcp_none_wait_max, i++); pr_var(pll_unlock_max, i++); pr_var(esd_phy_rst_max, i++); @@ -4145,8 +4134,6 @@ int rx_set_global_variable(const char *buf, int size) return pr_var(atmos_edid_update_hpd_en, index); if (set_pr_var(tmpbuf, var_to_str(suspend_pddq_sel), &suspend_pddq_sel, value)) return pr_var(suspend_pddq_sel, index); - if (set_pr_var(tmpbuf, var_to_str(aud_ch_map), &aud_ch_map, value)) - return pr_var(aud_ch_map, index); if (set_pr_var(tmpbuf, var_to_str(hdcp_none_wait_max), &hdcp_none_wait_max, value)) return pr_var(hdcp_none_wait_max, index); if (set_pr_var(tmpbuf, var_to_str(pll_unlock_max), &pll_unlock_max, value)) @@ -4967,8 +4954,6 @@ static bool sepcail_dev_need_extra_wait(int wait_cnt, u8 port) */ void rx_main_state_machine(void) { - int pre_auds_ch_alloc; - int pre_auds_hbr; int one_frame_cnt; u8 port = rx_info.main_port; @@ -5227,7 +5212,7 @@ void rx_main_state_machine(void) rx_get_aud_info(&rx[port].aud_info, port); hdmirx_config_audio(port); rx_aud_pll_ctl(1, port); - rx_afifo_store_all_subpkt(false); + rx_afifo_store_valid(true, port); hdmirx_audio_fifo_rst(port); rx[port].hdcp.hdcp_pre_ver = rx[port].hdcp.hdcp_version; rx[port].stable_timestamp = rx[port].timestamp; @@ -5403,21 +5388,11 @@ void rx_main_state_machine(void) break; //packet_update(port); hdcp_sts_update(port); - pre_auds_ch_alloc = rx[port].aud_info.auds_ch_alloc; - pre_auds_hbr = rx[port].aud_info.aud_hbr_rcv; rx_get_aud_info(&rx[port].aud_info, port); if (check_real_sr_change(port)) rx_audio_pll_sw_update(); - if (pre_auds_ch_alloc != rx[port].aud_info.auds_ch_alloc || - (pre_auds_hbr != rx[port].aud_info.aud_hbr_rcv && - hbr_force_8ch)) { - if (log_level & AUDIO_LOG) - dump_state(RX_DUMP_AUDIO, port); - hdmirx_config_audio(port); - hdmirx_audio_fifo_rst(port); - rx_audio_pll_sw_update(); - } + if (is_aud_pll_error()) { rx[port].aud_sr_unstable_cnt++; if (rx[port].aud_sr_unstable_cnt > aud_sr_stb_max) { @@ -5723,7 +5698,6 @@ void rx_port0_main_state_machine(void) rx_get_aud_info(&rx[port].aud_info, port); hdmirx_config_audio(port); rx_aud_pll_ctl(1, port); - rx_afifo_store_all_subpkt(false); hdmirx_audio_fifo_rst(port); rx[port].hdcp.hdcp_pre_ver = rx[port].hdcp.hdcp_version; rx[port].stable_timestamp = rx[port].timestamp; @@ -6217,7 +6191,6 @@ void rx_port1_main_state_machine(void) rx_get_aud_info(&rx[port].aud_info, port); hdmirx_config_audio(port); rx_aud_pll_ctl(1, port); - rx_afifo_store_all_subpkt(false); //hdmirx_audio_fifo_rst(port); rx[port].hdcp.hdcp_pre_ver = rx[port].hdcp.hdcp_version; rx[port].stable_timestamp = rx[port].timestamp; @@ -6756,7 +6729,6 @@ void rx_port2_main_state_machine(void) rx_get_aud_info(&rx[port].aud_info, port); hdmirx_config_audio(port); rx_aud_pll_ctl(1, port); - rx_afifo_store_all_subpkt(false); hdmirx_audio_fifo_rst(port); rx[port].hdcp.hdcp_pre_ver = rx[port].hdcp.hdcp_version; rx[port].stable_timestamp = rx[port].timestamp; @@ -7297,7 +7269,6 @@ void rx_port3_main_state_machine(void) rx_get_aud_info(&rx[port].aud_info, port); hdmirx_config_audio(port); rx_aud_pll_ctl(1, port); - rx_afifo_store_all_subpkt(false); hdmirx_audio_fifo_rst(port); rx[port].hdcp.hdcp_pre_ver = rx[port].hdcp.hdcp_version; rx[port].stable_timestamp = rx[port].timestamp; @@ -7775,7 +7746,7 @@ void dump_video_status(u8 port) rx_pirnt_edid_support(); } -static void dump_audio_status(u8 port) +void dump_audio_status(u8 port) { static struct aud_info_s a; //u32 val0, val1; @@ -7789,8 +7760,8 @@ static void dump_audio_status(u8 port) rx_pr(" CA=%u\n", a.auds_ch_alloc); rx_pr("CTS=%d, N=%d,", a.cts, a.n); rx_pr("acr clk=%d\n", a.arc); - //rx_get_audio_N_CTS(&val0, &val1, port); - //rx_pr("top CTS:%d, N:%d\n", a., val0); + rx_pr("layout=%d\n", a.auds_layout); + rx_pr("afifo cfg=%d\n", a.afifo_cfg); rx_pr("audio receive data:%d\n", rx[port].aud_info.aud_packet_received); rx_pr("aud mute = %d", a.aud_mute_en); rx_pr("aud fifo = %d", rx[port].afifo_sts); diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h index 75f782c1f..5517d8695 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h @@ -139,7 +139,7 @@ enum tvin_sig_fmt_e hdmirx_hw_get_fmt(u8 port); void rx_mute_vpp(void); void rx_main_state_machine(void); void rx_port2_main_state_machine(void); - +void dump_audio_status(u8 port); void rx_nosig_monitor(u8 port); bool rx_is_nosig(u8 port); bool rx_is_sig_ready(u8 port);