summaryrefslogtreecommitdiff
authorZhiqiang Han <zhiqiang.han@amlogic.com>2019-12-30 07:54:38 (GMT)
committer Zhi Zhou <zhi.zhou@amlogic.com>2020-01-09 04:05:09 (GMT)
commitb34f2e35d9fa47a1340993d844b7ffeac3324ac8 (patch)
treef8f791eddb755324f38ca7e02186a778b07b1d76
parent6933cd86d1d664d20e8a26069f29f9642bb41b2a (diff)
downloadmedia_modules-b34f2e35d9fa47a1340993d844b7ffeac3324ac8.zip
media_modules-b34f2e35d9fa47a1340993d844b7ffeac3324ac8.tar.gz
media_modules-b34f2e35d9fa47a1340993d844b7ffeac3324ac8.tar.bz2
sub: sleep in irq_handler [1/4]
PD#SWPL-19036 Problem: sleep in irq_handler Solution: change dynamic phys2virt to init base once Verify: Patchbuild Change-Id: I734a6c5c02c84daa5eda1ceb00d97287d7b699ba Signed-off-by: Zhiqiang Han <zhiqiang.han@amlogic.com>
Diffstat
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dmx.c43
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.h11
2 files changed, 44 insertions, 10 deletions
diff --git a/drivers/stream_input/parser/hw_demux/aml_dmx.c b/drivers/stream_input/parser/hw_demux/aml_dmx.c
index 52334da..56e028d 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dmx.c
+++ b/drivers/stream_input/parser/hw_demux/aml_dmx.c
@@ -1110,9 +1110,12 @@ static void process_sub(struct aml_dmx *dmx)
u32 end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR);
u32 buffer1 = 0, buffer2 = 0;
- unsigned char *buffer1_virt = 0, *buffer2_virt = 0;
+ u8 *buffer1_virt = 0, *buffer2_virt = 0;
u32 len1 = 0, len2 = 0;
+ if (!dmx->sub_buf_base_virt)
+ return;
+
rd_ptr = READ_MPEG_REG(PARSER_SUB_RP);
if (!rd_ptr)
return;
@@ -1134,10 +1137,10 @@ static void process_sub(struct aml_dmx *dmx)
}
if (buffer1 && len1)
- buffer1_virt = codec_mm_phys_to_virt(buffer1);
+ buffer1_virt = dmx->sub_buf_base_virt + (buffer1 - start_ptr);
if (buffer2 && len2)
- buffer2_virt = codec_mm_phys_to_virt(buffer2);
+ buffer2_virt = dmx->sub_buf_base_virt + (buffer2 - start_ptr);
// 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);
@@ -1153,7 +1156,7 @@ static void process_sub(struct aml_dmx *dmx)
if (dmx->channel[2].used) {
if (dmx->channel[2].feed && dmx->channel[2].feed->cb.ts &&
- ((buffer1_virt != NULL && len1 !=0 ) | (buffer2_virt != NULL && len2 != 0)))
+ ((buffer1_virt != NULL && len1 !=0 ) || (buffer2_virt != NULL && len2 != 0)))
{
dmx->channel[2].feed->cb.ts(buffer1_virt, len1,
buffer2_virt, len2,
@@ -2431,6 +2434,7 @@ static int dmx_alloc_sec_buffer(struct aml_dmx *dmx)
/*Set subtitle buffer*/
static int dmx_alloc_sub_buffer(struct aml_dmx *dmx)
{
+#ifdef SUB_BUF_DMX
unsigned long addr;
if (dmx->sub_pages)
@@ -2450,6 +2454,7 @@ static int dmx_alloc_sub_buffer(struct aml_dmx *dmx)
addr = virt_to_phys((void *)dmx->sub_pages);
DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
DMX_WRITE_REG(dmx->id, SB_LAST_ADDR, (dmx->sub_buf_len >> 3) - 1);
+#endif
return 0;
}
#endif /*NO_SUB */
@@ -2848,6 +2853,7 @@ static int dmx_deinit(struct aml_dmx *dmx)
dmx->sec_pages_map = 0;
}
#ifdef NO_SUB
+#ifdef SUB_BUF_DMX
if (dmx->sub_pages) {
dma_unmap_single(dmx_get_dev(dmx), dmx->sub_pages_map,
dmx->sub_buf_len, DMA_FROM_DEVICE);
@@ -2855,6 +2861,7 @@ static int dmx_deinit(struct aml_dmx *dmx)
dmx->sub_pages = 0;
}
#endif
+#endif
if (dmx->pes_pages) {
dma_unmap_single(dmx_get_dev(dmx), dmx->pes_pages_map,
dmx->pes_buf_len, DMA_FROM_DEVICE);
@@ -3850,14 +3857,16 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq)
(SEC_GRP_LEN_2 << 8) |
(SEC_GRP_LEN_3 << 12));
}
-
+#ifdef NO_SUB
+#ifdef SUB_BUF_DMX
if (dmx->sub_pages) {
addr = virt_to_phys((void *)dmx->sub_pages);
DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
DMX_WRITE_REG(dmx->id, SB_LAST_ADDR,
(dmx->sub_buf_len >> 3) - 1);
}
-
+#endif
+#endif
if (dmx->pes_pages) {
addr = virt_to_phys((void *)dmx->pes_pages);
DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
@@ -4039,14 +4048,16 @@ void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx,
(SEC_GRP_LEN_2 << 8) |
(SEC_GRP_LEN_3 << 12));
}
-
+#ifdef NO_SUB
+#ifdef SUB_BUF_DMX
if (dmx->sub_pages) {
addr = virt_to_phys((void *)dmx->sub_pages);
DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
DMX_WRITE_REG(dmx->id, SB_LAST_ADDR,
(dmx->sub_buf_len >> 3) - 1);
}
-
+#endif
+#endif
if (dmx->pes_pages) {
addr = virt_to_phys((void *)dmx->pes_pages);
DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
@@ -4189,6 +4200,17 @@ exit:
}
#endif
+int dmx_init_sub_buffer(struct aml_dmx *dmx)
+{
+ dmx->sub_buf_base = READ_MPEG_REG(PARSER_SUB_START_PTR);
+ pr_inf("sub buf base: 0x%lx\n", dmx->sub_buf_base);
+
+ dmx->sub_buf_base_virt = codec_mm_phys_to_virt(dmx->sub_buf_base);
+ pr_inf("sub buf base virt: 0x%p\n", dmx->sub_buf_base_virt);
+
+ return 0;
+}
+
/*Allocate a new channel*/
int dmx_alloc_chan(struct aml_dmx *dmx, int type, int pes_type, int pid)
{
@@ -4878,6 +4900,11 @@ 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);
+
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.h b/drivers/stream_input/parser/hw_demux/aml_dvb.h
index 604be3a..e18bb9b 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dvb.h
+++ b/drivers/stream_input/parser/hw_demux/aml_dvb.h
@@ -213,9 +213,16 @@ struct aml_dmx {
unsigned long pes_pages;
unsigned long pes_pages_map;
int pes_buf_len;
- unsigned long sub_pages;
- unsigned long sub_pages_map;
+ union {
+ unsigned long sub_pages;
+ unsigned long sub_buf_base;
+ };
+ union {
+ unsigned long sub_pages_map;
+ u8 *sub_buf_base_virt;
+ };
int sub_buf_len;
+
struct aml_channel channel[CHANNEL_COUNT+1];
struct aml_filter filter[FILTER_COUNT+1];
irq_handler_t irq_handler;