mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user