author | Zhiqiang Han <zhiqiang.han@amlogic.com> | 2020-01-19 04:57:19 (GMT) |
---|---|---|
committer | Zhiqiang Han <zhiqiang.han@amlogic.com> | 2020-02-12 09:51:08 (GMT) |
commit | a20abedfa9b73263836765158c84e4ab5b10fd7d (patch) | |
tree | d7c31652e266c31d1bc3be129532f3052dccb911 | |
parent | 5bdd7b7a3eeb91f775968d753d2c1f83b88f4277 (diff) | |
download | media_modules-a20abedfa9b73263836765158c84e4ab5b10fd7d.zip media_modules-a20abedfa9b73263836765158c84e4ab5b10fd7d.tar.gz media_modules-a20abedfa9b73263836765158c84e4ab5b10fd7d.tar.bz2 |
sub: may sleep in irq-disabled [1/2]
PD#SWPL-20113
Problem:
may sleep in irq-disabled
Solution:
use self maintaining buf for sub pes channel
Verify:
Patchbuild
Change-Id: I12ebc0182c9789f026b0f31246d7ba99b01792ca
Signed-off-by: Zhiqiang Han <zhiqiang.han@amlogic.com>
-rw-r--r-- | drivers/stream_input/parser/hw_demux/aml_dmx.c | 58 | ||||
-rw-r--r-- | drivers/stream_input/parser/hw_demux/aml_dvb.c | 5 | ||||
-rw-r--r-- | drivers/stream_input/parser/hw_demux/aml_dvb.h | 1 |
3 files changed, 49 insertions, 15 deletions
diff --git a/drivers/stream_input/parser/hw_demux/aml_dmx.c b/drivers/stream_input/parser/hw_demux/aml_dmx.c index 6bf9186..0b6ac6b 100644 --- a/drivers/stream_input/parser/hw_demux/aml_dmx.c +++ b/drivers/stream_input/parser/hw_demux/aml_dmx.c @@ -391,6 +391,12 @@ static void dmxn_op_chan(int dmx, int ch, int(*op)(int, int), int ch_op) } while (0) #define NO_SUB +#define SUB_BUF_DMX +#define SUB_PARSER + +#ifndef SUB_BUF_DMX +#undef SUB_PARSER +#endif #define SYS_CHAN_COUNT (4) #define SEC_GRP_LEN_0 (0xc) @@ -1137,10 +1143,18 @@ static void process_sub(struct aml_dmx *dmx) } if (buffer1 && len1) - buffer1_virt = dmx->sub_buf_base_virt + (buffer1 - start_ptr); +#ifdef SUB_BUF_DMX + buffer1_virt = (void *)dmx->sub_pages + (buffer1 - start_ptr); +#else + buffer1_virt = (void *)dmx->sub_buf_base_virt + (buffer1 - start_ptr); +#endif if (buffer2 && len2) - buffer2_virt = dmx->sub_buf_base_virt + (buffer2 - start_ptr); +#ifdef SUB_BUF_DMX + buffer2_virt = (void *)dmx->sub_pages + (buffer2 - start_ptr); +#else + buffer2_virt = (void *)dmx->sub_buf_base_virt + (buffer2 - start_ptr); +#endif // printk("rd_ptr %p buffer1 %p len1 %d buffer2 %p len2 %d buffer1_virt %p buffer2_virt %p\n", // (void*)rd_ptr, (void*)buffer1, len1, (void*)buffer2, len2, buffer1_virt, buffer2_virt); @@ -2452,9 +2466,12 @@ static int dmx_alloc_sub_buffer(struct aml_dmx *dmx) dmx->sub_buf_len, DMA_FROM_DEVICE); addr = virt_to_phys((void *)dmx->sub_pages); +#ifndef SUB_PARSER DMX_WRITE_REG(dmx->id, SB_START, addr >> 12); DMX_WRITE_REG(dmx->id, SB_LAST_ADDR, (dmx->sub_buf_len >> 3) - 1); #endif + pr_inf("sub buff: (%d) %lx %x\n", dmx->id, addr, dmx->sub_buf_len); +#endif return 0; } #endif /*NO_SUB */ @@ -4200,14 +4217,39 @@ exit: } #endif +static int set_subtitle_pes_buffer(struct aml_dmx *dmx) +{ +#ifdef SUB_PARSER + unsigned long addr = virt_to_phys((void *)dmx->sub_pages); + WRITE_MPEG_REG(PARSER_SUB_RP, addr); + WRITE_MPEG_REG(PARSER_SUB_START_PTR, addr); + WRITE_MPEG_REG(PARSER_SUB_END_PTR, addr + dmx->sub_buf_len - 8); + pr_inf("set sub buff: (%d) %lx %x\n", dmx->id, addr, dmx->sub_buf_len); +#endif + return 0; +} + +int dmx_get_sub_buffer(unsigned long *base, unsigned long *virt) +{ +#ifndef SUB_BUF_DMX + unsigned long s = READ_MPEG_REG(PARSER_SUB_START_PTR); + if (base) + *base = s; + if (virt) + *virt = (unsigned long)codec_mm_phys_to_virt(s); +#endif + return 0; +} + int dmx_init_sub_buffer(struct aml_dmx *dmx, unsigned long base, unsigned long virt) { - dmx->sub_buf_base = (base)? base : READ_MPEG_REG(PARSER_SUB_START_PTR); +#ifndef SUB_BUF_DMX + dmx->sub_buf_base = base; pr_inf("sub buf base: 0x%lx\n", dmx->sub_buf_base); - dmx->sub_buf_base_virt = (base)? (u8 *)virt : codec_mm_phys_to_virt(dmx->sub_buf_base); + dmx->sub_buf_base_virt = (u8 *)virt; pr_inf("sub buf base virt: 0x%p\n", dmx->sub_buf_base_virt); - +#endif return 0; } @@ -4232,6 +4274,7 @@ int dmx_alloc_chan(struct aml_dmx *dmx, int type, int pes_type, int pid) if (!dmx->channel[2].used) id = 2; //alloc_subtitle_pes_buffer(dmx); + set_subtitle_pes_buffer(dmx); break; case DMX_PES_PCR: if (!dmx->channel[3].used) @@ -4900,11 +4943,6 @@ int aml_dmx_hw_start_feed(struct dvb_demux_feed *dvbdmxfeed) unsigned long flags; int ret = 0; - if (dvbdmxfeed->type == DMX_TYPE_TS - && (dvbdmxfeed->pes_type == DMX_PES_SUBTITLE - || dvbdmxfeed->pes_type == DMX_PES_TELETEXT)) - dmx_init_sub_buffer(dmx, 0, 0); - spin_lock_irqsave(&dvb->slock, flags); ret = dmx_add_feed(dmx, dvbdmxfeed); spin_unlock_irqrestore(&dvb->slock, flags); diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb.c b/drivers/stream_input/parser/hw_demux/aml_dvb.c index 5785466..1a5e174 100644 --- a/drivers/stream_input/parser/hw_demux/aml_dvb.c +++ b/drivers/stream_input/parser/hw_demux/aml_dvb.c @@ -2884,12 +2884,10 @@ static int aml_tsdemux_set_vid(int vpid) if (dmx) { if (dmx->vid_chan != -1) { dmx_free_chan(dmx, dmx->vid_chan); - dmx_init_sub_buffer(dmx, 1, 0); dmx->vid_chan = -1; } if ((vpid >= 0) && (vpid < 0x1FFF)) { - dmx_init_sub_buffer(dmx, 0, 0); dmx->vid_chan = dmx_alloc_chan(dmx, DMX_TYPE_TS, DMX_PES_VIDEO, vpid); @@ -2920,7 +2918,6 @@ static int aml_tsdemux_set_aid(int apid) } if ((apid >= 0) && (apid < 0x1FFF)) { - dmx_init_sub_buffer(dmx, 0, 0); dmx->aud_chan = dmx_alloc_chan(dmx, DMX_TYPE_TS, DMX_PES_AUDIO, apid); @@ -2948,12 +2945,10 @@ static int aml_tsdemux_set_sid(int spid) if (dmx) { if (dmx->sub_chan != -1) { dmx_free_chan(dmx, dmx->sub_chan); - dmx_init_sub_buffer(dmx, 1, 0); dmx->sub_chan = -1; } if ((spid >= 0) && (spid < 0x1FFF)) { - dmx_init_sub_buffer(dmx, 0, 0); dmx->sub_chan = dmx_alloc_chan(dmx, DMX_TYPE_TS, DMX_PES_SUBTITLE, spid); diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb.h b/drivers/stream_input/parser/hw_demux/aml_dvb.h index 3fa9cd8..41c7d0f 100644 --- a/drivers/stream_input/parser/hw_demux/aml_dvb.h +++ b/drivers/stream_input/parser/hw_demux/aml_dvb.h @@ -366,6 +366,7 @@ extern void dmx_free_chan(struct aml_dmx *dmx, int cid); extern int dmx_get_ts_serial(enum aml_ts_source_t src); +extern int dmx_get_sub_buffer(unsigned long *base, unsigned long *virt); extern int dmx_init_sub_buffer(struct aml_dmx *dmx, unsigned long base, unsigned long virt); /*AMLogic dsc interface*/ |