From 3f4854e57de2065dd16dcf7e9de1fd02f7935dff Mon Sep 17 00:00:00 2001 From: Yong Qin Date: Thu, 28 Feb 2019 11:17:17 +0800 Subject: [PATCH] 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 --- .../amlogic/media/deinterlace/deinterlace.c | 127 +++++- .../amlogic/media/deinterlace/deinterlace.h | 10 + .../media/deinterlace/deinterlace_dbg.c | 26 +- .../media/deinterlace/deinterlace_dbg.h | 3 + .../media/deinterlace/deinterlace_hw.c | 364 ++++++++++-------- .../media/deinterlace/deinterlace_hw.h | 35 +- 6 files changed, 379 insertions(+), 186 deletions(-) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index c78ccabee747..028fd8a68fd7 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -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); diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index 9aa19e26558a..c594d61a0b9f 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -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, diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c index a65a546bd46d..0a3094c293eb 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c @@ -34,6 +34,7 @@ #include #include "register.h" #include "deinterlace_dbg.h" +#include "deinterlace_hw.h" #include "di_pps.h" #include "nr_downscale.h" #include @@ -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) diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h index ab4cbd98f4b1..21e83a9f8291 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h @@ -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); diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index 2c157bf11b99..972ed8e2532c 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -28,6 +28,7 @@ #include #include #include +#include #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 ®_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 ®_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 } diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index eb303531e46c..28ec32c4c41a 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -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);