di: support the interlace format from vdin afbc [2/2]
authorYong Qin <yong.qin@amlogic.com>
Thu, 28 Feb 2019 03:17:17 +0000 (11:17 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 11 Mar 2019 09:37:25 +0000 (01:37 -0800)
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>
drivers/amlogic/media/deinterlace/deinterlace.c
drivers/amlogic/media/deinterlace/deinterlace.h
drivers/amlogic/media/deinterlace/deinterlace_dbg.c
drivers/amlogic/media/deinterlace/deinterlace_dbg.h
drivers/amlogic/media/deinterlace/deinterlace_hw.c
drivers/amlogic/media/deinterlace/deinterlace_hw.h

index c78ccab..028fd8a 100644 (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);
 
index 9aa19e2..c594d61 100644 (file)
 #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,
index a65a546..0a3094c 100644 (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)
index ab4cbd9..21e83a9 100644 (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);
index 2c157bf..972ed8e 100644 (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_reg_sw(bool on)
+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
        }
index eb30353..28ec32c 100644 (file)
 
 #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);