blob: 988a0b0b36a5dfe70bbe72543215300c700073c6 [file] [edit]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* drivers/amlogic/media/di_multi/nr_downscale.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/dma-map-ops.h>
#include <linux/amlogic/iomap.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/canvas/canvas_mgr.h>
#include <linux/amlogic/media/ppmgr/tbff.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "register.h"
#include "nr_downscale.h"
#include "di_data_l.h"
#include "di_sys.h"
#include "di_api.h"
#include "di_dbg.h"
#include "di_prc.h"
#include "di_reg_v3.h"
#include "tb_task.h"
#ifdef DIM_TB_DETECT
struct tb_core_s {
unsigned int di_tb_quit_flag : 1,
first_frame : 1,
reset_tb : 1,
cur_invert : 2,
cur_invert_a : 2,
cur_invert_b : 2,
cur_invert_c : 2,
nr_dump_en : 1,
rev : 20;
u8 dim_tb_detect_last_flag;
unsigned int di_tb_buff_wptr;
unsigned int di_tb_buff_rptr;
s8 di_tb_buffer_status;
unsigned int di_tb_buffer_start;
void *virt;
unsigned int di_tb_buffer_size;
unsigned int di_tb_buffer_len;
u8 di_tb_first_frame_type;
int first_frame_type;
unsigned int skip_picture;
u8 last_type;
unsigned int last_width;
unsigned int last_height;
unsigned int di_tb_init_mute;
unsigned int init_mute;
atomic_t di_tb_sem;
atomic_t dim_detect_status;
atomic_t dim_tb_detect_flag;
atomic_t di_tb_reset_flag;
atomic_t di_tb_skip_flag;
atomic_t di_tb_run_flag;
struct dim_tb_buf_s di_detect_buf[DIM_TB_BUFFER_MAX_SIZE];
struct dim_tb_buf_s di_detect_wbuf[DIM_TB_BUFFER_MAX_SIZE];
unsigned int nr_dump_count;
int di_init;
unsigned char flg_from;
};
//static struct tb_core_s dim_tbs[DI_CHANNEL_NUB];
static struct tb_core_s *dim_tbs[DI_CHANNEL_NUB];
//struct tb_core_s *get_dim_tb(void)
//{
// return dim_tbs;
//}
static DEFINE_MUTEX(di_tb_mutex);
static s32 di_tb_canvas = -1;
static struct TB_DetectFuncPtr *digfunc;
static struct tbff_stats *di_tb_reg[DI_CHANNEL_NUB];
//static u32 di_tb_src_canvas;
#endif
#define NR_DETECT_DUMP_CNT 150
#ifdef DIM_TB_DETECT
static int diwrite_to_file(unsigned long dump_adr, int size, unsigned int ch)
{
#ifdef CONFIG_AMLOGIC_ENABLE_MEDIA_FILE
int ret = 0;
struct file *fp = NULL;
mm_segment_t old_fs;
bool bflg_vmap = false;
void *buff = NULL;
loff_t pos = 0;
int nwrite = 0;
int offset = 0;
char parm[64];
/* change to KERNEL_DS address limit */
old_fs = get_fs();
set_fs(KERNEL_DS);
//PR_ERR("11%s: open file ok\n", __func__);
/* open file to write */
//fp = filp_open("/storage/A2DC-E6BA/tb.yuv",
//O_WRONLY | O_CREAT | O_APPEND, 0777);
sprintf(parm, "/storage/A2DC-E6BA/tb%d.yuv", ch);
fp = filp_open(parm, O_WRONLY | O_CREAT | O_APPEND, 0777);
//sprintf(parm, "/storage/A2DC-E6BA/TEST4/yuv00%d", didump_tb_cont++);
//fp = filp_open(parm, O_WRONLY | O_CREAT, 0666);
//PR_ERR("22%s: open file ok\n", __func__);
if (IS_ERR_OR_NULL(fp)) {
PR_ERR("%s: open file error\n", __func__);
ret = -1;
goto exit;
}
buff = dim_vmap(dump_adr, size, &bflg_vmap);
//PR_ERR("%s:vmap:0x%x\n", __func__, (unsigned int *)buff);
pos = (unsigned long)offset;
//buff = codec_mm_vmap(dump_adr, size);
//PR_ERR("%s:vmap:0x%p\n", __func__, buff);
/* Write buf to file */
if (IS_ERR_OR_NULL(buff))
PR_ERR("%s: ioremap error.\n", __func__);
nwrite = vfs_write(fp, buff, size, &pos);
offset += nwrite;
vfs_fsync(fp, 0);
if (bflg_vmap)
dim_unmap_phyaddr(buff);
filp_close(fp, NULL);
//PR_ERR("33%s: open file ok\n", __func__);
exit:
set_fs(old_fs);
#endif
return 0; //ret;
}
int dim_tb_detect(struct vframe_tb_s *vf, int data1, unsigned int ch)
{
bool is_top;
const struct reg_acc *op = &di_pre_regset;
struct tb_core_s *pcfg;
struct di_dev_s *di_devp = get_dim_de_devp();
dbg_tb("%s :step 3 s\n", __func__);
pcfg = dim_tbs[ch];
if (!di_devp->tb_flag_int)
return -1;
if (unlikely(!vf))
return -1;
if (pcfg->di_tb_buff_wptr & 1)
is_top = false;
else
is_top = true;
if (data1 == 0) {
if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_BOTTOM) {
pcfg->di_detect_buf[0].paddr =
pcfg->di_detect_wbuf[1].paddr;
pcfg->di_detect_buf[1].paddr =
pcfg->di_detect_wbuf[0].paddr;
pcfg->di_detect_buf[2].paddr =
pcfg->di_detect_wbuf[3].paddr;
pcfg->di_detect_buf[3].paddr =
pcfg->di_detect_wbuf[2].paddr;
pcfg->di_detect_buf[4].paddr =
pcfg->di_detect_wbuf[5].paddr;
pcfg->di_detect_buf[5].paddr =
pcfg->di_detect_wbuf[4].paddr;
pcfg->di_detect_buf[6].paddr =
pcfg->di_detect_wbuf[7].paddr;
pcfg->di_detect_buf[7].paddr =
pcfg->di_detect_wbuf[6].paddr;
pcfg->cur_invert_a = 1;//dump
pcfg->cur_invert_b = 1;//revert
pcfg->cur_invert_c = 1;//normal
dbg_tb("%s:NR01A %x\n", __func__, data1);
} else {
pcfg->di_detect_buf[0].paddr =
pcfg->di_detect_wbuf[0].paddr;
pcfg->di_detect_buf[1].paddr =
pcfg->di_detect_wbuf[1].paddr;
pcfg->di_detect_buf[2].paddr =
pcfg->di_detect_wbuf[2].paddr;
pcfg->di_detect_buf[3].paddr =
pcfg->di_detect_wbuf[3].paddr;
pcfg->di_detect_buf[4].paddr =
pcfg->di_detect_wbuf[4].paddr;
pcfg->di_detect_buf[5].paddr =
pcfg->di_detect_wbuf[5].paddr;
pcfg->di_detect_buf[6].paddr =
pcfg->di_detect_wbuf[6].paddr;
pcfg->di_detect_buf[7].paddr =
pcfg->di_detect_wbuf[7].paddr;
pcfg->cur_invert_a = 0;
pcfg->cur_invert_b = 2;
pcfg->cur_invert_c = 2;
dbg_tb("%s:NR01B %x\n", __func__, data1);
}
}
if (pcfg->cur_invert && pcfg->cur_invert_b) {
if (pcfg->cur_invert_b == 1) {
pcfg->di_detect_buf[0].paddr =
pcfg->di_detect_wbuf[0].paddr;
pcfg->di_detect_buf[1].paddr =
pcfg->di_detect_wbuf[1].paddr;
pcfg->di_detect_buf[2].paddr =
pcfg->di_detect_wbuf[2].paddr;
pcfg->di_detect_buf[3].paddr =
pcfg->di_detect_wbuf[3].paddr;
pcfg->di_detect_buf[4].paddr =
pcfg->di_detect_wbuf[4].paddr;
pcfg->di_detect_buf[5].paddr =
pcfg->di_detect_wbuf[5].paddr;
pcfg->di_detect_buf[6].paddr =
pcfg->di_detect_wbuf[6].paddr;
pcfg->di_detect_buf[7].paddr =
pcfg->di_detect_wbuf[7].paddr;
pcfg->cur_invert_a = 0;
pcfg->cur_invert_c = 1;
dbg_tb("%s:NR01C %x\n", __func__, data1);
} else {
pcfg->di_detect_buf[0].paddr =
pcfg->di_detect_wbuf[1].paddr;
pcfg->di_detect_buf[1].paddr =
pcfg->di_detect_wbuf[0].paddr;
pcfg->di_detect_buf[2].paddr =
pcfg->di_detect_wbuf[3].paddr;
pcfg->di_detect_buf[3].paddr =
pcfg->di_detect_wbuf[2].paddr;
pcfg->di_detect_buf[4].paddr =
pcfg->di_detect_wbuf[5].paddr;
pcfg->di_detect_buf[5].paddr =
pcfg->di_detect_wbuf[4].paddr;
pcfg->di_detect_buf[6].paddr =
pcfg->di_detect_wbuf[7].paddr;
pcfg->di_detect_buf[7].paddr =
pcfg->di_detect_wbuf[6].paddr;
pcfg->cur_invert_a = 1;
pcfg->cur_invert_c = 2;
dbg_tb("%s:NR01D %x\n", __func__, data1);
}
pcfg->cur_invert_b = 0;
}
if (!pcfg->cur_invert && !pcfg->cur_invert_b && pcfg->cur_invert_c) {
if (pcfg->cur_invert_c == 1) {
pcfg->di_detect_buf[0].paddr =
pcfg->di_detect_wbuf[1].paddr;
pcfg->di_detect_buf[1].paddr =
pcfg->di_detect_wbuf[0].paddr;
pcfg->di_detect_buf[2].paddr =
pcfg->di_detect_wbuf[3].paddr;
pcfg->di_detect_buf[3].paddr =
pcfg->di_detect_wbuf[2].paddr;
pcfg->di_detect_buf[4].paddr =
pcfg->di_detect_wbuf[5].paddr;
pcfg->di_detect_buf[5].paddr =
pcfg->di_detect_wbuf[4].paddr;
pcfg->di_detect_buf[6].paddr =
pcfg->di_detect_wbuf[7].paddr;
pcfg->di_detect_buf[7].paddr =
pcfg->di_detect_wbuf[6].paddr;
pcfg->cur_invert_a = 1;
pcfg->cur_invert_b = 1;
dbg_tb("%s:NR01E %x\n", __func__, data1);
} else {
pcfg->di_detect_buf[0].paddr =
pcfg->di_detect_wbuf[0].paddr;
pcfg->di_detect_buf[1].paddr =
pcfg->di_detect_wbuf[1].paddr;
pcfg->di_detect_buf[2].paddr =
pcfg->di_detect_wbuf[2].paddr;
pcfg->di_detect_buf[3].paddr =
pcfg->di_detect_wbuf[3].paddr;
pcfg->di_detect_buf[4].paddr =
pcfg->di_detect_wbuf[4].paddr;
pcfg->di_detect_buf[5].paddr =
pcfg->di_detect_wbuf[5].paddr;
pcfg->di_detect_buf[6].paddr =
pcfg->di_detect_wbuf[6].paddr;
pcfg->di_detect_buf[7].paddr =
pcfg->di_detect_wbuf[7].paddr;
pcfg->cur_invert_a = 0;
pcfg->cur_invert_b = 2;
dbg_tb("%s:NR01F %x\n", __func__, data1);
}
pcfg->cur_invert_c = 0;
}
canvas_config(di_tb_canvas,
pcfg->di_detect_buf[pcfg->di_tb_buff_wptr].paddr,
DIM_TB_DETECT_W, DIM_TB_DETECT_H,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
op->bwr(NRDSWR_CTRL, di_tb_canvas, 0, 8);
if (DIM_IS_IC_EF(T7))
di_mif1_linear_wr_cfgds
(pcfg->di_detect_buf[pcfg->di_tb_buff_wptr].paddr,
NRDSWR_STRIDE, NRDSWR_BADDR);
//dim_nr_ds_hw_ctrl(true);
dbg_tb("%s:e:ch[%d]dump %x frames start\n", __func__, ch,
pcfg->di_tb_buff_wptr);
return 1;
}
void dim_ds_detect(struct vframe_tb_s *vf, int data1, unsigned int ch)
{
struct di_dev_s *di_devp = get_dim_de_devp();
struct tb_core_s *pcfg;
struct di_ch_s *pch;
int ret = 0;
pch = get_chdata(ch);
if (!di_devp->tb_flag_int)
return;
if (!pch->en_tb) {
//dim_nr_ds_hw_ctrl(false);
return;
}
dbg_tb("%s :step 2 s\n", __func__);
pcfg = dim_tbs[ch];
if (vf->source_type !=
VFRAME_SOURCE_TYPE_OTHERS)
return;
if ((vf->width * vf->height)
> (1920 * 1088)) {
// greater than (1920 * 1088), do not detect
return;
}
if (pcfg->di_tb_buff_wptr < pcfg->di_tb_buffer_len) {
ret = dim_tb_detect(vf, data1, ch);
dbg_tb("%s:TB tb detect00,data1=%X\n", __func__, data1);
} else {
dbg_tb("%s :TB tb detect skip case2\n", __func__);
atomic_set(&pcfg->di_tb_skip_flag, 1);
pcfg->skip_picture++;
}
if (ret > 0) {
pcfg->di_tb_buff_wptr++;
if (pcfg->di_tb_buff_wptr >= DIM_TB_ALGO_COUNT &&
(atomic_read(&pcfg->dim_detect_status)
== di_tb_idle)) {
atomic_set
(&pcfg->dim_detect_status,
di_tb_running);
dbg_tb("%s:TB tb detect01=%d\n", __func__,
pcfg->di_tb_buff_wptr);
}
if (pcfg->di_tb_buff_wptr >= DIM_TB_ALGO_COUNT) {
atomic_set(&pcfg->di_tb_sem, 1);
dbg_tb("%s:TB tb detect02=%d\n", __func__,
pcfg->di_tb_buff_wptr);
}
}
}
void dim_tb_function(struct vframe_tb_s *vf, int data1, unsigned int ch)
{
int ret = 0;
struct di_dev_s *di_devp = get_dim_de_devp();
struct tb_core_s *pcfg;
struct di_ch_s *pch;
//const struct reg_acc *op = &di_pre_regset;
pch = get_chdata(ch);
if (!di_devp->tb_flag_int)
return;
if (!pch->en_tb) {
//dim_nr_ds_hw_ctrl(false);
return;
}
//dbg_tb("%s :s\n", __func__);
pcfg = dim_tbs[ch];
if (vf->source_type !=
VFRAME_SOURCE_TYPE_OTHERS)
goto SKIP_DETECT;
if ((vf->width * vf->height)
> (1920 * 1088)) {
// greater than (1920 * 1088), do not detect
goto SKIP_DETECT;
}
dbg_tb("%s:step 1 ch[%d]type=%x,cur_invert=%x,%x,%x,%x\n", __func__,
ch, vf->type, pcfg->cur_invert, vf->width, vf->height, data1);
//op->bwr(NR_DS_CTRL, vf->width / NR_DS_WIDTH, 16, 6);
//op->bwr(NR_DS_CTRL, vf->height / 2 / NR_DS_HEIGHT, 24, 6);
//if (data1 == 0)
//pcfg->first_frame = 1;
if (pcfg->first_frame) {
pcfg->last_type = vf->type & VIDTYPE_TYPEMASK;
pcfg->last_width = vf->width;
pcfg->last_height = vf->height;
pcfg->first_frame_type = pcfg->last_type;
pcfg->di_tb_first_frame_type = pcfg->last_type;
pcfg->first_frame = 0;
pcfg->reset_tb = 0;
pcfg->skip_picture = 0;
pcfg->cur_invert = 0;
pcfg->init_mute = pcfg->di_tb_init_mute;
atomic_set(&pcfg->di_tb_skip_flag, 1);
atomic_set(&pcfg->di_tb_reset_flag, 0);
dbg_tb("%s:first f type:%x,first_frame_type %X\n", __func__,
pcfg->last_type, pcfg->first_frame_type);
} else if ((pcfg->last_type ==
(vf->type & VIDTYPE_TYPEMASK)) && pcfg->last_type) {
/* interlace seq changed */
pcfg->first_frame_type =
vf->type & VIDTYPE_TYPEMASK;
pcfg->di_tb_first_frame_type =
pcfg->first_frame_type;
pcfg->reset_tb = 1;
data1 = 0;
/* keep old invert */
dbg_tb("%s:DI:TB interlace seq chg,old:%d,new:%d,invert: %d\n",
__func__,
pcfg->last_type,
pcfg->first_frame_type,
pcfg->cur_invert);
} else if ((pcfg->last_type == 0) &&
((vf->type & VIDTYPE_TYPEMASK) != 0)) {
/* prog -> interlace changed */
pcfg->first_frame_type =
vf->type & VIDTYPE_TYPEMASK;
pcfg->di_tb_first_frame_type =
pcfg->first_frame_type;
pcfg->reset_tb = 1;
dbg_tb("%s:TB prog -> interlace, new type: %d, invert: %d\n",
__func__, pcfg->first_frame_type, pcfg->cur_invert);
/* not invert */
pcfg->cur_invert = 0;
} else if (((pcfg->last_width != vf->width) ||
(pcfg->last_height != vf->height)) &&
((vf->type & VIDTYPE_TYPEMASK) != 0)) {
/* size changed and next seq is interlace */
pcfg->first_frame_type =
vf->type & VIDTYPE_TYPEMASK;
pcfg->di_tb_first_frame_type =
pcfg->first_frame_type;
pcfg->reset_tb = 1;
/* keep old invert */
dbg_tb("%s:TB tb size change new type: %d, invert: %d\n",
__func__, pcfg->first_frame_type, pcfg->cur_invert);
} else if ((pcfg->last_type != 0) &&
((vf->type & VIDTYPE_TYPEMASK) == 0)) {
/* interlace -> prog changed */
dbg_tb("%s:TB tb interlace -> prog, invert: %d\n",
__func__, pcfg->cur_invert);
/* not invert */
pcfg->cur_invert = 0;
}
pcfg->last_type = vf->type & VIDTYPE_TYPEMASK;
pcfg->last_width = vf->width;
pcfg->last_height = vf->height;
dbg_tb("%s:S frame type: %x,first_frame_type %X,cur_invert=%x\n", __func__,
pcfg->last_type, pcfg->first_frame_type, pcfg->cur_invert);
if (di_devp->tb_flag_int) {
ret = 0;
if (pcfg->di_tb_buffer_status <= 0)
goto SKIP_DETECT;
di_devp->tb_detect_buf_len = pcfg->di_tb_buffer_len;
vf->type = (vf->type & ~TB_DETECT_MASK);
if (pcfg->init_mute > 0) {
pcfg->init_mute--;
atomic_set(&pcfg->di_tb_skip_flag, 1);
goto SKIP_DETECT;
}
if (pcfg->last_type == 0) {/* cur type is prog */
pcfg->skip_picture++;
pcfg->cur_invert = 0;
goto SKIP_DETECT;
}
vf->type |=
pcfg->cur_invert <<
TB_DETECT_MASK_BIT;
dbg_tb("%s: M first f type:%x,first_frame_type %X\n", __func__,
pcfg->last_type, pcfg->first_frame_type);
if (pcfg->reset_tb) {
/* wait tb task done */
while ((pcfg->di_tb_buff_wptr >= DIM_TB_ALGO_COUNT) &&
(pcfg->di_tb_buff_rptr <=
pcfg->di_tb_buff_wptr - DIM_TB_ALGO_COUNT) &&
(atomic_read(&pcfg->di_tb_run_flag) == 1))
usleep_range(100, 200);
//usleep_range(4000, 5000);
atomic_set(&pcfg->dim_detect_status, di_tb_idle);
pcfg->di_tb_buff_wptr = 0;
pcfg->di_tb_buff_rptr = 0;
atomic_set(&pcfg->dim_tb_detect_flag, TB_DETECT_NC);
atomic_set(&pcfg->di_tb_reset_flag, 1);
atomic_set(&pcfg->di_tb_skip_flag, 1);
pcfg->skip_picture = 0;
pcfg->reset_tb = 0;
dbg_tb("%s reset once\n", __func__);
}
if ((atomic_read(&pcfg->dim_detect_status) == di_tb_done) &&
pcfg->skip_picture >=
di_devp->tb_detect_period &&
pcfg->last_type == pcfg->first_frame_type) {
int tbf_flag =
atomic_read(&pcfg->dim_tb_detect_flag);
u8 old_invert = pcfg->cur_invert;
atomic_set(&pcfg->dim_detect_status, di_tb_idle);
pcfg->di_tb_buff_wptr = 0;
pcfg->di_tb_buff_rptr = 0;
pcfg->skip_picture = 0;
if (tbf_flag == TB_DETECT_TBF &&
pcfg->first_frame_type == VIDTYPE_INTERLACE_TOP) {
/* TBF sams as BFF */
vf->type |=
TB_DETECT_INVERT
<< TB_DETECT_MASK_BIT;
pcfg->cur_invert = 1;
} else if ((tbf_flag == TB_DETECT_BFF) &&
(pcfg->first_frame_type ==
VIDTYPE_INTERLACE_TOP)) {
vf->type |=
TB_DETECT_INVERT
<< TB_DETECT_MASK_BIT;
pcfg->cur_invert = 1;
} else if ((tbf_flag == TB_DETECT_TFF) &&
(pcfg->first_frame_type ==
VIDTYPE_INTERLACE_BOTTOM)) {
vf->type |=
TB_DETECT_INVERT
<< TB_DETECT_MASK_BIT;
pcfg->cur_invert = 1;
} else if (tbf_flag != TB_DETECT_NC) {
pcfg->cur_invert = 0;
}
vf->type = (vf->type & ~TB_DETECT_MASK);
vf->type |=
pcfg->cur_invert <<
TB_DETECT_MASK_BIT;
dbg_tb("%s process mask:vf[0x%x] type=0x%x\n",
__func__, vf->omx_index, vf->type);
if (old_invert != pcfg->cur_invert)
dbg_tb
("%s:flag00: %d->%d, invert: %d->%d\n",
__func__,
pcfg->dim_tb_detect_last_flag,
tbf_flag,
old_invert,
pcfg->cur_invert);
else if (pcfg->dim_tb_detect_last_flag != tbf_flag)
dbg_tb
("%s:flag01: %d->%d, invert: %d\n",
__func__,
pcfg->dim_tb_detect_last_flag,
tbf_flag,
pcfg->cur_invert);
pcfg->dim_tb_detect_last_flag = tbf_flag;
atomic_set(&pcfg->dim_tb_detect_flag, TB_DETECT_NC);
}
if (pcfg->di_tb_buff_wptr == 0 &&
pcfg->last_type != pcfg->first_frame_type) {
pcfg->skip_picture++;
atomic_set(&pcfg->di_tb_skip_flag, 1);
dbg_tb("%s:TB tb detect skip case1\n", __func__);
goto SKIP_DETECT;
}
} else {
pcfg->reset_tb = 1;
pcfg->skip_picture++;
pcfg->cur_invert = 0;
if (pcfg->init_mute > 0)
pcfg->init_mute--;
dbg_tb("%s :step 1 else\n", __func__);
}
dbg_tb("%s :step 1 e\n", __func__);
SKIP_DETECT:
if (pcfg->skip_picture >
di_devp->tb_detect_period) {
pcfg->skip_picture =
di_devp->tb_detect_period;
dbg_tb("%s :skip\n", __func__);
}
}
int dim_tb_buffer_init(unsigned int ch)
{
int i;
//int flags = CODEC_MM_FLAGS_DMA_CPU | CODEC_MM_FLAGS_CMA_CLEAR;
//int flags = 0;
struct di_dev_s *di_devp = get_dim_de_devp();
struct tb_core_s *pcfg;
struct dim_mm_s omm;
//struct div2_mm_s *mm;
bool ret;
struct di_ch_s *pch;
PR_INF("%s :s\n", __func__);
if (!di_devp->tb_flag_int)
return -1;
pch = get_chdata(ch);
if (!pch->en_tb)
return -1;
pcfg = dim_tbs[ch];
di_tb_reg[ch] = kmalloc(sizeof(*di_tb_reg[ch]), GFP_KERNEL);
if (!di_tb_reg[ch])
return -1;
memset(di_tb_reg[ch], 0, sizeof(struct tbff_stats));
if (pcfg->di_tb_buffer_status)
return pcfg->di_tb_buffer_status;
if (di_tb_canvas < 0)
di_tb_canvas =
canvas_pool_map_alloc_canvas("tb_detect_dst");
if (di_tb_canvas < 0)
return -1;
if (pcfg->di_tb_buffer_start == 0 && pch->en_tb) {
if (!di_devp->tb_detect_buf_len)
di_devp->tb_detect_buf_len = 8;
pcfg->di_tb_buffer_len = di_devp->tb_detect_buf_len;
pcfg->di_tb_buffer_size = DIM_TB_DETECT_H * DIM_TB_DETECT_W
* pcfg->di_tb_buffer_len;
pcfg->di_tb_buffer_size = PAGE_ALIGN(pcfg->di_tb_buffer_size);
ret = mm_cma_alloc(NULL,
pcfg->di_tb_buffer_size >> PAGE_SHIFT,
&omm);
pcfg->flg_from = 1;
if (!ret) {
pcfg->flg_from = 2;
ret = mm_cma_alloc(&di_devp->pdev->dev,
pcfg->di_tb_buffer_size >> PAGE_SHIFT,
&omm);
if (!ret) {
PR_ERR("%s:cma\n", __func__);
pcfg->flg_from = 0;
return -1;
}
}
pcfg->di_tb_buffer_start = omm.addr;
pcfg->virt = omm.ppage;
dbg_tb("%s:ch[%d] %x, size %x, item %d\n", __func__, ch,
(unsigned int)pcfg->di_tb_buffer_start,
(unsigned int)pcfg->di_tb_buffer_size,
pcfg->di_tb_buffer_len);
if (pcfg->di_tb_buffer_start == 0) {
PR_ERR("di:err:DI:TB cma memory config fail\n");
pcfg->di_tb_buffer_status = -1;
return -1;
}
for (i = 0; i < pcfg->di_tb_buffer_len; i++) {
pcfg->di_detect_buf[i].paddr =
pcfg->di_tb_buffer_start +
DIM_TB_DETECT_H * DIM_TB_DETECT_W * i;
pcfg->di_detect_buf[i].vaddr =
(ulong)codec_mm_vmap
(pcfg->di_detect_buf[i].paddr,
DIM_TB_DETECT_H * DIM_TB_DETECT_W);
pcfg->di_detect_wbuf[i].paddr =
pcfg->di_detect_buf[i].paddr;
dbg_tb("%s:TBbuf(%d)paddr:%lx,vaddr: %lx,vaddr: %lx\n",
__func__, i, pcfg->di_detect_buf[i].paddr,
pcfg->di_detect_buf[i].vaddr,
pcfg->di_detect_wbuf[i].paddr);
}
}
pcfg->di_tb_buffer_status = 1;
dbg_tb("%s :e\n", __func__);
return 1;
}
int dim_tb_buffer_uninit(unsigned int ch)
{
int i;
struct tb_core_s *pcfg;
struct di_dev_s *di_devp = get_dim_de_devp();
struct di_ch_s *pch;
dbg_tb("%s :s\n", __func__);
pch = get_chdata(ch);
pcfg = dim_tbs[ch];
if (!di_devp->tb_flag_int)
return 0;
if (!pch->en_tb)
return 0;
if (pcfg->di_tb_buffer_status <= 0)
return 0;
if (di_tb_canvas >= 0)
canvas_pool_map_free_canvas(di_tb_canvas);
di_tb_canvas = -1;
if (pcfg->di_tb_buffer_start) {
dbg_tb("%s:ch[%d] free addr is %x, size is %x\n", __func__, ch,
(unsigned int)pcfg->di_tb_buffer_start,
(unsigned int)pcfg->di_tb_buffer_size);
for (i = 0; i < pcfg->di_tb_buffer_len; i++) {
if (pcfg->di_detect_buf[i].vaddr) {
codec_mm_unmap_phyaddr
((u8 *)pcfg->di_detect_buf[i].vaddr);
pcfg->di_detect_buf[i].vaddr = 0;
}
}
if (pcfg->flg_from == 2)
dma_release_from_contiguous
(&di_devp->pdev->dev,
(struct page *)pcfg->virt,
pcfg->di_tb_buffer_size >> PAGE_SHIFT);
else
dma_release_from_contiguous
(NULL,
(struct page *)pcfg->virt,
pcfg->di_tb_buffer_size >> PAGE_SHIFT);
pcfg->di_tb_buffer_start = 0;
pcfg->di_tb_buffer_size = 0;
pcfg->virt = NULL;
}
pcfg->di_tb_buffer_status = 0;
kfree(di_tb_reg[ch]);
di_tb_reg[ch] = NULL;
//di_devp->tb_detect = 0x8;
dbg_tb("%s :e\n", __func__);
return 0;
}
void dim_tb_reg_init(struct vframe_tb_s *vfm, unsigned int on, unsigned int ch)
{
int val = 0;
struct di_dev_s *di_devp = get_dim_de_devp();
struct tb_core_s *pcfg;
struct di_ch_s *pch;
dbg_tb("%s :s\n", __func__);
pch = get_chdata(ch);
if (vfm->source_type !=
VFRAME_SOURCE_TYPE_OTHERS)
return;
if ((vfm->width * vfm->height) > (1920 * 1088))
return;
if (!di_devp->tb_flag_int)
return;
if (!pch->en_tb)
return;
if (!(vfm->type & VIDTYPE_TYPEMASK))
return;
pcfg = dim_tbs[ch];
if (on) {
atomic_set(&pcfg->di_tb_sem, val);
memset(pcfg->di_detect_buf, 0, sizeof(pcfg->di_detect_buf));
memset(pcfg->di_detect_wbuf, 0, sizeof(pcfg->di_detect_wbuf));
atomic_set(&pcfg->dim_detect_status, di_tb_idle);
atomic_set(&pcfg->dim_tb_detect_flag, TB_DETECT_NC);
atomic_set(&pcfg->di_tb_reset_flag, 0);
atomic_set(&pcfg->di_tb_skip_flag, 0);
atomic_set(&pcfg->di_tb_run_flag, 1);
//di_devp->tb_detect = 0x8;
di_devp->tb_detect_period = 0;
di_devp->tb_detect_buf_len = 8;
di_devp->tb_detect_init_mute = 0;
pcfg->dim_tb_detect_last_flag = TB_DETECT_NC;
pcfg->di_tb_buff_wptr = 0;
pcfg->di_tb_buff_rptr = 0;
pcfg->di_tb_buffer_status = 0;
pcfg->di_tb_buffer_start = 0;
pcfg->di_tb_buffer_size = 0;
pcfg->di_tb_first_frame_type = 0;
pcfg->di_tb_quit_flag = 0;
pcfg->di_tb_init_mute = di_devp->tb_detect_init_mute;
pcfg->cur_invert_b = 0;
pcfg->cur_invert_a = 0;
pcfg->first_frame = 1;
pcfg->di_tb_buffer_len = DIM_TB_BUFFER_MAX_SIZE;
pcfg->nr_dump_en = 0;
pcfg->nr_dump_count = 0;
pcfg->skip_picture = 0;
pcfg->cur_invert = 0;
dbg_tb("%s :ch[%d] TB init\n", __func__, ch);
}
dbg_tb("%s :e\n", __func__);
}
bool dim_tb_t_try_alloc(struct di_ch_s *pch)
{
if (pch->tb_busy)
return false;
pch->tb_busy = true;
pch->tb_owner = pch->ch_id;
dbg_tb("%s :a:ch[%d]:alloc:ok\n", __func__, pch->ch_id);
return true;
}
void dim_tb_polling_active(struct di_ch_s *pch)
{
if (pch->en_tb_buf && pch->en_tb) {
if (dim_tb_t_try_alloc(pch))
pch->en_tb = true;
}
}
void dim_tb_t_release(struct di_ch_s *pch)
{
struct di_dev_s *di_devp = get_dim_de_devp();
dbg_tb("%s :s\n", __func__);
if (!di_devp->tb_flag_int)
return;
if (!pch->en_tb)
return;
if (pch->en_tb) {
if (pch->ch_id == pch->tb_owner) {
pch->tb_owner = 0xff;
pch->tb_busy = false;
} else {
PR_ERR("%s:%d->%d\n",
__func__, pch->ch_id, pch->tb_owner);
}
pch->en_tb = false;
}
if (pch->en_tb_buf) {
get_datal()->tb_src_cnt--;
pch->en_tb_buf = false;
}
kfree(dim_tbs[pch->ch_id]);
dbg_tb("%s :e:r:ch[%d]:cnt[%d]\n", __func__,
pch->ch_id,
get_datal()->tb_src_cnt);
}
void dim_tb_alloc(struct vframe_tb_s *vf, struct di_ch_s *pch)
{
unsigned char tb_cnt, tb_nub;
struct di_dev_s *di_devp = get_dim_de_devp();
dbg_tb("%s 0:s = %d\n", __func__, pch->ch_id);
if (!di_devp->tb_flag_int)
return;
pch->en_tb = false;
pch->en_tb_buf = false;
if (vf->source_type !=
VFRAME_SOURCE_TYPE_OTHERS)
return;
if ((vf->width * vf->height) > (1920 * 1088))
return;
if (!(vf->type & VIDTYPE_TYPEMASK))
return;
tb_nub = cfgg(TB);
if (!tb_nub)
return;
tb_cnt = get_datal()->tb_src_cnt;
tb_cnt++;
if (tb_cnt > tb_nub)
return;
if (!dim_tb_t_try_alloc(pch))
return;
pch->en_tb = true;
pch->en_tb_buf = true;
get_datal()->tb_src_cnt = tb_cnt;
dbg_tb("%s s = %d\n", __func__, get_datal()->tb_src_cnt);
dim_tbs[pch->ch_id] = kmalloc(sizeof(*dim_tbs[pch->ch_id]), GFP_KERNEL);
if (!dim_tbs[pch->ch_id])
return;
//memset(dim_tbs[pch->ch_id], 0, sizeof(struct tb_core_s));
dbg_tb("%s :e:ch[%d]:cnt[%d]\n", __func__,
pch->ch_id,
get_datal()->tb_src_cnt);
}
int dim_tb_task_process(struct vframe_tb_s *vf, u32 data, unsigned int ch)
{
int tbff_flag = 0;
ulong y5fld[5] = {0};
int is_top = 0;
int i;
int di_inter_flag = 0;
struct di_dev_s *di_devp = get_dim_de_devp();
static const char * const detect_type[] = {"NC", "TFF", "BFF", "TBF"};
struct tb_core_s *pcfg;
struct di_ch_s *pch;
dbg_tb("%s :step 4 s\n", __func__);
if (!di_devp->tb_flag_int)
return 1;
if (vf->source_type !=
VFRAME_SOURCE_TYPE_OTHERS)
return 1;
if ((vf->width * vf->height) > (1920 * 1088))
return 1;
pch = get_chdata(ch);
if (!pch->en_tb)
return 1;
if (digfunc)
digfunc->stats_init(di_tb_reg[ch],
DIM_TB_DETECT_H, DIM_TB_DETECT_W);
pcfg = dim_tbs[ch];
if (atomic_read(&pcfg->di_tb_sem) != 0) {
if (pcfg->di_tb_quit_flag)
return 1;
if (pcfg->di_tb_buff_rptr == 0) {
if (atomic_read(&pcfg->di_tb_reset_flag) != 0)
pcfg->di_init = 0;
atomic_set(&pcfg->di_tb_reset_flag, 0);
if (digfunc)
digfunc->fwalg_init(pcfg->di_init, ch);
}
pcfg->di_init = 1;
is_top = (pcfg->di_tb_buff_rptr & 1) ? 0 : 1;
if (pcfg->di_tb_buff_rptr == 0) {
codec_mm_dma_flush
((void *)pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 5].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
codec_mm_dma_flush
((void *)pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 4].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
codec_mm_dma_flush
((void *)pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 3].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
codec_mm_dma_flush
((void *)pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 2].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
codec_mm_dma_flush
((void *)pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 1].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
codec_mm_dma_flush
((void *)pcfg->di_detect_buf[pcfg->di_tb_buff_rptr].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
if (data >= dimp_get(edi_mp_tb_dump) &&
dimp_get(edi_mp_tb_dump)) {
pcfg->nr_dump_en = 1;
if (pcfg->cur_invert_a == 1) {
dim_dump_tb(1, ch);
dim_dump_tb(0, ch);
dim_dump_tb(3, ch);
dim_dump_tb(2, ch);
} else {
dim_dump_tb(0, ch);
dim_dump_tb(1, ch);
dim_dump_tb(2, ch);
dim_dump_tb(3, ch);
}
}
} else if (pcfg->di_tb_buff_rptr == 1) {
codec_mm_dma_flush((void *)pcfg->di_detect_buf[6].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
if (pcfg->nr_dump_en) {
if (pcfg->cur_invert_a == 1) {
dim_dump_tb(5, ch);
dim_dump_tb(4, ch);
} else {
dim_dump_tb(4, ch);
dim_dump_tb(5, ch);
}
}
} else if (pcfg->di_tb_buff_rptr == 2) {
codec_mm_dma_flush((void *)pcfg->di_detect_buf[7].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
if (pcfg->nr_dump_en) {
if (pcfg->cur_invert_a == 1) {
dim_dump_tb(7, ch);
dim_dump_tb(6, ch);
} else {
dim_dump_tb(6, ch);
dim_dump_tb(7, ch);
}
}
} else if (pcfg->di_tb_buff_rptr == 3) {
codec_mm_dma_flush((void *)pcfg->di_detect_buf[7].vaddr,
DIM_TB_DETECT_W * DIM_TB_DETECT_H,
DMA_FROM_DEVICE);
if (pcfg->nr_dump_en) {
dim_dump_tb(6, ch);
dim_dump_tb(7, ch);
}
}
/* new -> old */
y5fld[0] = pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 4].vaddr;
y5fld[1] = pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 3].vaddr;
y5fld[2] = pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 2].vaddr;
y5fld[3] = pcfg->di_detect_buf[pcfg->di_tb_buff_rptr + 1].vaddr;
y5fld[4] = pcfg->di_detect_buf[pcfg->di_tb_buff_rptr].vaddr;
if (digfunc) {
if (IS_ERR_OR_NULL(di_tb_reg[ch])) {
kfree(di_tb_reg[ch]);
PR_ERR("di:err:DI:TB di_tb_reg is NULL!\n");
return 1;
}
for (i = 0; i < 5; i++) {
if (IS_ERR_OR_NULL((void *)y5fld[i])) {
PR_ERR("di:err:DI:TB y5fld[%d]isNULL\n",
i);
di_inter_flag = 1;
break;
}
}
if (di_inter_flag) {
di_inter_flag = 0;
return 1;
}
digfunc->stats_get(y5fld, di_tb_reg[ch]);
}
is_top = is_top ^ 1;
tbff_flag = -1;
if (digfunc)
tbff_flag = digfunc->fwalg_get(di_tb_reg[ch], is_top,
(pcfg->di_tb_first_frame_type == 3) ? 0 : 1,
pcfg->di_tb_buff_rptr,
atomic_read(&pcfg->di_tb_skip_flag),
(dimp_get(edi_mp_nrds_en)) ? 1 : 0, ch);
dbg_tb("%s TB=%x,=%x,=%x,=%x,=%x,data=%x,ch=%x\n", __func__,
is_top,
pcfg->di_tb_first_frame_type, pcfg->di_tb_buff_rptr,
atomic_read(&pcfg->di_tb_skip_flag),
tbff_flag, data, ch);
if (pcfg->di_tb_buff_rptr == 0)
atomic_set(&pcfg->di_tb_skip_flag, 0);
if ((tbff_flag < -1) || tbff_flag > 2) {
PR_ERR("di:err:DI:TB get tb detect flag error: %d\n",
tbff_flag);
}
if ((tbff_flag == -1) && (digfunc))
tbff_flag =
digfunc->majority_get(ch);
if (tbff_flag == -1)
tbff_flag =
TB_DETECT_NC;
else if (tbff_flag == 0)
tbff_flag =
TB_DETECT_TFF;
else if (tbff_flag == 1)
tbff_flag =
TB_DETECT_BFF;
else if (tbff_flag == 2)
tbff_flag =
TB_DETECT_TBF;
else
tbff_flag =
TB_DETECT_NC;
//tbff_flag =
//TB_DETECT_NC;//mark for dis di tb
pcfg->di_tb_buff_rptr++;
dbg_tb("%s:task %d,%d\n", __func__,
pcfg->di_tb_buff_rptr, pcfg->di_tb_buffer_len);
if ((pcfg->di_tb_buff_rptr >
pcfg->di_tb_buffer_len - DIM_TB_ALGO_COUNT) &&
(atomic_read(&pcfg->dim_detect_status) == di_tb_running)) {
atomic_set(&pcfg->dim_tb_detect_flag, tbff_flag);
dbg_tb("%s:TB get tb detect final flag: %s\n",
__func__, detect_type[tbff_flag]);
atomic_set(&pcfg->dim_detect_status, di_tb_done);
}
atomic_set(&pcfg->di_tb_sem, 0);
}
atomic_set(&pcfg->di_tb_run_flag, 0);
dbg_tb("%s :e\n", __func__);
return 0;
}
void dim_tb_ext_cmd(struct vframe_s *vf, int data1, unsigned int ch,
unsigned int cmd)
{
struct tb_task_cmd_s tb_blk_cmd;
struct vframe_tb_s cfg_data;
struct vframe_tb_s *cfg = &cfg_data;
memset(cfg, 0, sizeof(struct vframe_tb_s));
if (!IS_ERR_OR_NULL(vf)) {
cfg->height = vf->height;
cfg->width = vf->width;
cfg->source_type = vf->source_type;
cfg->type = vf->type;
}
dbg_tb("%s :S\n", __func__);
if (cmd == ECMD_TB_REG)
dim_tb_alloc(cfg, get_chdata(ch));
tb_blk_cmd.cmd = cmd;
tb_blk_cmd.field_count = data1;
tb_blk_cmd.ch = ch;
tb_blk_cmd.in_buf_vf = vf;
tb_task_alloc_block(ch, &tb_blk_cmd);
if (cmd == ECMD_TB_PROC)
dim_ds_detect(cfg, data1, ch);
}
#endif
#ifdef DIM_TB_DETECT
int RegisterTB_Function(struct TB_DetectFuncPtr *func, const char *ver)
{
int ret = -1;
mutex_lock(&di_tb_mutex);
pr_info("DI:TB RegDITB digfunc %p, func: %p, ver:%s\n", digfunc,
func, ver);
if (!digfunc && func) {
digfunc = func;
ret = 0;
}
mutex_unlock(&di_tb_mutex);
return ret;
}
EXPORT_SYMBOL(RegisterTB_Function);
int UnRegisterTB_Function(struct TB_DetectFuncPtr *func)
{
int ret = -1;
mutex_lock(&di_tb_mutex);
pr_info("DI:TB UnRegDITB: digfunc %p, func: %p\n", digfunc, func);
if (func && func == digfunc) {
digfunc = NULL;
ret = 0;
}
mutex_unlock(&di_tb_mutex);
return ret;
}
EXPORT_SYMBOL(UnRegisterTB_Function);
void dim_nr_ds_hw_init(unsigned int width, unsigned int height, unsigned int ch)
{
unsigned char h_step = 0, v_step = 0;
unsigned int width_out, height_out;
const struct reg_acc *op = &di_pre_regset;
struct di_dev_s *di_devp = get_dim_de_devp();
struct di_ch_s *pch;
dbg_tb("%s :s\n", __func__);
if (!di_devp->tb_flag_int)
return;
pch = get_chdata(ch);
if (!pch->en_tb)
return;
width_out = NR_DS_WIDTH;
height_out = NR_DS_HEIGHT;
h_step = width / width_out;
v_step = height / height_out;
/*Switch MIF to NR_DS*/
op->bwr(VIUB_MISC_CTRL0, 3, 5, 2);
/* config dsbuf_ocol*/
op->bwr(NR_DS_BUF_SIZE_REG, width_out, 0, 8);
/* config dsbuf_orow*/
op->bwr(NR_DS_BUF_SIZE_REG, height_out, 8, 8);
op->bwr(NRDSWR_X, (width_out - 1), 0, 13);
op->bwr(NRDSWR_Y, (height_out - 1), 0, 13);
op->bwr(NRDSWR_CAN_SIZE, (height_out - 1), 0, 13);
op->bwr(NRDSWR_CAN_SIZE, (width_out - 1), 16, 13);
/* little endian */
op->bwr(NRDSWR_CAN_SIZE, 1, 13, 1);
op->bwr(NR_DS_CTRL, v_step, 16, 6);
op->bwr(NR_DS_CTRL, h_step, 24, 6);
op->bwr(NR_DS_CTRL, (dimp_get(edi_mp_blend_mode) >> 24) & 0xf, 12, 3);
op->bwr(NR_DS_CTRL, (dimp_get(edi_mp_blend_mode) >> 24) & 0xf, 8, 3);
//op->bwr(NR_DS_CTRL, 2, 8, 3);
op->bwr(NR_DS_BLD_COEF, (dimp_get(edi_mp_blend_mode) >> 16) & 0xff,
16, 8);
op->bwr(NR_DS_BLD_COEF, (dimp_get(edi_mp_blend_mode) >> 8) & 0xff,
8, 8);
op->bwr(NR_DS_BLD_COEF, dimp_get(edi_mp_blend_mode) & 0xff, 0, 8);
op->bwr(NR_DS_CTRL, (dimp_get(edi_mp_blend_mode) >> 28) & 0xf, 0, 1);
dbg_tb("%s:e:done\n", __func__);
}
void dim_dump_tb(unsigned int data, unsigned int ch)
{
struct tb_core_s *pcfg;
pcfg = dim_tbs[ch];
if (pcfg->nr_dump_en) {
if (pcfg->nr_dump_count < NR_DETECT_DUMP_CNT) {
diwrite_to_file(pcfg->di_detect_buf[data].paddr,
NR_DS_WIDTH * NR_DS_HEIGHT
* 1, ch);
dbg_tb("%s:dump NR1 %d %d done\n", __func__,
pcfg->nr_dump_count, data);
pcfg->nr_dump_count++;
} else {
dbg_tb("%s:dump done\n", __func__);
pcfg->nr_dump_en = 0;
}
}
}
/*
* 0x37f9 ~ 0x37fc 0x3740 ~ 0x3743 8 regs
*/
void dim_dump_nrds_reg(unsigned int base_addr)
{
unsigned int i = 0x37f9;
pr_info("-----nrds reg start-----\n");
pr_info("[0x%x][0x%x]=0x%x\n",
base_addr + (0x2006 << 2), i, DIM_RDMA_RD(0x2006));
for (i = 0x37f9; i < 0x37fd; i++)
pr_info("[0x%x][0x%x]=0x%x\n",
base_addr + (i << 2), i, DIM_RDMA_RD(i));
for (i = 0x3740; i < 0x3744; i++)
pr_info("[0x%x][0x%x]=0x%x\n",
base_addr + (i << 2), i, DIM_RDMA_RD(i));
pr_info("-----nrds reg end-----\n");
}
#endif
/*
* enable/disable nr ds mif&hw
*/
void dim_nr_ds_hw_ctrl(bool enable)
{
/*Switch MIF to NR_DS*/
const struct reg_acc *op = &di_pre_regset;
#ifdef DIM_TB_DETECT
struct di_dev_s *di_devp = get_dim_de_devp();
if (!di_devp->tb_flag_int)
enable = 0;
#endif
op->bwr(VIUB_MISC_CTRL0, enable ? 3 : 2, 5, 2);
op->bwr(NRDSWR_CTRL, enable ? 1 : 0, 12, 1);
op->bwr(NR_DS_CTRL, enable ? 1 : 0, 30, 1);
dbg_tb("%s TB %d\n", __func__, enable);
}
void dim_tb_prob(void)
{
#ifdef DIM_TB_DETECT
struct di_dev_s *di_devp = get_dim_de_devp();
if (IS_IC_SUPPORT(TB))
di_devp->tb_flag_int = 1;
else
di_devp->tb_flag_int = 0;
PR_INF("%s:end=%d\n", __func__, di_devp->tb_flag_int);
#endif
}