From a67313fd7f0f7d64040b755576ef8b2901612f9e Mon Sep 17 00:00:00 2001 From: Jihong Sui Date: Sun, 29 Sep 2019 18:56:32 +0800 Subject: [PATCH] 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 --- drivers/amlogic/media/deinterlace/deinterlace.c | 173 ++++++++++++++++++++- drivers/amlogic/media/deinterlace/deinterlace.h | 26 ++++ .../amlogic/media/deinterlace/deinterlace_dbg.c | 29 ++++ drivers/amlogic/media/deinterlace/deinterlace_hw.c | 5 +- .../amlogic/media/deinterlace/deinterlace_mtn.c | 33 +++- .../amlogic/media/deinterlace/deinterlace_mtn.h | 2 +- drivers/amlogic/media/deinterlace/di_pqa.h | 2 +- drivers/amlogic/media/di_multi/deinterlace.c | 4 +- drivers/amlogic/media/di_multi/deinterlace.h | 1 + 9 files changed, 266 insertions(+), 9 deletions(-) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 9f1bcba..1401ba7 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -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; diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index 2cae178..d93e312 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -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 { diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c index 191f686..ac68b40 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c @@ -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, ®_cue_int_fops}, + {"dumpmov", S_IFREG | 0644, &dbg_patch_mov_data_fops}, }; void di_debugfs_init(void) diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index 172de4f..b4a2e2f 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -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, diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c index 5d19a12..12e029a 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c @@ -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, diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.h b/drivers/amlogic/media/deinterlace/deinterlace_mtn.h index 8c7c6d2..0592f5d 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_mtn.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.h @@ -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, diff --git a/drivers/amlogic/media/deinterlace/di_pqa.h b/drivers/amlogic/media/deinterlace/di_pqa.h index 74d669b..fcf3e54 100644 --- a/drivers/amlogic/media/deinterlace/di_pqa.h +++ b/drivers/amlogic/media/deinterlace/di_pqa.h @@ -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, diff --git a/drivers/amlogic/media/di_multi/deinterlace.c b/drivers/amlogic/media/di_multi/deinterlace.c index 21b129d..1190401 100644 --- a/drivers/amlogic/media/di_multi/deinterlace.c +++ b/drivers/amlogic/media/di_multi/deinterlace.c @@ -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); } diff --git a/drivers/amlogic/media/di_multi/deinterlace.h b/drivers/amlogic/media/di_multi/deinterlace.h index a529710..96abc67 100644 --- a/drivers/amlogic/media/di_multi/deinterlace.h +++ b/drivers/amlogic/media/di_multi/deinterlace.h @@ -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 { -- 2.7.4