summaryrefslogtreecommitdiff
authorZhiqiang 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)
commita20abedfa9b73263836765158c84e4ab5b10fd7d (patch)
treed7c31652e266c31d1bc3be129532f3052dccb911
parent5bdd7b7a3eeb91f775968d753d2c1f83b88f4277 (diff)
downloadmedia_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>
Diffstat
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dmx.c58
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.c5
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.h1
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*/