From: Chuanzhi Wang Date: Tue, 15 Dec 2020 06:11:12 +0000 (+0800) Subject: tsdemux: use hw_demux spinlock to sync audio and subtitle reset. [2/2] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a10259f45f5bf42bfe62e233b1f3bf1577683ac7;p=GitHub%2FLineageOS%2FG12%2Fandroid_hardware_amlogic_kernel-modules_media.git tsdemux: use hw_demux spinlock to sync audio and subtitle reset. [2/2] PD#SWPL-38748 Problem: Video freeze when switch audio track. Solution: Use the hw demux spinlock to sync audio reset. Verify: S905X2 U215 Signed-off-by: Chuanzhi Wang Change-Id: Ie2910ef4c32ccc68c3dc9979cd2a3ae778327500 --- diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb.c b/drivers/stream_input/parser/hw_demux/aml_dvb.c index fe7932a..bd9d3e7 100644 --- a/drivers/stream_input/parser/hw_demux/aml_dvb.c +++ b/drivers/stream_input/parser/hw_demux/aml_dvb.c @@ -110,6 +110,8 @@ static int aml_tsdemux_set_sid(int spid); static int aml_tsdemux_set_pcrid(int pcrpid); static int aml_tsdemux_set_skipbyte(int skipbyte); static int aml_tsdemux_set_demux(int id); +static unsigned long aml_tsdemux_hwdmx_spin_lock(unsigned long flags); +static int aml_tsdemux_hwdmx_spin_unlock(unsigned long flags); static struct tsdemux_ops aml_tsdemux_ops = { .reset = aml_tsdemux_reset, @@ -121,7 +123,9 @@ static struct tsdemux_ops aml_tsdemux_ops = { .set_sid = aml_tsdemux_set_sid, .set_pcrid = aml_tsdemux_set_pcrid, .set_skipbyte = aml_tsdemux_set_skipbyte, - .set_demux = aml_tsdemux_set_demux + .set_demux = aml_tsdemux_set_demux, + .hw_dmx_lock = aml_tsdemux_hwdmx_spin_lock, + .hw_dmx_unlock = aml_tsdemux_hwdmx_spin_unlock }; long aml_stb_get_base(int id) @@ -3025,6 +3029,22 @@ static int aml_tsdemux_set_demux(int id) return 0; } +static unsigned long aml_tsdemux_hwdmx_spin_lock(unsigned long flags) +{ + struct aml_dvb *dvb = &aml_dvb_device; + + spin_lock_irqsave(&dvb->slock, flags); + return flags; +} + +static int aml_tsdemux_hwdmx_spin_unlock(unsigned long flags) +{ + struct aml_dvb *dvb = &aml_dvb_device; + + spin_unlock_irqrestore(&dvb->slock, flags); + return 0; +} + module_init(aml_dvb_init); module_exit(aml_dvb_exit); diff --git a/drivers/stream_input/parser/tsdemux.c b/drivers/stream_input/parser/tsdemux.c index 11895ed..7d5788e 100644 --- a/drivers/stream_input/parser/tsdemux.c +++ b/drivers/stream_input/parser/tsdemux.c @@ -1067,16 +1067,19 @@ void tsdemux_change_avid(unsigned int vid, unsigned int aid) WRITE_DEMUX_REG(FM_WR_ADDR, 0x8000); while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000) ; - } else { - curr_vid_id = vid; - curr_aud_id = aid; - - tsdemux_set_vid(vid); - tsdemux_set_aid(aid); - + } + else + { + if (curr_vid_id != vid) { + tsdemux_set_vid(vid); + curr_vid_id = vid; + } + if (curr_aud_id != aid) { + tsdemux_set_aid(aid); + curr_aud_id = aid; + } reset_pcr_regs(); } - } void tsdemux_change_sid(unsigned int sid) @@ -1101,10 +1104,11 @@ void tsdemux_change_sid(unsigned int sid) void tsdemux_audio_reset(void) { ulong flags; + unsigned long xflags = 0; - DEFINE_SPINLOCK(lock); - - spin_lock_irqsave(&lock, flags); + spin_lock_irqsave(&demux_ops_lock, flags); + if (demux_ops && demux_ops->hw_dmx_lock) + xflags = demux_ops->hw_dmx_lock(xflags); WRITE_PARSER_REG(PARSER_AUDIO_WP, READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR)); @@ -1120,18 +1124,21 @@ void tsdemux_audio_reset(void) WRITE_AIU_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_AIU_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - spin_unlock_irqrestore(&lock, flags); - + if (demux_ops && demux_ops->hw_dmx_unlock) + demux_ops->hw_dmx_unlock(xflags); + spin_unlock_irqrestore(&demux_ops_lock, flags); } void tsdemux_sub_reset(void) { ulong flags; - DEFINE_SPINLOCK(lock); u32 parser_sub_start_ptr; u32 parser_sub_end_ptr; + unsigned long xflags = 0; - spin_lock_irqsave(&lock, flags); + spin_lock_irqsave(&demux_ops_lock, flags); + if (demux_ops && demux_ops->hw_dmx_lock) + xflags = demux_ops->hw_dmx_lock(xflags); parser_sub_start_ptr = READ_PARSER_REG(PARSER_SUB_START_PTR); parser_sub_end_ptr = READ_PARSER_REG(PARSER_SUB_END_PTR); @@ -1143,8 +1150,9 @@ void tsdemux_sub_reset(void) SET_PARSER_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); - spin_unlock_irqrestore(&lock, flags); - + if (demux_ops && demux_ops->hw_dmx_unlock) + demux_ops->hw_dmx_unlock(xflags); + spin_unlock_irqrestore(&demux_ops_lock, flags); } void tsdemux_set_skipbyte(int skipbyte)