author | Yahui 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) |
commit | 0470dd09d0a038e0c7f7410b1473c5beec99fecf (patch) | |
tree | 00ee0211bdb1f720ee6dc3bf20a9d4d9782fb889 | |
parent | b26fbec421f1e7435047e231b5e81b8c35169691 (diff) | |
download | media_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
-rw-r--r-- | drivers/stream_input/parser/hw_demux/aml_dmx.c | 212 | ||||
-rw-r--r-- | drivers/stream_input/parser/hw_demux/aml_dvb.h | 1 |
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 { |