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 <kele.bai@amlogic.com>
This commit is contained in:
kele bai
2018-05-15 17:33:55 +08:00
committed by Yixun Lan
parent 276b415992
commit 348e23ccb5
6 changed files with 149 additions and 22 deletions

View File

@@ -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);

View File

@@ -29,6 +29,7 @@
#include <linux/amlogic/media/vfm/vframe_provider.h>
#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

View File

@@ -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;

View File

@@ -21,7 +21,9 @@
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include <linux/amlogic/iomap.h>
#include <linux/amlogic/cpu_version.h>
#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));
}
}

View File

@@ -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))

View File

@@ -17,6 +17,7 @@
#ifndef _DNR_H
#define _DNR_H
#include <linux/atomic.h>
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