From 348e23ccb53ed12ca11627470950a5b3efe4bcca Mon Sep 17 00:00:00 2001 From: kele bai Date: Tue, 15 May 2018 17:33:55 +0800 Subject: [PATCH] di: fix nr pq load error PD#162226: di: fix nr pq load error 1) move nr gate ctrl before nr init 2) fix skip logic error 3) load ctrl reg in irq avoid affect pre sequence Change-Id: I9b5438f55e42eabfa37e10a04dc0f3026bbbd595 Signed-off-by: kele bai --- drivers/amlogic/media/deinterlace/deinterlace.c | 8 ++- drivers/amlogic/media/deinterlace/deinterlace_hw.c | 55 +++++++++++----- drivers/amlogic/media/deinterlace/deinterlace_hw.h | 2 + drivers/amlogic/media/deinterlace/detect3d.c | 14 +++- drivers/amlogic/media/deinterlace/nr_drv.c | 76 +++++++++++++++++++++- drivers/amlogic/media/deinterlace/nr_drv.h | 16 +++++ 6 files changed, 149 insertions(+), 22 deletions(-) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 99f719c..bbd5aa3 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -2042,7 +2042,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) } #ifdef CONFIG_CMA if (de_devp->flag_cma == 1) { - pr_dbg("%s:cma alloc req time: %d ms\n", + pr_dbg("%s:cma alloc req time: %u ms\n", __func__, jiffies_to_msecs(jiffies)); atomic_set(&de_devp->mem_flag, 0); di_pre_stru.cma_alloc_req = 1; @@ -5640,9 +5640,10 @@ static void di_unreg_process_irq(void) enable_di_pre_mif(false, mcpre_en); di_hw_uninit(); if (is_meson_txlx_cpu() || is_meson_txhd_cpu() - || is_meson_g12a_cpu()) + || is_meson_g12a_cpu()) { di_pre_gate_control(false, mcpre_en); - else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { + nr_gate_control(false); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { DI_Wr(DI_CLKG_CTRL, 0x80f60000); DI_Wr(DI_PRE_CTRL, 0); } else @@ -5888,6 +5889,7 @@ static void di_reg_process_irq(void) de_devp->flags |= DI_VPU_CLKB_SET; enable_di_pre_mif(true, mcpre_en); di_pre_gate_control(true, mcpre_en); + nr_gate_control(true); } else { /* if mcdi enable DI_CLKG_CTRL should be 0xfef60000 */ DI_Wr(DI_CLKG_CTRL, 0xfef60001); diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index ed113a1..c4b3bcd 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -29,6 +29,7 @@ #include #include "deinterlace_hw.h" #include "register.h" +#include "register_nr4.h" #ifdef DET3D #include "detect3d.h" #endif @@ -56,9 +57,7 @@ static unsigned int pq_load_dbg; module_param_named(pq_load_dbg, pq_load_dbg, uint, 0644); static bool pd22_flg_calc_en = true; -#ifdef DEBUG_SUPPORT -module_param_named(pd22_flg_calc_en, pd22_flg_calc_en, bool, 0644); -#endif +static unsigned int ctrl_regs[SKIP_CTRE_NUM]; #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA extern u32 VSYNC_RD_MPEG_REG(u32 adr); @@ -421,7 +420,26 @@ static void pre_hold_block_mode_config(void) DI_Wr(DI_PRE_HOLD, (1 << 31) | (31 << 16) | 31); } } - +/* + * ctrl or size related regs configured + * in software base on real size and condition + */ +static void set_skip_ctrl_size_regs(void) +{ + ctrl_regs[0] = DI_CLKG_CTRL; + ctrl_regs[1] = DI_MTN_1_CTRL1; + ctrl_regs[2] = MCDI_MOTINEN; + ctrl_regs[3] = MCDI_CTRL_MODE; + ctrl_regs[4] = MCDI_MC_CRTL; + ctrl_regs[5] = MCDI_PD_22_CHK_WND0_X; + ctrl_regs[6] = MCDI_PD_22_CHK_WND0_Y; + ctrl_regs[7] = MCDI_PD_22_CHK_WND1_X; + ctrl_regs[8] = MCDI_PD_22_CHK_WND1_Y; + ctrl_regs[9] = NR4_MCNR_LUMA_STAT_LIMTX; + ctrl_regs[10] = NR4_MCNR_LUMA_STAT_LIMTY; + ctrl_regs[11] = NR4_NM_X_CFG; + ctrl_regs[12] = NR4_NM_Y_CFG; +} void di_hw_init(bool pd_enable, bool mc_enable) { unsigned short fifo_size_vpp = 0xc0; @@ -473,7 +491,7 @@ void di_hw_init(bool pd_enable, bool mc_enable) } pre_hold_block_mode_config(); - + set_skip_ctrl_size_regs(); ma_di_init(); ei_hw_init(); nr_hw_init(); @@ -2987,7 +3005,6 @@ void combing_pd22_window_config(unsigned int width, unsigned int height) DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, (width-1), 16, 13);/* pd22 x1 */ DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, 0, 0, 13);/* pd22 y0 */ DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, y1, 16, 13);/* pd y1 */ - DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, 0, 0, 13);/* pd x0 */ DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, (width-1), 16, 13);/* pd x1 */ DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_Y, (y1+1), 0, 13);/* pd y0 */ @@ -3042,12 +3059,13 @@ void pulldown_vof_win_config(struct pulldown_detected_s *wins) wins->regs[3].blend_mode, 14, 2); } + void di_load_regs(struct di_pq_parm_s *di_pq_ptr) { unsigned int i = 0, j = 0, addr = 0, value = 0, mask = 0, len; - unsigned int ctrl_reg[6] = {0x1707, 0x1718, 0x2d60, - 0x2dff, 0x2f04, 0x2f70}; - struct am_reg_s *regs_p; + unsigned int table_name = 0, nr_table = 0; + bool ctrl_reg_flag = false; + struct am_reg_s *regs_p = NULL; if (pq_load_dbg == 1) return; @@ -3059,9 +3077,12 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr) pr_err("[DI] table ptr error.\n"); return; } + nr_table = TABLE_NAME_NR | TABLE_NAME_DEBLOCK | TABLE_NAME_DEMOSQUITO; regs_p = (struct am_reg_s *)di_pq_ptr->regs; len = di_pq_ptr->pq_parm.table_len; + table_name = di_pq_ptr->pq_parm.table_name; for (i = 0; i < len; i++) { + ctrl_reg_flag = false; addr = regs_p->addr; value = regs_p->val; mask = regs_p->mask; @@ -3069,8 +3090,8 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr) pr_info("[%u][0x%x] = [0x%x]&[0x%x]\n", i, addr, value, mask); - for (j = 0; j < 6; j++) { - if (addr == ctrl_reg[j]) + for (j = 0; j < SKIP_CTRE_NUM; j++) { + if (addr == ctrl_regs[j]) break; } @@ -3078,14 +3099,17 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr) value = ((Rd(addr) & (~(mask))) | (value & mask)); } - if (j < 6) { + regs_p++; + if (j < SKIP_CTRE_NUM) { if (pq_load_dbg == 3) pr_info("%s skip [0x%x]=[0x%x].\n", __func__, addr, value); - break; + continue; } - regs_p++; - DI_Wr(addr, value); + if (table_name & nr_table) + ctrl_reg_flag = set_nr_ctrl_reg_table(addr, value); + if (!ctrl_reg_flag) + DI_Wr(addr, value); if (pq_load_dbg == 2) pr_info("[%u][0x%x] = [0x%x] %s\n", i, addr, value, Rd(addr) != value?"fail":"success"); @@ -3098,4 +3122,5 @@ module_param_named(pre_hold_line, pre_hold_line, ushort, 0644); module_param_named(pre_ctrl, pre_ctrl, uint, 0644); module_param_named(line_num_post_frst, line_num_post_frst, ushort, 0644); module_param_named(line_num_pre_frst, line_num_pre_frst, ushort, 0644); +module_param_named(pd22_flg_calc_en, pd22_flg_calc_en, bool, 0644); #endif diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index 1ee22e4..ce13458 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -26,6 +26,8 @@ #define MIN_POST_WIDTH 80 #define MIN_BLEND_WIDTH 27 +#define SKIP_CTRE_NUM 13 + struct DI_MIF_s { unsigned short luma_x_start0; unsigned short luma_x_end0; diff --git a/drivers/amlogic/media/deinterlace/detect3d.c b/drivers/amlogic/media/deinterlace/detect3d.c index 320edf2..6a0bacb 100644 --- a/drivers/amlogic/media/deinterlace/detect3d.c +++ b/drivers/amlogic/media/deinterlace/detect3d.c @@ -21,7 +21,9 @@ #include #include +#include #include "register.h" +#include "register_nr4.h" #include "detect3d.h" /*******************Local defines**********************/ @@ -111,13 +113,21 @@ void det3d_config(bool flag) DI_Wr_reg_bits(DET3D_MOTN_CFG, 1, DET3D_INTR_EN_BIT, DET3D_INTR_EN_WID); /* enable 3D detection */ - DI_Wr_reg_bits(NR2_SW_EN, 1, DET3D_EN_BIT, DET3D_EN_WID); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) + DI_Wr_reg_bits(NR4_TOP_CTRL, 1, 14, 1); + else + DI_Wr_reg_bits(NR2_SW_EN, 1, + DET3D_EN_BIT, DET3D_EN_WID); } else{ /* Det 3D interrupt disable */ DI_Wr_reg_bits(DET3D_MOTN_CFG, 0, DET3D_INTR_EN_BIT, DET3D_INTR_EN_WID); /* disable 3D detection */ - DI_Wr_reg_bits(NR2_SW_EN, 0, DET3D_EN_BIT, DET3D_EN_WID); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) + DI_Wr_reg_bits(NR4_TOP_CTRL, 0, 14, 1); + else + DI_Wr_reg_bits(NR2_SW_EN, 0, + DET3D_EN_BIT, DET3D_EN_WID); memset(&det3d_info, 0, sizeof(det3d_info)); } } diff --git a/drivers/amlogic/media/deinterlace/nr_drv.c b/drivers/amlogic/media/deinterlace/nr_drv.c index 3a4fb07..85c3702 100644 --- a/drivers/amlogic/media/deinterlace/nr_drv.c +++ b/drivers/amlogic/media/deinterlace/nr_drv.c @@ -44,6 +44,8 @@ module_param_named(dnr_en, dnr_en, bool, 0644); static unsigned int nr2_en = 0x1; module_param_named(nr2_en, nr2_en, uint, 0644); +static bool nr_ctrl_reg; + int global_bs_calc_sw(int *pGbsVldCnt, int *pGbsVldFlg, int *pGbs, @@ -393,7 +395,6 @@ void nr_all_config(unsigned short width, unsigned short height, nr_param.height = height; nr_param.frame_count = 0; nr_param.prog_flag = field_type?false:true; - nr_gate_control(true); nr2_config(width, height); dnr_config(nr_param.pdnr_parm, width, height); @@ -728,9 +729,52 @@ void adaptive_cue_adjust(unsigned int frame_diff, unsigned int field_diff) } } +/* + * insert nr ctrl regs into ctrl table + */ +bool set_nr_ctrl_reg_table(unsigned int addr, unsigned int value) +{ + unsigned int i = 0; + struct NR_CTRL_REGS_s *pnr_regs = NULL; + + pnr_regs = nr_param.pnr_regs; + for (i = 0; i < NR_CTRL_REG_NUM; i++) { + if (pnr_regs->regs[i].addr == addr) { + pnr_regs->regs[i].addr = addr; + pnr_regs->regs[i].value = value; + atomic_set(&pnr_regs->regs[i].load_flag, 1); + if (nr_ctrl_reg) + pr_info("NR_CTRL_REG[0x%x]=[0x%x].\n", + addr, value); + return true; + } + } + return false; +} + +/* load nr related ctrl regs */ +static void nr_ctrl_reg_load(struct NR_CTRL_REGS_s *pnr_regs) +{ + unsigned int i = 0; + + for (i = 0; i < pnr_regs->reg_num; i++) { + if (atomic_read(&pnr_regs->regs[i].load_flag)) { + DI_Wr(pnr_regs->regs[i].addr, + pnr_regs->regs[i].value); + atomic_set(&pnr_regs->regs[i].load_flag, 0); + if (nr_ctrl_reg) { + pr_info("LOAD NR[0x%x]=[0x%x]\n", + pnr_regs->regs[i].addr, + pnr_regs->regs[i].value); + } + } + } +} + void nr_process_in_irq(void) { nr_param.frame_count++; + nr_ctrl_reg_load(nr_param.pnr_regs); if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) cue_process_irq(); if (dnr_en) @@ -1123,13 +1167,36 @@ void nr_gate_control(bool gate) DI_Wr_reg_bits(NR4_TOP_CTRL, 1, 20, 2); } } +/* + * set ctrl reg address need load in irq + */ +static void nr_ctrl_regs_init(struct NR_CTRL_REGS_s *pnr_regs) +{ + unsigned int i = 0; + + pnr_regs->regs[0].addr = NR4_TOP_CTRL; + pnr_regs->regs[1].addr = NR_DB_FLT_CTRL; + pnr_regs->regs[2].addr = DNR_DM_CTRL; + pnr_regs->regs[3].addr = DI_NR_CTRL0; + pnr_regs->regs[4].addr = DNR_CTRL; + pnr_regs->regs[5].addr = NR2_CUE_PRG_DIF; + pnr_regs->reg_num = NR_CTRL_REG_NUM; + for (i = 0; i < pnr_regs->reg_num; i++) { + pnr_regs->regs[i].value = 0; + atomic_set(&pnr_regs->regs[i].load_flag, 0); + } +} + void nr_drv_uninit(struct device *dev) { if (nr_param.pnr4_parm) { vfree(nr_param.pnr4_parm); nr_param.pnr4_parm = NULL; } - + if (nr_param.pnr_regs) { + vfree(nr_param.pnr_regs); + nr_param.pnr_regs = NULL; + } if (nr_param.pcue_parm) { vfree(nr_param.pcue_parm); nr_param.pcue_parm = NULL; @@ -1151,6 +1218,11 @@ void nr_drv_init(struct device *dev) device_create_file(dev, &dev_attr_nr4_param); } } + nr_param.pnr_regs = vmalloc(sizeof(struct NR_CTRL_REGS_s)); + if (IS_ERR(nr_param.pnr_regs)) + pr_err("%s allocate ctrl regs error.\n", __func__); + else + nr_ctrl_regs_init(nr_param.pnr_regs); if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) { nr_param.pcue_parm = vmalloc(sizeof(struct CUE_PARM_s)); if (IS_ERR(nr_param.pcue_parm)) diff --git a/drivers/amlogic/media/deinterlace/nr_drv.h b/drivers/amlogic/media/deinterlace/nr_drv.h index 715b3fe..85e8587 100644 --- a/drivers/amlogic/media/deinterlace/nr_drv.h +++ b/drivers/amlogic/media/deinterlace/nr_drv.h @@ -17,6 +17,7 @@ #ifndef _DNR_H #define _DNR_H +#include struct nr_param_s { char *name; @@ -76,6 +77,19 @@ struct CUE_PARM_s { int frame_count; }; +#define NR_CTRL_REG_NUM 6 +/* nr ctrl reg addr,value, flag*/ +struct NR_CTRL_REG_s { + unsigned int addr; + unsigned int value; + atomic_t load_flag; +}; + +struct NR_CTRL_REGS_s { + struct NR_CTRL_REG_s regs[NR_CTRL_REG_NUM]; + unsigned int reg_num; +}; + struct NR_PARM_s { unsigned short width; unsigned short height; @@ -84,6 +98,7 @@ struct NR_PARM_s { struct DNR_PARM_s *pdnr_parm; struct NR4_PARM_s *pnr4_parm; struct CUE_PARM_s *pcue_parm; + struct NR_CTRL_REGS_s *pnr_regs; }; #ifndef SGN2 #define SGN2(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : 0)) @@ -153,5 +168,6 @@ void nr_drv_uninit(struct device *dev); void nr_process_in_irq(void); void nr_all_config(unsigned short nCol, unsigned short nRow, unsigned short type); +bool set_nr_ctrl_reg_table(unsigned int addr, unsigned int value); #endif -- 2.7.4