deinterlace: pq: add save db value interface [1/2]

PD#SWPL-15705

Problem:
VLSI finetue TL1 1080i mtn setting.

Solution:
a. add di_gmv in vframe type;
b. add interface for save db setting and switch;
-api:void di_patch_mov_setreg(unsigned int nub, unsigned int *preg)
-for set register that you want to save from db;
-preg: register list that you want to save from db; < 5
-api:bool di_api_mov_sel(unsigned int mode, unsigned int *pdate)
-to set register that you save;
-mode:0:value from db;1: setting from pq
-*pdate: data from pq, value/mask
- pdate need keep same order from preg;
c. add interface for switch 1080i comb setting
-void di_set_comb_mode(unsigned int mode)
-mode:0: set nothing; 1:fix_tl1_1080i_sawtooth_patch;
2: new 1080i setting;

Verify:
tl1

Change-Id: I8e0f084d33757ab0e48fb49aececc020dae5c62d
Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>
This commit is contained in:
Jihong Sui
2019-09-29 18:56:32 +08:00
committed by Tao Zeng
parent 2a5149de90
commit a67313fd7f
9 changed files with 266 additions and 9 deletions

View File

@@ -2448,6 +2448,173 @@ static void di_cma_release(struct di_dev_s *devp)
__func__, rels_cnt, delta_time, start_time, end_time);
}
#endif
static void di_patch_mov_ini(void)
{
struct di_patch_mov_s *pmov;
if (!de_devp)
return;
pmov = &de_devp->mov;
if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
pmov->en_support = false;
return;
}
pmov->en_support = true;
pmov->mode = -1;
pmov->nub = 0;
}
bool di_patch_mov_db(unsigned int addr, unsigned int val)
{
bool ret = false;
int i;
struct di_patch_mov_s *pmov;
struct di_patch_mov_d_s *pmv;
if (!de_devp)
return ret;
pmov = &de_devp->mov;
if (!pmov->en_support || !pmov->nub)
return ret;
for (i = 0; i < pmov->nub; i++) {
if (addr == pmov->reg_addr[i]) {
pmv = &pmov->val_db[i];
pmv->val = val;
pmv->en = true;
pmv->mask = 0xffffffff;
ret = true;
}
}
return ret;
}
void di_patch_mov_setreg(unsigned int nub, unsigned int *preg)
{
struct di_patch_mov_s *pmov;
unsigned int i;
if (!de_devp)
return;
pmov = &de_devp->mov;
if (!pmov->en_support)
return;
pmov->nub = nub;
if (nub > DI_PATCH_MOV_MAX_NUB) {
pr_error("err: %s:nub is overflow %d\n",
__func__, nub);
pmov->nub = DI_PATCH_MOV_MAX_NUB;
}
pmov->mode = -1;
for (i = 0; i < pmov->nub; i++) {
pmov->reg_addr[i] = preg[i];
di_pr_info("reg:0x%x\n", preg[i]);
}
}
EXPORT_SYMBOL(di_patch_mov_setreg);
/**************************************************
* pdate:
* value / mask
* value / mask
* need keep same order with di_patch_mov_setreg
**************************************************/
bool di_api_mov_sel(unsigned int mode, unsigned int *pdate)
{
struct di_patch_mov_s *pmov;
int i;
struct di_patch_mov_d_s *pmv;
bool ret = true;
if (!de_devp)
return false;
pmov = &de_devp->mov;
if (!pmov ||
!pmov->en_support ||
!init_flag)
return false;
switch (mode) {
case 0:/*setting from db*/
pmov->mode = 0;
pmov->update = 1;
break;
case 1:/*setting from pq*/
pmov->update = 0;
for (i = 0; i < pmov->nub; i++) {
pmv = &pmov->val_pq[i];
pmv->val = pdate[i * 2];
pmv->mask = pdate[i * 2 + 1];
pmv->en = true;
}
pmov->mode = 1;
pmov->update = true;
break;
default:
ret = false;
break;
}
return ret;
}
EXPORT_SYMBOL(di_api_mov_sel);
static void di_patch_mov_setting(void)
{
struct di_patch_mov_s *pmov;
int i;
struct di_patch_mov_d_s *pmv;
unsigned int val;
if (!de_devp)
return;
pmov = &de_devp->mov;
if (!pmov ||
!pmov->en_support ||
pmov->mode < 0 ||
pmov->mode > 1 ||
!pmov->update)
return;
if (pmov->mode == 0)
pmv = &pmov->val_db[0];
else
pmv = &pmov->val_pq[0];
for (i = 0; i < pmov->nub; i++) {
if (pmv->en) {
if (pmv->mask != 0xffffffff) {
val = ((RDMA_RD(pmov->reg_addr[i]) &
(~(pmv->mask))) |
(pmv->val & pmv->mask));
} else {
val = pmv->val;
}
DI_Wr(pmov->reg_addr[i], val);
}
pmv++;
}
pmov->update = 0;
}
void di_set_comb_mode(unsigned int mode)
{
di_pre_stru.comb_mode = mode;
}
EXPORT_SYMBOL(di_set_comb_mode);
static int di_init_buf(int width, int height, unsigned char prog_flag)
{
int i;
@@ -3391,6 +3558,7 @@ static void pre_de_process(void)
di_pre_stru.input_size_change_flag = false;
}
di_patch_mov_setting();
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
if (de_devp->nrds_enable) {
nr_ds_mif_config();
@@ -4633,10 +4801,10 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
return 0;
}
if (is_meson_tl1_cpu() &&
combing_fix_en &&
di_pre_stru.comb_mode &&
flg_1080i) {
di_pre_stru.combing_fix_en = false;
fix_tl1_1080i_sawtooth_patch();
fix_tl1_1080i_patch_sel(di_pre_stru.comb_mode);
} else {
di_pre_stru.combing_fix_en = combing_fix_en;
}
@@ -8670,6 +8838,7 @@ static int di_probe(struct platform_device *pdev)
di_patch_post_update_mc_sw(DI_MC_SW_IC, true);
dil_attach_ext_api(&di_ext);
di_patch_mov_ini();
di_pr_info("%s:ok\n", __func__);
return ret;

View File

@@ -220,6 +220,29 @@ extern bool is_vsync_rdma_enable(void);
#define TABLE_LEN_MAX 10000
#define TABLE_FLG_END (0xfffffffe)
/******************************************
* patch for TV-10258 multiwave group issue
*****************************************/
#define DI_PATCH_MOV_MAX_NUB 5
struct di_patch_mov_d_s {
unsigned int val;
unsigned int mask;
bool en;
};
struct di_patch_mov_s {
unsigned int reg_addr[DI_PATCH_MOV_MAX_NUB];
struct di_patch_mov_d_s val_db[DI_PATCH_MOV_MAX_NUB];
struct di_patch_mov_d_s val_pq[DI_PATCH_MOV_MAX_NUB];
int mode;/*-1 : not set; 0: set from db, 1: set from pq*/
bool en_support;
bool update;
unsigned int nub;
};
bool di_patch_mov_db(unsigned int addr, unsigned int val);
struct di_dev_s {
dev_t devt;
struct cdev cdev; /* The cdev structure */
@@ -254,6 +277,7 @@ struct di_dev_s {
struct page *total_pages;
atomic_t mem_flag;
struct dentry *dbg_root; /*dbg_fs*/
struct di_patch_mov_s mov;
};
struct di_pre_stru_s {
@@ -378,6 +402,8 @@ struct di_pre_stru_s {
unsigned int retry_cnt;
/*****************/
bool combing_fix_en;
unsigned int comb_mode;
/*struct di_patch_mov_s mov;*/
};
struct di_post_stru_s {

View File

@@ -589,6 +589,8 @@ static int dump_di_pre_stru_seq(struct seq_file *seq, void *v)
di_pre_stru_p->invert_flag ? "true" : "false");
seq_printf(seq, "%-25s = %s\n", "combing_fix_en",
di_pre_stru_p->combing_fix_en ? "true" : "false");
seq_printf(seq, "%-25s = %d\n", "comb_mode",
di_pre_stru_p->comb_mode);
return 0;
}
@@ -881,6 +883,7 @@ void dump_vframe(struct vframe_s *vf)
pr_info("pixel_ratio %d list %p\n",
vf->pixel_ratio, &vf->list);
pr_info("di_pulldown 0x%x\n", vf->di_pulldown);
pr_info("di_gmv 0x%x\n", vf->di_gmv);
}
void print_di_buf(struct di_buf_s *di_buf, int format)
@@ -1077,6 +1080,30 @@ void dump_afbcd_reg(void)
VD2_AFBCD1_MISC_CTRL, RDMA_RD(VD2_AFBCD1_MISC_CTRL));
}
static int dbg_patch_mov_data_show(struct seq_file *seq, void *v)
{
struct di_dev_s *de_devp = get_di_de_devp();
struct di_patch_mov_s *pmov = &de_devp->mov;
int i;
seq_printf(seq, "mode:%d\n", pmov->mode);
seq_printf(seq, "en_support:%d\n", pmov->en_support);
seq_printf(seq, "number:%d\n", pmov->nub);
seq_printf(seq, "update:%d\n", pmov->update);
for (i = 0; i < DI_PATCH_MOV_MAX_NUB; i++) {
seq_printf(seq, "index:[%d]\n", i);
seq_printf(seq, "\treg:0x%x\n", pmov->reg_addr[i]);
if (i < pmov->nub)
seq_printf(seq, "\t\t= 0x%x\n",
RDMA_RD(pmov->reg_addr[i]));
seq_printf(seq, "\tdb_val:0x%x\n", pmov->val_db[i].val);
seq_printf(seq, "\tdb_en :0x%x\n", pmov->val_db[i].en);
seq_printf(seq, "\tpq_val:0x%x\n", pmov->val_pq[i].val);
seq_printf(seq, "\tpq_val:0x%x\n", pmov->val_pq[i].en);
}
return 0;
}
/*2018-08-17 add debugfs*/
/*same as dump_state*/
static int seq_file_di_state_show(struct seq_file *seq, void *v)
@@ -1256,6 +1283,7 @@ DEFINE_SHOW_DI(seq_file_dump_di_reg);
DEFINE_SHOW_DI(seq_file_dump_mif_size_state);
DEFINE_SHOW_DI(seq_file_afbc);
DEFINE_SHOW_DI(reg_cue_int);
DEFINE_SHOW_DI(dbg_patch_mov_data);
struct di_debugfs_files_t {
const char *name;
@@ -1269,6 +1297,7 @@ static struct di_debugfs_files_t di_debugfs_files[] = {
{"dumpmif", S_IFREG | 0644, &seq_file_dump_mif_size_state_fops},
{"dumpafbc", S_IFREG | 0644, &seq_file_afbc_fops},
{"reg_cue", S_IFREG | 0644, &reg_cue_int_fops},
{"dumpmov", S_IFREG | 0644, &dbg_patch_mov_data_fops},
};
void di_debugfs_init(void)

View File

@@ -3878,6 +3878,7 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr)
unsigned int table_name = 0, nr_table = 0;
bool ctrl_reg_flag = false;
struct am_reg_s *regs_p = NULL;
bool mov_flg = false;
if (pq_load_dbg == 1)
return;
@@ -3926,7 +3927,9 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr)
}
if (table_name & nr_table)
ctrl_reg_flag = set_nr_ctrl_reg_table(addr, value);
if (!ctrl_reg_flag)
if (table_name & TABLE_NAME_DI)
mov_flg = di_patch_mov_db(addr, value);
if (!ctrl_reg_flag && !mov_flg)
DI_Wr(addr, value);
if (pq_load_dbg == 2)
pr_info("[%u][0x%x] = [0x%x] %s\n", i, addr,

View File

@@ -807,7 +807,7 @@ MODULE_PARM_DESC(di_debug_readreg, "di_debug_readreg");
/*from VLSI yanling.liu, the patch fix TL1 1080I in some dark */
/*scenes and roller coasters have small sawtooth, when turn off*/
/*combing_fix_en, set the registers*/
void fix_tl1_1080i_sawtooth_patch(void)
static void fix_tl1_1080i_sawtooth_patch(void)
{
DI_Wr(0x1741, 0x0A0A1A22);
DI_Wr(0x1742, 0x0a100101);
@@ -822,6 +822,35 @@ void fix_tl1_1080i_sawtooth_patch(void)
DI_Wr(0x17af, 0x60020a60);
}
static void fix_tl1_1080i_patch2(void)
{
DI_Wr(0x1741, 0x010a010a);
DI_Wr(0x1742, 0x01010101);
DI_Wr(0x1743, 0x00000101);
DI_Wr(0x1744, 0x00000101);
DI_Wr(0x17a9, 0x01010102);
DI_Wr(0x17aa, 0x02020101);
DI_Wr(0x17ab, 0x010a010a);
DI_Wr(0x17ac, 0x010a0102);
DI_Wr(0x17ad, 0x08080808);
DI_Wr(0x17ae, 0x01010101);
DI_Wr(0x17af, 0xff00031f);
}
void fix_tl1_1080i_patch_sel(unsigned int mode)
{
switch (mode) {
case 0:/*not set*/
break;
case 1:
fix_tl1_1080i_sawtooth_patch();
break;
case 2:
fix_tl1_1080i_patch2();
break;
}
}
static int combing_cnt;
int combing_diff_min = 2000;
int combing_diff_max = 2000;
@@ -987,7 +1016,7 @@ module_param_named(cmb_adpset_cnt, cmb_adpset_cnt, int, 0644);
static const struct mtn_op_s di_ops_mtn = {
.mtn_int_combing_glbmot = mtn_int_combing_glbmot,
.adpative_combing_exit = adpative_combing_exit,
.fix_tl1_1080i_sawtooth_patch = fix_tl1_1080i_sawtooth_patch,
.fix_tl1_1080i_patch_sel = fix_tl1_1080i_patch_sel,
.adaptive_combing_fixing = adaptive_combing_fixing,
.adpative_combing_config = adpative_combing_config,
.com_patch_pre_sw_set = com_patch_pre_sw_set,

View File

@@ -39,7 +39,7 @@ struct combing_status_s *adpative_combing_config(unsigned int width,
unsigned int height,
enum vframe_source_type_e src_type, bool prog,
enum tvin_sig_fmt_e fmt);
extern void fix_tl1_1080i_sawtooth_patch(void);
void fix_tl1_1080i_patch_sel(unsigned int mode);
int adaptive_combing_fixing(
struct combing_status_s *cmb_status,
unsigned int field_diff, unsigned int frame_diff,

View File

@@ -111,7 +111,7 @@ bool di_attach_ops_nr(const struct nr_op_s **ops);
struct mtn_op_s {
void (*mtn_int_combing_glbmot)(void);
void (*adpative_combing_exit)(void);
void (*fix_tl1_1080i_sawtooth_patch)(void);
void (*fix_tl1_1080i_patch_sel)(unsigned int mode);
int (*adaptive_combing_fixing)(
struct combing_status_s *cmb_status,
unsigned int field_diff, unsigned int frame_diff,

View File

@@ -4404,10 +4404,10 @@ unsigned char dim_pre_de_buf_config(unsigned int channel)
return 0;
}
if (is_meson_tl1_cpu() &&
di_mpr(combing_fix_en) &&
ppre->comb_mode &&
flg_1080i) {
ppre->combing_fix_en = false;
get_ops_mtn()->fix_tl1_1080i_sawtooth_patch();
get_ops_mtn()->fix_tl1_1080i_patch_sel(ppre->comb_mode);
} else {
ppre->combing_fix_en = di_mpr(combing_fix_en);
}

View File

@@ -414,6 +414,7 @@ struct di_pre_stru_s {
/* combing adaptive */
struct combing_status_s *mtn_status;
bool combing_fix_en;
unsigned int comb_mode;
};
struct di_post_stru_s {