tsdemux: use hw_demux spinlock to sync audio and subtitle reset. [2/2]
authorChuanzhi Wang <chuanzhi.wang@amlogic.com>
Tue, 15 Dec 2020 06:11:12 +0000 (14:11 +0800)
committerZhi Zhou <zhi.zhou@amlogic.com>
Thu, 17 Dec 2020 07:48:15 +0000 (23:48 -0800)
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 <chuanzhi.wang@amlogic.com>
Change-Id: Ie2910ef4c32ccc68c3dc9979cd2a3ae778327500

drivers/stream_input/parser/hw_demux/aml_dvb.c
drivers/stream_input/parser/tsdemux.c

index fe7932a6deb12282c74a5612e976bb37ca714a90..bd9d3e77e72eeb803fe95dbfc9f7fb62f26b80ca 100644 (file)
@@ -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);
 
index 11895ed19e0ea2d80c174ec468dc963993ee2619..7d5788e3fa53e050fa0cc83d90d3e8bb83b0ea60 100644 (file)
@@ -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)