summaryrefslogtreecommitdiff
authorYahui Han <yahui.han@amlogic.com>2020-07-09 06:37:05 (GMT)
committer Shen Liu <shen.liu@amlogic.com>2020-07-09 07:28:11 (GMT)
commit0470dd09d0a038e0c7f7410b1473c5beec99fecf (patch)
tree00ee0211bdb1f720ee6dc3bf20a9d4d9782fb889
parentb26fbec421f1e7435047e231b5e81b8c35169691 (diff)
downloadmedia_modules-0470dd09d0a038e0c7f7410b1473c5beec99fecf.zip
media_modules-0470dd09d0a038e0c7f7410b1473c5beec99fecf.tar.gz
media_modules-0470dd09d0a038e0c7f7410b1473c5beec99fecf.tar.bz2
merge demux driver patches 92879/99144/106991/106769 [1/1]
Change-Id: If7822d8bc5152e6ecc944935fd06567b4ce1c436
Diffstat
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dmx.c212
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.h1
2 files changed, 137 insertions, 76 deletions
diff --git a/drivers/stream_input/parser/hw_demux/aml_dmx.c b/drivers/stream_input/parser/hw_demux/aml_dmx.c
index dc09426..6dd43e4 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dmx.c
+++ b/drivers/stream_input/parser/hw_demux/aml_dmx.c
@@ -114,8 +114,8 @@ MODULE_PARM_DESC(disable_dsc, "\n\t\t Disable discrambler");
static int disable_dsc;
module_param(disable_dsc, int, 0644);
-MODULE_PARM_DESC(enable_sec_monitor, "\n\t\t Enable sec monitor default is disable");
-static int enable_sec_monitor = 1;
+MODULE_PARM_DESC(enable_sec_monitor, "\n\t\t Enable sec monitor default is enable");
+static int enable_sec_monitor = 2;
module_param(enable_sec_monitor, int, 0644);
/*For old version kernel */
#ifndef MESON_CPU_MAJOR_ID_GXL
@@ -132,6 +132,9 @@ module_param_array(debug_dmx##_dmx##_chanpids, short, &npids, 0444)
#define CIPLUS_OUTPUT_AUTO 8
static int ciplus_out_sel = CIPLUS_OUTPUT_AUTO;
static int ciplus_out_auto_mode = 1;
+static u32 ciplus = 0;
+#define CIPLUS_OUT_SEL 28
+#define CIPLUS_IN_SEL 26
MOD_PARAM_DECLARE_CHANPIDS(0);
MOD_PARAM_DECLARE_CHANPIDS(1);
@@ -488,19 +491,25 @@ static void section_buffer_watchdog_func(unsigned long arg)
DMX_READ_REG(device_no, DEMUX_CHANNEL_ACTIVITY);
section_busy32 =
DMX_READ_REG(device_no, SEC_BUFF_BUSY);
-#if 1
+
if (om_cmd_status32 & 0x8fc2) {
- /* bit 15:12 -- om_cmd_count */
+ /* bit 15:12 -- om_cmd_count (read only) */
/* bit 11:9 -- overflow_count */
+ /* bit 11:9 -- om_cmd_wr_ptr(read only) */
/* bit 8:6 -- om_overwrite_count */
- /* bit 1 -- om_cmd_overflow */
+ /* bit 8:6 -- om_cmd_rd_ptr(read only) */
+ /* bit 5:3 -- type_stb_om_w_rd(read only) */
+ /* bit 2 -- unit_start_stb_om_w_rd(read only) */
+ /* bit 1 -- om_cmd_overflow(read only) */
+ /* bit 0 -- om_cmd_pending(read) */
+ /* bit 0 -- om_cmd_read_finished(write) */
/*BUG: If the recoder is running, return */
- if (dmx->record)
- goto end;
- /*Reset the demux */
- pr_dbg("reset the demux\n"
+ if (!dmx->record) {
+ /* OM status is wrong */
+ dmx->om_status_error_count++;
+ pr_dbg("demux om status \n"
"%04x\t%03x\t%03x\t%03x\t%01x\t%01x\t"
- "%x\t%x\tdmx%d:status:0x%x\n",
+ "%x\t%x\tdmx%d:status:0x%xerr_cnt:%d-%d\n",
(om_cmd_status32 >> 12) & 0xf,
(om_cmd_status32 >> 9) & 0x7,
(om_cmd_status32 >> 6) & 0x7,
@@ -508,28 +517,20 @@ static void section_buffer_watchdog_func(unsigned long arg)
(om_cmd_status32 >> 2) & 0x1,
(om_cmd_status32 >> 1) & 0x1,
demux_channel_activity32, section_busy32,
- dmx->id, om_cmd_status32);
-
+ dmx->id, om_cmd_status32, dmx->om_status_error_count, enable_sec_monitor);
+ if (enable_sec_monitor &&
+ dmx->om_status_error_count > enable_sec_monitor) {
+ /*Reset the demux */
dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
+ /* Reset the error count */
+ dmx->om_status_error_count = 0;
goto end;
}
-#else
- /* bit 15:12 -- om_cmd_count (read only) */
- /* bit 11:9 -- overflow_count */
- /* bit 11:9 -- om_cmd_wr_ptr(read only) */
- /* bit 8:6 -- om_overwrite_count */
- /* bit 8:6 -- om_cmd_rd_ptr(read only) */
- /* bit 5:3 -- type_stb_om_w_rd(read only) */
- /* bit 2 -- unit_start_stb_om_w_rd(read only) */
- /* bit 1 -- om_cmd_overflow(read only) */
- /* bit 0 -- om_cmd_pending(read) */
- /* bit 0 -- om_cmd_read_finished(write) */
- if (om_cmd_status32 & 0x0002) {
- pr_error("reset the demux\n");
- dmx_reset_hw_ex(dvb, 0);
- goto end;
}
-#endif
+ } else {
+ /* OM status is correct, reset the error count */
+ dmx->om_status_error_count = 0;
+ }
section_busy32 =
DMX_READ_REG(device_no, SEC_BUFF_BUSY);
if (LARGE_SEC_BUFF_MASK ==
@@ -1668,7 +1669,9 @@ static void stb_enable(struct aml_dvb *dvb)
(en_des << ENABLE_DES_PL) |
(dec_clk_en << ENABLE_DES_PL_CLK) |
(invert0 << INVERT_S2P0_FEC_CLK) |
- (fec_s0 << S2P0_FEC_SERIAL_SEL));
+ (fec_s0 << S2P0_FEC_SERIAL_SEL)|
+ (ciplus));
+ ciplus = 0;
if (dvb->reset_flag)
hiu = 0;
@@ -1720,6 +1723,25 @@ int dsc_set_pid(struct aml_dsc_channel *ch, int pid)
return 0;
}
+int dsc_get_pid(struct aml_dsc_channel *ch, int *pid)
+{
+ struct aml_dsc *dsc = ch->dsc;
+ int is_dsc2 = (dsc->id == 1) ? 1 : 0;
+ u32 data;
+
+ WRITE_MPEG_REG(TS_PL_PID_INDEX,
+ ((ch->id & 0x0f) >> 1)+(is_dsc2 ? 4 : 0));
+ data = READ_MPEG_REG(TS_PL_PID_DATA);
+ if (ch->id & 1) {
+ *pid = data & 0x1fff;
+ } else {
+ *pid = (data >> 16) & 0x1fff;
+ }
+
+ /*pr_dbg("%s,get DSC %d ch %d PID %d\n", __FUNCTION__,dsc->id, ch->id, *pid);*/
+ return 0;
+}
+
int dsc_set_key(struct aml_dsc_channel *ch, int flags, enum ca_cw_type type,
u8 *key)
{
@@ -1836,8 +1858,6 @@ static int dsc_set_csa_key(struct aml_dsc_channel *ch, int flags,
#define ENABLE_DEC_PL 7
#define ENABLE_DES_PL_CLK 15
-#define CIPLUS_OUT_SEL 28
-#define CIPLUS_IN_SEL 26
#define KEY_WR_AES_IV_B 5
#define KEY_WR_AES_IV_A 4
@@ -2109,6 +2129,39 @@ void dsc_release(void)
aml_ci_plus_disable();
}
/************************* AES DESC************************************/
+void set_ciplus_input_source(struct aml_dsc *dsc)
+{
+ u32 data;
+ u32 in = 0;
+
+ if (dsc->id != 0) {
+ pr_error("Ciplus set output can only work at dsc0 device\n");
+ return;
+ }
+
+ switch (dsc->source) {
+ case AM_TS_SRC_DMX0:
+ in = 0;
+ break;
+ case AM_TS_SRC_DMX1:
+ in = 1;
+ break;
+ case AM_TS_SRC_DMX2:
+ in = 2;
+ break;
+ default:
+ break;
+ }
+
+ if (ciplus_out_auto_mode == 1) {
+ /* Set ciplus input source */
+ data = READ_MPEG_REG(STB_TOP_CONFIG);
+ data &= ~(3<<CIPLUS_IN_SEL);
+ data |= in << CIPLUS_IN_SEL;
+ WRITE_MPEG_REG(STB_TOP_CONFIG, data);
+ pr_inf("dsc ciplus in[%x]\n", in);
+ }
+}
int dsc_enable(struct aml_dsc *dsc, int enable)
{
@@ -2574,6 +2627,7 @@ static int dmx_init(struct aml_dmx *dmx)
memset(dmx->sec_buf_watchdog_count, 0,
sizeof(dmx->sec_buf_watchdog_count));
+ dmx->om_status_error_count = 0;
dmx->init = 1;
return 0;
@@ -3400,8 +3454,22 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq)
if (reset_irq)
del_timer_sync(&dvb->watchdog_timer);
#endif
+ /*RESET_TOP will clear the dsc pid , save all dsc pid that setting in TA*/
+ for (id = 0; id < DSC_DEV_COUNT; id++) {
+ struct aml_dsc *dsc = &dvb->dsc[id];
+ int n;
- WRITE_MPEG_REG(RESET1_REGISTER, RESET_DEMUXSTB);
+ for (n = 0; n < DSC_COUNT; n++) {
+ struct aml_dsc_channel *ch = &dsc->channel[n];
+ /*if(ch->used)*/
+ {
+ ch->id = n;
+ dsc_get_pid(ch,&ch->pid);
+ }
+ }
+ }
+ /*WRITE_MPEG_REG(RESET1_REGISTER, RESET_DEMUXSTB);*/
+ WRITE_MPEG_REG(RESET3_REGISTER, RESET_DEMUX2|RESET_DEMUX1|RESET_DEMUX0|RESET_S2P1|RESET_S2P0|RESET_TOP);
for (id = 0; id < DMX_DEV_COUNT; id++) {
times = 0;
@@ -3410,6 +3478,11 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq)
break;
}
}
+ {
+ u32 data;
+ data = READ_MPEG_REG(STB_TOP_CONFIG);
+ ciplus = 0x7C000000 & data;
+ }
WRITE_MPEG_REG(STB_TOP_CONFIG, 0);
@@ -3532,32 +3605,20 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq)
int n;
for (n = 0; n < DSC_COUNT; n++) {
+ int flag = 0;
struct aml_dsc_channel *ch = &dsc->channel[n];
- /*if(ch->used) */
+ /*if(ch->used)*/
{
- ch->id = n;
- dsc_set_pid(ch, ch->pid);
-
- if (ch->flags & DSC_SET_EVEN) {
- dsc_set_key(ch, 0,
- CA_CW_DVB_CSA_EVEN,
- ch->even);
- }
- if (ch->flags & DSC_SET_ODD) {
- dsc_set_key(ch, 0,
- CA_CW_DVB_CSA_ODD,
- ch->odd);
- }
- if (ch->flags & DSC_SET_AES_EVEN) {
- dsc_set_key(ch, 0,
- CA_CW_AES_EVEN,
- ch->aes_even);
- }
- if (ch->flags & DSC_SET_AES_ODD) {
- dsc_set_key(ch, 0,
- CA_CW_AES_ODD,
- ch->aes_odd);
+ ch->work_mode = -1;
+ //if ta setting pid, used will 0
+ if (ch->pid != 0x1fff && !ch->used) {
+ flag = 1;
+ ch->used = 1;
}
+ dsc_set_pid(ch, ch->pid);
+ if (flag)
+ ch->used = 0;
+ //dsc_set_keys(ch);
}
}
}
@@ -3609,6 +3670,11 @@ void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx,
}
/*WRITE_MPEG_REG(STB_TOP_CONFIG, 0); */
+ {
+ u32 data;
+ data = READ_MPEG_REG(STB_TOP_CONFIG);
+ ciplus = 0x7C000000 & data;
+ }
{
u32 version, data;
@@ -3737,29 +3803,20 @@ void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx,
int n;
for (n = 0; n < DSC_COUNT; n++) {
+ int flag = 0;
struct aml_dsc_channel *ch = &dsc->channel[n];
- /*if(ch->used) */
- dsc_set_pid(ch, ch->pid);
-
- if (ch->flags & DSC_SET_EVEN) {
- dsc_set_key(ch, 0,
- CA_CW_DVB_CSA_EVEN,
- ch->even);
- }
- if (ch->flags & DSC_SET_ODD) {
- dsc_set_key(ch, 0,
- CA_CW_DVB_CSA_ODD,
- ch->odd);
- }
- if (ch->flags & DSC_SET_AES_EVEN) {
- dsc_set_key(ch, 0,
- CA_CW_AES_EVEN,
- ch->aes_even);
+ /*if(ch->used)*/ {
+ ch->id = n;
+ ch->work_mode = -1;
+ dsc_get_pid(ch,&ch->pid);
+ if (ch->pid != 0x1fff && !ch->used) {
+ flag = 1;
+ ch->used = 1;
}
- if (ch->flags & DSC_SET_AES_ODD) {
- dsc_set_key(ch, 0,
- CA_CW_AES_ODD,
- ch->aes_odd);
+ dsc_set_pid(ch, ch->pid);
+ if (flag)
+ ch->used = 0;
+ //dsc_set_keys(ch);
}
}
}
@@ -4787,6 +4844,9 @@ int aml_dsc_hw_set_source(struct aml_dsc *dsc,
if (hw_dst == -1)
dsc_enable(dsc, 0);
}
+ if (src_reset && dst_reset) {
+ set_ciplus_input_source(dsc);
+ }
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 ee3831f..114e6dd 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dvb.h
+++ b/drivers/stream_input/parser/hw_demux/aml_dvb.h
@@ -231,6 +231,7 @@ struct aml_dmx {
int crc_check_count;
u32 crc_check_time;
+ int om_status_error_count;
};
struct aml_dvr_block {