dtv_demod: rebuild dtmb driver (v3.25.32) [1/1]

PD#SWPL-158422

Problem:
1.signal locking and channel scanning are slow
2.signal locking process is unstable

Solution:
rebuild driver
1.signal locking speed is increased by more than 60%
2.signal locking timeout speed is increased by more than 40% ~ 90%
3.the channel scanning speed is increased by more than 35%
4.improve the stability of signal locking
5.reduced sensitivity to transient abnormalities in the signal

Verify:
T5M, T950s

Change-Id: Ie9b0f522478222e0076fced126a966c2f951cc1c
Signed-off-by: caiyi.xu <caiyi.xu@amlogic.com>
This commit is contained in:
caiyi.xu
2024-03-04 02:38:17 +00:00
committed by gerrit autosubmit
parent 88da7efe65
commit d37f84a2e1
6 changed files with 225 additions and 5 deletions
+13 -2
View File
@@ -80,6 +80,11 @@
#include <linux/amlogic/media/vout/vdac_dev.h>
#include <linux/amlogic/aml_dtvdemod.h>
//dtmb
unsigned char dtmb_new_driver = 1;
MODULE_PARM_DESC(dtmb_new_driver, "\n\t\t use dtmb new driver to work");
module_param(dtmb_new_driver, byte, 0644);
//dvb-c
MODULE_PARM_DESC(dvbc_new_driver, "\n\t\t use dvbc new driver to work");
static unsigned char dvbc_new_driver;
@@ -2338,7 +2343,10 @@ static int aml_dtvdm_read_status(struct dvb_frontend *fe,
break;
#ifdef AML_DEMOD_SUPPORT_DTMB
case SYS_DTMB:
ret = gxtv_demod_dtmb_read_status(fe, status);
if (dtmb_new_driver)
*status = demod->last_status;
else
ret = gxtv_demod_dtmb_read_status(fe, status);
break;
#endif
default:
@@ -2759,7 +2767,10 @@ static int aml_dtvdm_tune(struct dvb_frontend *fe, bool re_tune,
#endif
#ifdef AML_DEMOD_SUPPORT_DTMB
case SYS_DTMB:
ret = gxtv_demod_dtmb_tune(fe, re_tune, mode_flags, delay, status);
if (dtmb_new_driver)
ret = dtmb_tune(fe, re_tune, mode_flags, delay, status);
else
ret = gxtv_demod_dtmb_tune(fe, re_tune, mode_flags, delay, status);
break;
#endif
default:
+158 -1
View File
@@ -40,6 +40,20 @@
#include "addr_dtmb_top.h"
#include <linux/amlogic/aml_dtvdemod.h>
#define DTMB_TIME_CHECK_SIGNAL 150
static unsigned int dtmb_check_signal_time = DTMB_TIME_CHECK_SIGNAL;
MODULE_PARM_DESC(dtmb_check_signal_time, "\n\t\t dtmb check signal time");
module_param(dtmb_check_signal_time, int, 0644);
static unsigned int dtmb_lock_continuous_cnt = 1;
MODULE_PARM_DESC(dtmb_lock_continuous_cnt, "\n\t\t dtmb lock signal continuous counting");
module_param(dtmb_lock_continuous_cnt, int, 0644);
static unsigned int dtmb_lost_continuous_cnt = 15;
MODULE_PARM_DESC(dtmb_lost_continuous_cnt, "\n\t\t dtmb lost signal continuous counting");
module_param(dtmb_lost_continuous_cnt, int, 0644);
void gxtv_demod_dtmb_release(struct dvb_frontend *fe)
{
}
@@ -407,7 +421,8 @@ int gxtv_demod_dtmb_set_frontend(struct dvb_frontend *fe)
#endif
tuner_set_params(fe);
msleep(100);
if (!dtmb_new_driver)
msleep(100);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
if (fe->ops.tuner_ops.get_if_frequency)
@@ -490,6 +505,148 @@ int gxtv_demod_dtmb_tune(struct dvb_frontend *fe, bool re_tune,
return ret;
}
static void dtmb_read_status(struct dvb_frontend *fe, enum fe_status *status, unsigned int re_tune,
unsigned int *delay)
{
int i, lock;//0:none;1:lock;-1:lost
s16 strength;
unsigned int fsm_state, val, cur_time;
struct aml_dtvdemod *demod = (struct aml_dtvdemod *)fe->demodulator_priv;
static int lock_status;
static int has_signal;
//Threshold value of times of continuous lock and lost
int lock_continuous_cnt = dtmb_lock_continuous_cnt > 1 ? dtmb_lock_continuous_cnt : 1;
int lost_continuous_cnt = dtmb_lost_continuous_cnt > 1 ? dtmb_lost_continuous_cnt : 1;
int check_signal_time = dtmb_check_signal_time > 1 ? dtmb_check_signal_time :
DTMB_TIME_CHECK_SIGNAL;
int tuner_strength_threshold = THRD_TUNER_STRENGTH_DTMB;
cur_time = jiffies_to_msecs(jiffies);
if (re_tune) {
lock_status = 0;
has_signal = 0;
demod->time_start = cur_time;
*status = 0;
demod->last_status = 0;
dtmb_bch_check_new(fe, true);
return;
}
demod->time_passed = jiffies_to_msecs(jiffies) - demod->time_start;
gxtv_demod_dtmb_read_signal_strength(fe, &strength);
if (strength < tuner_strength_threshold && demod->time_passed < check_signal_time) {
*status = FE_TIMEDOUT;
PR_DTMB("%s: tuner strength [%d] no signal(%d).\n",
__func__, strength, tuner_strength_threshold);
goto finish;
}
fsm_state = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0);
for (i = 0; i < 8; i++)
if (((fsm_state >> (i * 4)) & 0xf) > 4)
has_signal = 0x1;
val = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR);
if (is_meson_gxtvbb_cpu())
demod->real_para.snr = convert_snr(val & 0xfff) * 10;
else
demod->real_para.snr = convert_snr(val & 0x3fff) * 10;
PR_DTMB("fsm=0x%x, r_snr=0x%x, snr=%d dB*10, time_passed=%d\n",
fsm_state, val, demod->real_para.snr, demod->time_passed);
if (val & 0x4000) {
lock = 1;
has_signal = 1;
dtmb_bch_check_new(fe, false);
*delay = 100;
} else {
if (demod->time_passed <= check_signal_time ||
(demod->time_passed <= TIMEOUT_DTMB && has_signal)) {
lock = 0;
} else {
lock = -1;
if (lock_status == 0) {//not dtmb signal
*status = FE_TIMEDOUT;
PR_ATSC("not dtmb signal\n");
goto finish;
}
}
}
//The status is updated only when the status continuously reaches the threshold of times
if (lock == -1) {
if (lock_status >= 0) {
lock_status = -1;
PR_ATSC("==> lost signal first\n");
} else if (lock_status <= -lost_continuous_cnt) {
lock_status = -lost_continuous_cnt;
PR_ATSC("==> lost signal continue\n");
} else {
lock_status--;
PR_ATSC("==> lost signal times%d\n", lock_status);
}
if (lock_status <= -lost_continuous_cnt)
*status = FE_TIMEDOUT;
else
*status = 0;
} else if (lock == 1) {
if (lock_status <= 0) {
lock_status = 1;
PR_ATSC("==> lock signal first\n");
} else if (lock_status >= lock_continuous_cnt) {
lock_status = lock_continuous_cnt;
PR_ATSC("==> lock signal continue\n");
} else {
lock_status++;
PR_ATSC("==> lock signal times:%d\n", lock_status);
}
if (lock_status >= lock_continuous_cnt)
*status = FE_HAS_LOCK | FE_HAS_SIGNAL |
FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
else
*status = 0;
} else {
*status = 0;
}
finish:
if (demod->last_status != *status && *status != 0) {
PR_INFO("!! >> %s << !!, freq=%d, time_passed=%d\n", *status == FE_TIMEDOUT ?
"UNLOCK" : "LOCK", fe->dtv_property_cache.frequency, demod->time_passed);
demod->last_status = *status;
}
}
int dtmb_tune(struct dvb_frontend *fe, bool re_tune,
unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
{
struct aml_dtvdemod *demod = (struct aml_dtvdemod *)fe->demodulator_priv;
*delay = HZ / 20;
if (re_tune) {
PR_INFO("%s [id %d]: re_tune.\n", __func__, demod->id);
demod->en_detect = 1;
gxtv_demod_dtmb_set_frontend(fe);
dtmb_read_status(fe, status, re_tune, delay);
*status = 0;
return 0;
}
dtmb_read_status(fe, status, re_tune, delay);
return 0;
}
int Gxtv_Demod_Dtmb_Init(struct aml_dtvdemod *demod)
{
int ret = 0;
@@ -21,6 +21,8 @@
#define DTMBM_POLL_DELAY_NO_SIGNAL (120)
#define DTMBM_POLL_DELAY_HAVE_SIGNAL (100)
extern unsigned char dtmb_new_driver;
void dtmb_save_status(struct aml_dtvdemod *demod, unsigned int s);
void dtmb_poll_start(struct aml_dtvdemod *demod);
void dtmb_poll_stop(struct aml_dtvdemod *demod);
@@ -42,6 +44,8 @@ int gxtv_demod_dtmb_set_frontend(struct dvb_frontend *fe);
int gxtv_demod_dtmb_get_frontend(struct dvb_frontend *fe);
int gxtv_demod_dtmb_tune(struct dvb_frontend *fe, bool re_tune,
unsigned int mode_flags, unsigned int *delay, enum fe_status *status);
int dtmb_tune(struct dvb_frontend *fe, bool re_tune,
unsigned int mode_flags, unsigned int *delay, enum fe_status *status);
int Gxtv_Demod_Dtmb_Init(struct aml_dtvdemod *demod);
int amdemod_stat_dtmb_islock(struct aml_dtvdemod *demod,
enum fe_delivery_system delsys);
+45
View File
@@ -457,6 +457,51 @@ int dtmb_bch_check(struct dvb_frontend *fe)
return 0;
}
void dtmb_bch_check_new(struct dvb_frontend *fe, bool reset)
{
struct aml_dtvdemod *demod = (struct aml_dtvdemod *)fe->demodulator_priv;
struct amldtvdemod_device_s *devp = (struct amldtvdemod_device_s *)demod->priv;
int fec_bch;
static int last_fec_bch;
union DTMB_TOP_CTRL_SW_RST_BITS sw_rst;
unsigned int val;
if (reset) {
last_fec_bch = -1;
return;
}
fec_bch = dtmb_reg_r_bch();
if (last_fec_bch != -1 && (fec_bch - last_fec_bch) > 50) {
PR_DTMB("fec lock, but bch add, need reset\n");
if (devp->data->hw_ver == DTVDEMOD_HW_T3) {
val = dtmb_read_reg(0x7);
PR_INFO("dtmb set ddr\n");
dtmb_write_reg(0x7, 0x6ffffd);
//dtmb_write_reg(0x47, 0xed33221);
dtmb_write_reg_bits(0x47, 0x1, 22, 1);
dtmb_write_reg_bits(0x47, 0x1, 23, 1);
msleep(20);
}
sw_rst.b.ctrl_sw_rst = 1;
sw_rst.b.ctrl_sw_rst_noreg = 1;
dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32);
if (devp->data->hw_ver == DTVDEMOD_HW_T3) {
clear_ddr_bus_data(demod);
dtmb_write_reg(0x7, val);
dtmb_write_reg_bits(0x47, 0x0, 22, 1);
dtmb_write_reg_bits(0x47, 0x0, 23, 1);
}
sw_rst.b.ctrl_sw_rst = 0;
sw_rst.b.ctrl_sw_rst_noreg = 0;
dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32);
}
last_fec_bch = fec_bch;
}
int dtmb_constell_check(void)
{
int constell;
@@ -156,6 +156,7 @@
/* V3.5.029 fix atsc-c signal strength issue */
/* V3.5.030 fix dvbt overflow when 6M 1/4 and other param */
/* V3.5.031 calibrate dvbc signal strength read from R842 */
/* V3.5.032 rebuild dtmb driver */
/****************************************************/
/****************************************************************/
/* AMLDTVDEMOD_VER Description: */
@@ -172,8 +173,8 @@
/*->The last four digits indicate the release time */
/****************************************************************/
#define KERNEL_4_9_EN 1
#define AMLDTVDEMOD_VER "V3.5.031"
#define DTVDEMOD_VER "2024/01/03: calibrate dvbc signal strength read from R842"
#define AMLDTVDEMOD_VER "V3.5.032"
#define DTVDEMOD_VER "2024/02/27: rebuild dtmb driver"
#define AMLDTVDEMOD_T2_FW_VER "20231019_141000"
#define DEMOD_DEVICE_NAME "dtvdemod"
@@ -201,6 +202,7 @@
#ifdef AML_DEMOD_SUPPORT_DTMB
#define THRD_TUNER_STRENGTH_DTMB (-100)
#define TIMEOUT_DTMB 2500
#endif
#ifdef AML_DEMOD_SUPPORT_DVBC
@@ -755,6 +755,7 @@ void dtmb_reset(void);
int dtmb_check_status_gxtv(struct dvb_frontend *fe);
int dtmb_check_status_txl(struct dvb_frontend *fe);
int dtmb_bch_check(struct dvb_frontend *fe);
void dtmb_bch_check_new(struct dvb_frontend *fe, bool reset);
void dtmb_write_reg(unsigned int reg_addr, unsigned int reg_data);
unsigned int dtmb_read_reg(unsigned int reg_addr);
void dtmb_write_reg_bits(u32 addr, const u32 data, const u32 start, const u32 len);