di: support the interlace format from vdin afbc [2/2]

PD#SWPL-5205

Problem:
support afbc from vdin and decoder on tl1

Solution:
1.add this function
2.support from vdin and decoder

Verify:
tl1

Change-Id: I258d40ad5706f4a9a5749298dd9a33a9b4bbafa2
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
This commit is contained in:
Yong Qin
2019-02-28 11:17:17 +08:00
committed by Jianxin Pan
parent a3fb1dc0b7
commit 3f4854e57d
6 changed files with 379 additions and 186 deletions

View File

@@ -129,7 +129,7 @@ static di_dev_t *de_devp;
static dev_t di_devno;
static struct class *di_clsp;
static const char version_s[] = "2019-02-27a";
static const char version_s[] = "2019-03-05a";
static int bypass_state = 1;
static int bypass_all;
@@ -272,6 +272,8 @@ static int di_receiver_event_fun(int type, void *data, void *arg);
static void di_uninit_buf(unsigned int disable_mirror);
static void log_buffer_state(unsigned char *tag);
/* static void put_get_disp_buf(void); */
static unsigned int isbypass_flag;
static unsigned int needbypass_flag;
static const
struct vframe_receiver_op_s di_vf_receiver = {
@@ -526,27 +528,57 @@ int get_di_dump_state_flag(void)
}
/*--------------------------*/
static void parse_param_di(char *buf_orig, char **parm)
{
char *ps, *token;
unsigned int n = 0;
char delim1[3] = " ";
char delim2[2] = "\n";
ps = buf_orig;
strcat(delim1, delim2);
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
}
static ssize_t
store_dbg(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
u32 val;
char *buf_orig, *parm[8] = {NULL};
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_di(buf_orig, (char **)&parm);
if (strncmp(buf, "buf", 3) == 0) {
struct di_buf_s *di_buf_tmp = 0;
if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp))
if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp)) {
kfree(buf_orig);
return count;
}
dump_di_buf(di_buf_tmp);
} else if (strncmp(buf, "vframe", 6) == 0) {
vframe_t *vf = 0;
if (kstrtoul(buf + 6, 16, (unsigned long *)&vf))
if (kstrtoul(buf + 6, 16, (unsigned long *)&vf)) {
kfree(buf_orig);
return count;
}
dump_vframe(vf);
} else if (strncmp(buf, "pool", 4) == 0) {
unsigned long idx = 0;
if (kstrtoul(buf + 4, 10, &idx))
if (kstrtoul(buf + 4, 10, &idx)) {
kfree(buf_orig);
return count;
}
dump_pool(get_queue_by_idx(idx));
} else if (strncmp(buf, "state", 4) == 0) {
dump_state();
@@ -576,10 +608,13 @@ store_dbg(struct device *dev,
} else if (strncmp(buf, "pstep", 5) == 0) {
pre_run_flag = DI_RUN_FLAG_STEP;
} else if (strncmp(buf, "dumpreg", 7) == 0) {
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
dump_di_reg_g12();
else
dump_afbcd_reg();
} else
pr_info("add new debugfs: cat /sys/kernel/debug/di/dumpreg\n");
} else if (strncmp(buf, "dumpafbc", 8) == 0) {
dump_afbcd_reg();
} else if (strncmp(buf, "dumpmif", 7) == 0) {
dump_mif_size_state(&di_pre_stru, &di_post_stru);
} else if (strncmp(buf, "recycle_buf", 11) == 0) {
@@ -589,10 +624,37 @@ store_dbg(struct device *dev,
di_vf_put(di_vf_get(NULL), NULL);
} else if (strncmp(buf, "mem_map", 7) == 0) {
dump_buf_addr(di_buf_local, MAX_LOCAL_BUF_NUM * 2);
} else if (strncmp(buf, "afbc_on", 7) == 0) {
if (kstrtoint(parm[1], 10, &val) < 0) {
kfree(buf_orig);
return count;
}
if (!val)
afbc_sw(false);
afbc_disable_flag = val > 0 ? 0:1;
pr_info("afbc_disable_flag:%d\n", afbc_disable_flag);
} else {
pr_info("DI no support cmd %s!!!\n", buf);
pr_info("DI no support cmd %s\n", buf);
pr_info("supported cmd list:\n");
pr_info("\t vframe\n");
pr_info("\t state\n");
pr_info("\t prog_proc_config 0/1\n");
pr_info("\t init_flag 0/1\n");
pr_info("\t run\n");
pr_info("\t pause\n");
pr_info("\t step\n");
pr_info("\t prun\n");
pr_info("\t ppause\n");
pr_info("\t pstep\n");
pr_info("\t dumpreg\n");
pr_info("\t dumpmif\n");
pr_info("\t recycle_buf\n");
pr_info("\t recycle_post\n");
pr_info("\t mem_map\n");
pr_info("\t afbc_on 0/1\n");
}
kfree(buf_orig);
return count;
}
static int __init di_read_canvas_reverse(char *str)
@@ -1548,6 +1610,7 @@ unsigned char is_bypass(vframe_t *vf_in)
int ret = 0;
static vframe_t vf_tmp;
isbypass_flag = true;
if (di_debug_flag & 0x10000) /* for debugging */
return (di_debug_flag >> 17) & 0x1;
@@ -1627,7 +1690,7 @@ unsigned char is_bypass(vframe_t *vf_in)
)
return 1;
}
isbypass_flag = false;
return 0;
}
@@ -2451,6 +2514,11 @@ static void dump_state(void)
dump_state_flag = 1;
pr_info("version %s, init_flag %d, is_bypass %d\n",
version_s, init_flag, is_bypass(NULL));
pr_info("isbypass_flag %d, needbypass_flag %d\n",
isbypass_flag, needbypass_flag);
pr_info("di_pre_stru.bypass_flag=%d\n",
di_pre_stru.bypass_flag);
pr_info("afbcd support %d\n", afbc_is_supported());
pr_info("recovery_flag = %d, recovery_log_reason=%d, di_blocking=%d",
recovery_flag, recovery_log_reason, di_blocking);
pr_info("recovery_log_queue_idx=%d, recovery_log_di_buf=0x%p\n",
@@ -2858,6 +2926,7 @@ static void pre_de_process(void)
} else
config_di_mif(&di_pre_stru.di_chan2_mif,
di_pre_stru.di_chan2_buf_dup_p);
config_di_wr_mif(&di_pre_stru.di_nrwr_mif, &di_pre_stru.di_mtnwr_mif,
di_pre_stru.di_wr_buf);
@@ -2911,9 +2980,6 @@ static void pre_de_process(void)
* we need to only leave one mask open
* to prevent multiple entry for de_irq
*/
enable_di_pre_aml(&di_pre_stru.di_inp_mif,
&di_pre_stru.di_mem_mif,
&di_pre_stru.di_chan2_mif,
@@ -3459,10 +3525,13 @@ static unsigned char pre_de_buf_config(void)
if (vframe == NULL)
return 0;
if (vframe->type & VIDTYPE_COMPRESS) {
/*for support compress from dec*/
if (IS_COMP_MODE(vframe->type) &&
(!is_from_vdin(vframe))) {
vframe->width = vframe->compWidth;
vframe->height = vframe->compHeight;
}
di_print("DI: get %dth vf[0x%p] from frontend %u ms.\n",
di_pre_stru.in_seq, vframe,
jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
@@ -3597,15 +3666,25 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
di_buf->vframe->width,
di_buf->vframe->height,
di_buf->vframe->source_type);
if (di_buf->type & VIDTYPE_COMPRESS) {
di_pre_stru.cur_width =
di_buf->vframe->compWidth;
di_pre_stru.cur_height =
di_buf->vframe->compHeight;
if (IS_COMP_MODE(di_buf->vframe->type)) {
if (IS_VDIN_SRC(di_buf->vframe->source_type) &&
IS_I_SRC(di_buf->vframe->type)) {
di_pre_stru.cur_width =
di_buf->vframe->compWidth;
di_pre_stru.cur_height =
di_buf->vframe->compHeight*2;
} else {
di_pre_stru.cur_width =
di_buf->vframe->compWidth;
di_pre_stru.cur_height =
di_buf->vframe->compHeight;
}
} else {
di_pre_stru.cur_width = di_buf->vframe->width;
di_pre_stru.cur_height = di_buf->vframe->height;
}
di_pre_stru.cur_prog_flag =
is_progressive(di_buf->vframe);
if (di_pre_stru.cur_prog_flag) {
@@ -3885,7 +3964,11 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
vframe_type_name[di_buf->di_wr_linked_buf->type],
di_buf->di_wr_linked_buf->index);
#endif
if (di_pre_stru.cur_inp_type & VIDTYPE_COMPRESS) {
/*for support compress from dec*/
if (IS_COMP_MODE(di_pre_stru.cur_inp_type) &&
(!(di_pre_stru.cur_inp_type & VIDTYPE_VIU_422))) {
/*compress type and not from vdin*/
di_pre_stru.di_inp_buf->vframe->width =
di_pre_stru.di_inp_buf->vframe->compWidth;
di_pre_stru.di_inp_buf->vframe->height =
@@ -3940,7 +4023,6 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
if (bypass_state == 0)
di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE;
}
if (is_bypass_post()) {
if (bypass_post_state == 0)
di_pre_stru.source_change_flag = 1;
@@ -5909,6 +5991,7 @@ static void di_unreg_process_irq(void)
adpative_combing_exit();
enable_di_pre_mif(false, mcpre_en);
afbc_reg_sw(false);
afbc_input_sw(false);
di_hw_uninit();
if (is_meson_txlx_cpu() || is_meson_txhd_cpu()
|| is_meson_g12a_cpu() || is_meson_g12b_cpu()
@@ -6079,6 +6162,7 @@ static void di_pre_size_change(unsigned short width,
static bool need_bypass(struct vframe_s *vf)
{
needbypass_flag = true;
if (vf->type & VIDTYPE_MVC)
return true;
@@ -6112,6 +6196,7 @@ static bool need_bypass(struct vframe_s *vf)
(vf->width > 720))
return true;
needbypass_flag = false;
return false;
}
@@ -6235,6 +6320,10 @@ static void di_reg_process_irq(void)
calc_lmv_init();
first_field_type = (vframe->type & VIDTYPE_TYPEMASK);
//pr_info("%s , %d\n", __func__, __LINE__);
//pr_info("filed type:0x%x, in H=%d, V=%d\n",
// first_field_type, vframe->width, nr_height);
di_pre_size_change(vframe->width, nr_height,
first_field_type);

View File

@@ -75,6 +75,16 @@
#endif
#endif
#define IS_VDIN_SRC(src) ( \
(src == VFRAME_SOURCE_TYPE_TUNER) || \
(src == VFRAME_SOURCE_TYPE_CVBS) || \
(src == VFRAME_SOURCE_TYPE_COMP) || \
(src == VFRAME_SOURCE_TYPE_HDMI))
#define IS_I_SRC(vftype) (vftype & VIDTYPE_INTERLACE_BOTTOM)
#define IS_COMP_MODE(vftype) (vftype & VIDTYPE_COMPRESS)
enum process_fun_index_e {
PROCESS_FUN_NULL = 0,
PROCESS_FUN_DI,

View File

@@ -34,6 +34,7 @@
#include <linux/string.h>
#include "register.h"
#include "deinterlace_dbg.h"
#include "deinterlace_hw.h"
#include "di_pps.h"
#include "nr_downscale.h"
#include <linux/amlogic/media/vfm/vframe_provider.h>
@@ -630,7 +631,9 @@ void dump_mif_size_state(struct di_pre_stru_s *pre_stru_p,
{
pr_info("======pre mif status======\n");
pr_info("DI_PRE_CTRL=0x%x\n", Rd(DI_PRE_CTRL));
pr_info("DI_PRE_SIZE=0x%x\n", Rd(DI_PRE_SIZE));
pr_info("DI_PRE_SIZE H=%d, V=%d\n",
(Rd(DI_PRE_SIZE)>>16)&0xffff,
Rd(DI_PRE_SIZE)&0xffff);
pr_info("DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE));
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
pr_info("CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec));
@@ -1045,6 +1048,27 @@ void dump_buf_addr(struct di_buf_s *di_buf, unsigned int num)
}
}
void dump_afbcd_reg(void)
{
u32 i;
u32 afbc_reg;
pr_info("---- dump afbc eAFBC_DEC0 reg -----\n");
for (i = 0; i < AFBC_REG_INDEX_NUB; i++) {
afbc_reg = reg_AFBC[eAFBC_DEC0][i];
pr_info("reg 0x%x val:0x%x\n", afbc_reg, RDMA_RD(afbc_reg));
}
pr_info("---- dump afbc eAFBC_DEC1 reg -----\n");
for (i = 0; i < AFBC_REG_INDEX_NUB; i++) {
afbc_reg = reg_AFBC[eAFBC_DEC1][i];
pr_info("reg 0x%x val:0x%x\n", afbc_reg, RDMA_RD(afbc_reg));
}
pr_info("reg 0x%x val:0x%x\n",
VD1_AFBCD0_MISC_CTRL, RDMA_RD(VD1_AFBCD0_MISC_CTRL));
pr_info("reg 0x%x val:0x%x\n",
VD2_AFBCD1_MISC_CTRL, RDMA_RD(VD2_AFBCD1_MISC_CTRL));
}
/*2018-08-17 add debugfs*/
/*same as dump_state*/
static int seq_file_di_state_show(struct seq_file *seq, void *v)

View File

@@ -18,6 +18,8 @@
#define _DI_DBG_H
#include "deinterlace.h"
extern const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB];
void parse_cmd_params(char *buf_orig, char **parm);
void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p);
void dump_di_post_stru(struct di_post_stru_s *di_post_stru_p);
@@ -28,6 +30,7 @@ void dump_di_reg_g12(void);
void print_di_buf(struct di_buf_s *di_buf, int format);
void dump_pre_mif_state(void);
void dump_post_mif_reg(void);
void dump_afbcd_reg(void);
void dump_buf_addr(struct di_buf_s *di_buf, unsigned int num);
void dump_mif_size_state(struct di_pre_stru_s *pre,
struct di_post_stru_s *post);

View File

@@ -28,6 +28,7 @@
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/video_sink/video.h>
#include "deinterlace_hw.h"
#include "register.h"
#include "register_nr4.h"
@@ -59,6 +60,7 @@ module_param_named(pq_load_dbg, pq_load_dbg, uint, 0644);
static bool pd22_flg_calc_en = true;
static unsigned int ctrl_regs[SKIP_CTRE_NUM];
u32 afbc_disable_flag;
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
extern u32 VSYNC_RD_MPEG_REG(u32 adr);
@@ -810,6 +812,96 @@ void enable_di_pre_aml(
);
}
}
const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = {
{
AFBC_ENABLE,
AFBC_MODE,
AFBC_SIZE_IN,
AFBC_DEC_DEF_COLOR,
AFBC_CONV_CTRL,
AFBC_LBUF_DEPTH,
AFBC_HEAD_BADDR,
AFBC_BODY_BADDR,
AFBC_SIZE_OUT,
AFBC_OUT_YSCOPE,
AFBC_STAT,
AFBC_VD_CFMT_CTRL,
AFBC_VD_CFMT_W,
AFBC_MIF_HOR_SCOPE,
AFBC_MIF_VER_SCOPE,
AFBC_PIXEL_HOR_SCOPE,
AFBC_PIXEL_VER_SCOPE,
AFBC_VD_CFMT_H,
},
{
VD2_AFBC_ENABLE,
VD2_AFBC_MODE,
VD2_AFBC_SIZE_IN,
VD2_AFBC_DEC_DEF_COLOR,
VD2_AFBC_CONV_CTRL,
VD2_AFBC_LBUF_DEPTH,
VD2_AFBC_HEAD_BADDR,
VD2_AFBC_BODY_BADDR,
VD2_AFBC_OUT_XSCOPE,
VD2_AFBC_OUT_YSCOPE,
VD2_AFBC_STAT,
VD2_AFBC_VD_CFMT_CTRL,
VD2_AFBC_VD_CFMT_W,
VD2_AFBC_MIF_HOR_SCOPE,
VD2_AFBC_MIF_VER_SCOPE,
VD2_AFBC_PIXEL_HOR_SCOPE,
VD2_AFBC_PIXEL_VER_SCOPE,
VD2_AFBC_VD_CFMT_H,
},
};
static enum eAFBC_DEC afbc_get_decnub(void)
{
enum eAFBC_DEC sel_dec = eAFBC_DEC0;
/* info from vlsi feijun
* gxl:have 1, AFBC_dec0
* txlx:have 2, di only can use 1
* g12a:have 2, di can use 2
* tl1: have 1, AFBC_dec0
*/
if (is_meson_gxl_cpu())
sel_dec = eAFBC_DEC0;
else if (is_meson_txlx_cpu())
sel_dec = eAFBC_DEC1;
else if (is_meson_g12a_cpu())
sel_dec = eAFBC_DEC1;
else if (is_meson_tl1_cpu())
sel_dec = eAFBC_DEC0;
return sel_dec;
}
static const unsigned int *afbc_get_regbase(void)
{
return &reg_AFBC[afbc_get_decnub()][0];
}
bool afbc_is_supported(void)
{
bool ret = false;
if (afbc_disable_flag)
return false;
/*currently support txlx and g12a*/
if (is_meson_txlx_cpu())
ret = false;
else if (is_meson_g12a_cpu())
ret = false;
else if (is_meson_tl1_cpu())
ret = true;
return ret;
}
/*
* after g12a, framereset will not reset simple
* wr mif of pre such as mtn&cont&mv&mcinfo wr
@@ -894,155 +986,75 @@ void enable_afbc_input(struct vframe_s *vf)
}
#endif
enum eAFBC_REG {
eAFBC_ENABLE,
eAFBC_MODE,
eAFBC_SIZE_IN,
eAFBC_DEC_DEF_COLOR,
eAFBC_CONV_CTRL,
eAFBC_LBUF_DEPTH,
eAFBC_HEAD_BADDR,
eAFBC_BODY_BADDR,
eAFBC_SIZE_OUT,
eAFBC_OUT_YSCOPE,
eAFBC_STAT,
eAFBC_VD_CFMT_CTRL,
eAFBC_VD_CFMT_W,
eAFBC_MIF_HOR_SCOPE,
eAFBC_MIF_VER_SCOPE,
eAFBC_PIXEL_HOR_SCOPE,
eAFBC_PIXEL_VER_SCOPE,
eAFBC_VD_CFMT_H,
};
enum eAFBC_DEC {
eAFBC_DEC0,
eAFBC_DEC1,
};
#define AFBC_REG_INDEX_NUB (18)
#define AFBC_DEC_NUB (2)
const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = {
{
AFBC_ENABLE,
AFBC_MODE,
AFBC_SIZE_IN,
AFBC_DEC_DEF_COLOR,
AFBC_CONV_CTRL,
AFBC_LBUF_DEPTH,
AFBC_HEAD_BADDR,
AFBC_BODY_BADDR,
AFBC_SIZE_OUT,
AFBC_OUT_YSCOPE,
AFBC_STAT,
AFBC_VD_CFMT_CTRL,
AFBC_VD_CFMT_W,
AFBC_MIF_HOR_SCOPE,
AFBC_MIF_VER_SCOPE,
AFBC_PIXEL_HOR_SCOPE,
AFBC_PIXEL_VER_SCOPE,
AFBC_VD_CFMT_H,
},
{
VD2_AFBC_ENABLE,
VD2_AFBC_MODE,
VD2_AFBC_SIZE_IN,
VD2_AFBC_DEC_DEF_COLOR,
VD2_AFBC_CONV_CTRL,
VD2_AFBC_LBUF_DEPTH,
VD2_AFBC_HEAD_BADDR,
VD2_AFBC_BODY_BADDR,
VD2_AFBC_OUT_XSCOPE,
VD2_AFBC_OUT_YSCOPE,
VD2_AFBC_STAT,
VD2_AFBC_VD_CFMT_CTRL,
VD2_AFBC_VD_CFMT_W,
VD2_AFBC_MIF_HOR_SCOPE,
VD2_AFBC_MIF_VER_SCOPE,
VD2_AFBC_PIXEL_HOR_SCOPE,
VD2_AFBC_PIXEL_VER_SCOPE,
VD2_AFBC_VD_CFMT_H,
},
};
#define AFBC_DEC_SEL (eAFBC_DEC1)
static enum eAFBC_DEC afbc_get_decnub(void)
{
enum eAFBC_DEC sel_dec = eAFBC_DEC0;
if (is_meson_gxl_cpu())
sel_dec = eAFBC_DEC0;
else if (is_meson_txlx_cpu())
sel_dec = eAFBC_DEC1;
else if (is_meson_g12a_cpu())
sel_dec = AFBC_DEC_SEL;
/* TL1 only have AFBC0 */
else if (is_meson_tl1_cpu())
sel_dec = eAFBC_DEC0;
return sel_dec;
}
static const unsigned int *afbc_get_regbase(void)
{
return &reg_AFBC[afbc_get_decnub()][0];
}
bool afbc_is_supported(void)
{
bool ret = false;
/*currently support txlx and g12a*/
if (is_meson_txlx_cpu()
|| is_meson_g12a_cpu()
/*|| is_meson_tl1_cpu()*/)
ret = false;
return ret;
}
void enable_afbc_input(struct vframe_s *vf)
u32 enable_afbc_input(struct vframe_s *vf)
{
unsigned int r, u, v, w_aligned, h_aligned;
unsigned int out_height = 0;
unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0;
const unsigned int *reg = afbc_get_regbase();
unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0;
unsigned int out_height = 0;
if (!afbc_is_supported())
return;
return false;
if ((vf->type & VIDTYPE_COMPRESS)) {
// only reg for the first time
if (vf->type & VIDTYPE_COMPRESS) {
/*only reg for the first time*/
afbc_reg_sw(true);
afbc_sw_trig(true);
afbc_sw(true);
} else {
afbc_sw_trig(false);
return;
afbc_sw(false);
return false;
}
w_aligned = round_up((vf->width-1), 32);
h_aligned = round_up((vf->height-1), 4);
w_aligned = round_up((vf->width), 32);
/*if (di_pre_stru.cur_inp_type & VIDTYPE_INTERLACE)*/
if ((vf->type & VIDTYPE_INTERLACE) &&
(vf->type & VIDTYPE_VIU_422))
h_aligned = round_up((vf->height/2), 4);/*from vdin and is i */
else
h_aligned = round_up((vf->height), 4);
/*AFBCD working mode config*/
r = (3 << 24) |
(10 << 16) |
(1 << 14) | /*burst1 1*/
(vf->bitdepth & BITDEPTH_MASK);
if (vf->bitdepth & BITDEPTH_SAVING_MODE)
r |= (1<<28); /* mem_saving_mode */
if (vf->type & VIDTYPE_SCATTER)
r |= (1<<29);
out_height = h_aligned;
if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) {
r |= 0x40;
vt_ini_phase = 0xc;
out_height = h_aligned>>1;
} else if ((vf->type & VIDTYPE_TYPEMASK) ==
VIDTYPE_INTERLACE_BOTTOM) {
r |= 0x80;
vt_ini_phase = 0x4;
vfmt_rpt_first = 0;
out_height = h_aligned>>1;
if (!(vf->type & VIDTYPE_VIU_422)) {
/*from dec, process P as i*/
if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) {
r |= 0x40;
vt_ini_phase = 0xc;
vfmt_rpt_first = 1;
out_height = h_aligned>>1;
} else if ((vf->type & VIDTYPE_TYPEMASK) ==
VIDTYPE_INTERLACE_BOTTOM) {
r |= 0x80;
vt_ini_phase = 0x4;
vfmt_rpt_first = 0;
out_height = h_aligned>>1;
}
}
RDMA_WR(reg[eAFBC_MODE], r);
r = 0x1600;
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
/* un compress mode data from vdin bit block order is
* different with from dos
*/
if (!(vf->type & VIDTYPE_VIU_422))
r |= (1 << 19); /* dos_uncomp */
if (vf->type & VIDTYPE_COMB_MODE)
r |= (1 << 20);
}
RDMA_WR(reg[eAFBC_ENABLE], r);
r = 0x100;
/* TL1 add bit[13:12]: fmt_mode; 0:yuv444; 1:yuv422; 2:yuv420
* di does not support yuv444, so for fmt yuv444 di will bypass+
@@ -1056,12 +1068,21 @@ void enable_afbc_input(struct vframe_s *vf)
r |= (2 << 12);
}
RDMA_WR(reg[eAFBC_CONV_CTRL], r);
u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3;
v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3;
RDMA_WR(reg[eAFBC_DEC_DEF_COLOR],
0x3FF00000 | /*Y,bit20+*/
0x80 << (u + 10) |
0x80 << v);
u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3;
v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3;
RDMA_WR(reg[eAFBC_DEC_DEF_COLOR],
0x3FF00000 | /*Y,bit20+*/
0x80 << (u + 10) |
0x80 << v);
/* chroma formatter */
RDMA_WR(reg[eAFBC_VD_CFMT_CTRL],
(1 << 21) |/* HFORMATTER_YC_RATIO_2_1 */
@@ -1070,25 +1091,46 @@ void enable_afbc_input(struct vframe_s *vf)
(vt_ini_phase << 8) |
(16 << 1)|/* VFORMATTER_PHASE_BIT */
0);/* different with inp */
#if 0
if (((vf->width-1) != RDMA_RD(reg[eAFBC_PIXEL_HOR_SCOPE])) ||
((vf->height-1) != RDMA_RD(reg[eAFBC_PIXEL_VER_SCOPE]))) {
pr_info("[afbc] in vf type=0x%x\n", vf->type);
/*pr_info("cur_inp_type=0x%x\n", di_pre_stru.cur_inp_type);*/
pr_info("[afbc] w_aligned=%d, h_aligned=%d\n",
w_aligned, h_aligned);
pr_info("[afbc] vfwidth=%d, vfheight=%d\n",
vf->width, vf->height);
pr_info("[afbc] out_height=%d\n", out_height);
}
#endif
if (vf->type & VIDTYPE_VIU_444)
RDMA_WR(reg[eAFBC_VD_CFMT_W],
(w_aligned << 16) | (w_aligned/2));
else
RDMA_WR(reg[eAFBC_VD_CFMT_W],
(w_aligned << 16) | (w_aligned));
RDMA_WR(reg[eAFBC_VD_CFMT_W],
(w_aligned << 16) | (w_aligned/2));
RDMA_WR(reg[eAFBC_MIF_HOR_SCOPE],
(0 << 16) | ((w_aligned>>5) - 1));
(0 << 16) | ((w_aligned>>5)-1));
RDMA_WR(reg[eAFBC_MIF_VER_SCOPE],
(0 << 16) | ((h_aligned>>2) - 1));
(0 << 16) | ((h_aligned>>2)-1));
RDMA_WR(reg[eAFBC_PIXEL_HOR_SCOPE],
(0 << 16) | (vf->width - 1));
(0 << 16) | (vf->width-1));
RDMA_WR(reg[eAFBC_PIXEL_VER_SCOPE],
0 << 16 | (vf->height-1));
RDMA_WR(reg[eAFBC_VD_CFMT_H], out_height);
RDMA_WR(reg[eAFBC_PIXEL_VER_SCOPE],
0 << 16 | (vf->height-1));
RDMA_WR(reg[eAFBC_SIZE_IN], h_aligned | w_aligned << 16);
RDMA_WR(reg[eAFBC_SIZE_IN], (vf->height) | w_aligned << 16);
RDMA_WR(reg[eAFBC_SIZE_OUT], out_height | w_aligned << 16);
RDMA_WR(reg[eAFBC_HEAD_BADDR], vf->compHeadAddr>>4);
RDMA_WR(reg[eAFBC_BODY_BADDR], vf->compBodyAddr>>4);
return true;
}
static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on) /*g12a*/
{
unsigned int reg_ctrl;
@@ -1103,6 +1145,7 @@ static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on) /*g12a*/
RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8);
}
static void afbcx_sw(bool on) /*g12a*/
{
unsigned int tmp;
@@ -1130,9 +1173,10 @@ static void afbcx_sw(bool on) /*g12a*/
| (1<<12)
| (1<<9);
RDMA_WR(reg_ctrl, tmp);
/*0:vd1 to di 1:vd2 to di */
RDMA_WR_BITS(VD2_AFBCD1_MISC_CTRL,
(reg_ctrl == VD1_AFBCD0_MISC_CTRL)?0:1, 8, 1);
RDMA_WR(reg_en, 0x1600);
/*RDMA_WR(reg_en, 0x1600);*/
RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1);
/*TL1 add mem control bit */
if (is_meson_tl1_cpu())
@@ -1147,8 +1191,6 @@ static void afbcx_sw(bool on) /*g12a*/
// printk("%s,on[%d],CTRL[0x%x],en[0x%x]\n", __func__, on,
// RDMA_RD(VD1_AFBCD0_MISC_CTRL),
// RDMA_RD(VD1_AFBCD0_MISC_CTRL));
}
static void afbc_sw_old(bool on)/*txlx*/
{
@@ -1165,7 +1207,6 @@ static void afbc_sw_old(bool on)/*txlx*/
reg_en = VD2_AFBC_ENABLE;
}
if (on) {
/* DI inp(current data) switch to AFBC */
if (RDMA_RD_BITS(VIU_MISC_CTRL0, 29, 1) != 1)
@@ -1185,26 +1226,20 @@ static void afbc_sw_old(bool on)/*txlx*/
} else {
RDMA_WR(reg_en, 0);
/* afbc to vpp(replace vd1) enable */
if (RDMA_RD_BITS(VIU_MISC_CTRL1, 0, 1) != 0 ||
RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) != 0) {
RDMA_WR_BITS(VIU_MISC_CTRL1, 0, 0, 1);
RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1);
}
}
}
static bool afbc_is_used(void)
{
bool ret = false;
if (RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) == 1)
ret = true;
//di_print("%s:%d\n",__func__,ret);
return ret;
}
static void afbc_power_sw(bool on)
@@ -1222,15 +1257,21 @@ static void afbc_power_sw(bool on)
switch_vpu_mem_pd_vmod(vpu_sel,
on?VPU_MEM_POWER_ON:VPU_MEM_POWER_DOWN);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
afbcx_power_sw(dec_sel, on);
}
static int afbc_reg_unreg_flag;
void afbc_sw(bool on)
{
if (is_meson_gxl_cpu() || is_meson_txlx_cpu())
afbc_sw_old(on);
else
afbcx_sw(on);
}
void afbc_reg_sw(bool on)
{
if (!afbc_is_supported())
return;
@@ -1239,25 +1280,18 @@ void afbc_reg_sw(bool on)
afbc_reg_unreg_flag = 1;
}
if ((!on) && afbc_reg_unreg_flag) {
afbc_sw_trig(false);
afbc_sw(false);
afbc_power_sw(false);
afbc_reg_unreg_flag = 0;
}
}
static void afbc_sw(bool on)
{
if (is_meson_gxl_cpu() || is_meson_txlx_cpu())
afbc_sw_old(on);
else
afbcx_sw(on);
}
#if 0
void afbc_sw_trig(bool on)
{
afbc_sw(on);
}
static void afbc_input_sw(bool on)
#endif
void afbc_input_sw(bool on)
{
const unsigned int *reg = afbc_get_regbase();
unsigned int reg_AFBC_ENABLE;
@@ -3624,9 +3658,11 @@ static void di_pre_data_mif_ctrl(bool enable)
if (Rd_reg_bits(VIU_MISC_CTRL1, 0, 1) == 1)
RDMA_WR_BITS(VD2_AFBC_ENABLE, 0, 8, 1);
#else
/* disable AFBC input */
if (afbc_is_used())
afbc_input_sw(false);
/*
* disable AFBC input at unreg
*/
//if (afbc_is_used())
// afbc_input_sw(false);
#endif
}

View File

@@ -27,6 +27,34 @@
#define SKIP_CTRE_NUM 13
enum eAFBC_REG {
eAFBC_ENABLE, /*0x1ae0*/
eAFBC_MODE, /*0x1ae1*/
eAFBC_SIZE_IN, /*0x1ae2*/
eAFBC_DEC_DEF_COLOR, /*0x1ae3*/
eAFBC_CONV_CTRL, /*0x1ae4*/
eAFBC_LBUF_DEPTH, /*0x1ae5*/
eAFBC_HEAD_BADDR, /*0x1ae6*/
eAFBC_BODY_BADDR, /*0x1ae7*/
eAFBC_SIZE_OUT, /*0x1ae8*/
eAFBC_OUT_YSCOPE, /*0x1ae9*/
eAFBC_STAT, /*0x1aea*/
eAFBC_VD_CFMT_CTRL, /*0x1aeb*/
eAFBC_VD_CFMT_W, /*0x1aec*/
eAFBC_MIF_HOR_SCOPE, /*0x1aed*/
eAFBC_MIF_VER_SCOPE, /*0x1aee*/
eAFBC_PIXEL_HOR_SCOPE, /*0x1aef*/
eAFBC_PIXEL_VER_SCOPE, /*0x1af0*/
eAFBC_VD_CFMT_H, /*0x1af1*/
};
enum eAFBC_DEC {
eAFBC_DEC0,
eAFBC_DEC1,
};
#define AFBC_REG_INDEX_NUB (18)
#define AFBC_DEC_NUB (2)
struct DI_MIF_s {
unsigned short luma_x_start0;
unsigned short luma_x_end0;
@@ -91,6 +119,7 @@ struct di_pq_parm_s {
struct list_head list;
};
extern u32 afbc_disable_flag;
void read_pulldown_info(unsigned int *glb_frm_mot_num,
unsigned int *glb_fid_mot_num);
void read_new_pulldown_info(struct FlmModReg_t *pFMRegp);
@@ -109,7 +138,7 @@ void enable_di_pre_aml(
struct DI_SIM_MIF_s *di_contwr_mif,
unsigned char madi_en, unsigned char pre_field_num,
unsigned char pre_vdin_link);
void enable_afbc_input(struct vframe_s *vf);
u32 enable_afbc_input(struct vframe_s *vf);
void mc_pre_mv_irq(void);
void enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif,
@@ -179,7 +208,9 @@ void di_txl_patch_prog(int prog_flg, unsigned int cnt, bool mc_en);
bool afbc_is_supported(void);
//extern void afbc_power_sw(bool on);
extern void afbc_reg_sw(bool on);
extern void afbc_sw_trig(bool on);
/*extern void afbc_sw_trig(bool on);*/
extern void afbc_sw(bool on);
extern void afbc_input_sw(bool on);
extern void dump_vd2_afbc(void);
extern u8 *di_vmap(ulong addr, u32 size, bool *bflg);