mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
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:
committed by
gerrit autosubmit
parent
88da7efe65
commit
d37f84a2e1
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user