hdmirx: optimized afifo configuration [1/1]

PD#SWPL-139924

Problem:
Afifo does not work sometimes when dolby5.1 input

Solution:
optimized afifo configuration

Verify:
tm2

Change-Id: I9acdd0018325a88ae625398faca2c63e9bf1ab3f
Signed-off-by: Lei Yang <lei.yang@amlogic.com>
This commit is contained in:
Lei Yang
2023-10-19 15:02:37 +08:00
committed by Luan Yuan
parent 6aaff584f0
commit 18828ec003
5 changed files with 68 additions and 96 deletions
+3 -1
View File
@@ -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];
+51 -52
View File
@@ -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);
}
}
}
+4 -4
View File
@@ -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);
@@ -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);
@@ -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);