__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;
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();
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;
}
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;
#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 */
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 {
unsigned int retry_cnt;
/*****************/
bool combing_fix_en;
+ unsigned int comb_mode;
+ /*struct di_patch_mov_s mov;*/
};
struct di_post_stru_s {
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;
}
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)
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)
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;
{"dumpmif", S_IFREG | 0644, &seq_file_dump_mif_size_state_fops},
{"dumpafbc", S_IFREG | 0644, &seq_file_afbc_fops},
{"reg_cue", S_IFREG | 0644, ®_cue_int_fops},
+ {"dumpmov", S_IFREG | 0644, &dbg_patch_mov_data_fops},
};
void di_debugfs_init(void)
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;
}
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,
/*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);
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;
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,
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,
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,
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);
}
/* combing adaptive */
struct combing_status_s *mtn_status;
bool combing_fix_en;
+ unsigned int comb_mode;
};
struct di_post_stru_s {