vpp: support the interlace format from vdin afbc [1/2]
authorYong Qin <yong.qin@amlogic.com>
Thu, 28 Feb 2019 03:24:59 +0000 (11:24 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:44:09 +0000 (14:44 +0800)
PD#SWPL-5205

Problem:
Now vdin support afbc+interlace format

Solution:
In vpp, add case to support vdin afbc with interlace

Verify:
tl1_x301, verify pass

Change-Id: I6540b03a6cb5308fc2bc202069aa87234fd35df6
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
a6973fc di: small window bottom of the screen no video [1/1]
fed45cd di: small window bottom of the screen is blank [1/1]
fb34727 deinterlace: fix tl1 in 1080i has small sawtooth [1/1]
66bdbe7 di: bringup for tm2 [1/1]
13ebe46 di: monkey test di cause crash [1/1]
2c8ed09 di: "DI: di_init_buf vmap fail" is seen when power on [1/1]
7ba6477 di: av to dtv , black screen [1/1]
5970920 di: The last frame of the video flash garbage [1/1]
8c3e98d di: flash green when play 265 SD video [1/1]
975c0ee di: exit play local 4k video flashing [1/1]
edc1970 di: pretect reg unreg flow [1/1]
030872b di: 1080p,the screen display anormal [1/1]
3f4854e di: support the interlace format from vdin afbc [2/2]
89a190a vpp: support the interlace format from vdin afbc [1/2]

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>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
di: 1080p,the screen display anormal [1/1]

PD#SWPL-5874

Problem:
1080p the screen display anormal

Solution:
compress mode, modify vdin frame type.

Verify:
tl1

Change-Id: Ic1ee1472105861c8debce2a1645f70ed617fd132
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
di: pretect reg unreg flow [1/1]

PD#SWPL-4918

Problem:
when reg unreg event called too fast, di cause system crash

Solution:
pretect reg and unreg flow

Verify:
tl1

Change-Id: I9b3e28c2b0b709d4f53f60b1f044a390933117ce
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
di: exit play local 4k video flashing [1/1]

PD#SWPL-5877

Problem:
1.afbc mode, play h.265 local video, when exit playing,
screen will flashing sometimes.
2.when exit playing, there cost 5s time.

Solution:
4k video di bypass, afbc hw module used by vpp, when
DI unreg, needn't to disable AFBC moudule.

Verify:
tl1

Change-Id: I2ac66a145a009042d286dda50e7259657f4bfc8e
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
di: flash green when play 265 SD video [1/1]

PD#SWPL-6097

Problem:
flash green garbages when play h.265 SD video

Solution:
afbc input not enable

Verify:
tl1

Change-Id: I310eeb6d922ab8b9035c815afc4e967c0e5390ff
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
di: The last frame of the video flash garbage [1/1]

PD#SWPL-6070

Problem:
flash garbages when unreg process.

Solution:
can't speed down the clkb rate, there is a mirror mode

Verify:
tl1

Change-Id: I5fcc29a1cda196992a457f40fee31992f4bc1528
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
di: av to dtv , black screen [1/1]

PD#SWPL-6096

Problem:
from local av switch to dtv,black screen,then search channel

Solution:
revert the modification "62617"

Verify:
tl1

Change-Id: I49ae627b9f0b1f6a776e5cbffc723a43e85cee72
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
di: "DI: di_init_buf vmap fail" is seen when power on [1/1]

PD#SWPL-5908

Problem:
execute vmap when di reserved memory is disable

Solution:
skip memory calculation in init buf  while using cma

Verify:
verified by t962x2_x301

Change-Id: Ib0c2e422f61f2b4182109cb7bbb3107029363ce0
Signed-off-by: zhiwei.yuan <zhiwei.yuan@amlogic.com>
di: monkey test di cause crash [1/1]

PD#SWPL-6133

Problem:
monkey test di cause crash,when is di reg processing, unreg event
attach, and released the di buffer, so cause crash.

Solution:
every unreg event received, need waitting reg process had done.

Verify:
tl1

Change-Id: I2f2bb068ed65ab14ab4f09de96b64d7290da5914
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
di: bringup for tm2 [1/1]

PD#SWPL-6575

Problem:
chip bring up

Solution:
1.add tm2 chip id for tm2
2.add h scaling down function for tm2

Verify:
tm2

Change-Id: I364d7c07be331d81ef546357445225c6071f8e3c
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
deinterlace: fix tl1 in 1080i has small sawtooth [1/1]

PD#SWPL-4072

Problem:
tl1 1080i in some dark scenes and roller coasters
have small sawtooth

Solution:
adjust a set of registers with special motion

Verify:
tl1

Change-Id: Idbe62e823f1c6c683b67d000978de1862c8e3162
Signed-off-by: Wenfeng Guo <wenfeng.guo@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
di: small window bottom of the screen is blank [1/1]

PD#TV-4708

Problem:
small window, bottom of the screen is covered by
blank on the online video

Solution:
vline is odd, mif out is not right

Verify:
verify on TL1

Change-Id: I39eb0cdfd2f4b200a09a9c8b779f509caf6dea37
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
di: small window bottom of the screen no video [1/1]

PD#TV-4708

Problem:
small window,v scaling mode, bottom of the screen is no video.

Solution:
vline is odd, mif out is not more enouth

Verify:
verify on TL1

Change-Id: I2ac35af3632e8b14df5c773b322d4b2d64b050ba
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
14 files changed:
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
drivers/amlogic/media/deinterlace/deinterlace_mtn.c
drivers/amlogic/media/deinterlace/deinterlace_mtn.h
drivers/amlogic/media/deinterlace/di_pps.c
drivers/amlogic/media/deinterlace/di_pps.h
drivers/amlogic/media/deinterlace/nr_drv.c
drivers/amlogic/media/deinterlace/register.h
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/video_sink/vpp.c

index a0c9b5a..98e9740 100644 (file)
@@ -105,7 +105,7 @@ static int mpeg2vdin_en;
 #endif
 
 static int queue_print_flag = -1;
-static int di_reg_unreg_cnt = 100;
+static int di_reg_unreg_cnt = 1000;
 static bool overturn;
 static bool check_start_drop_prog;
 static bool mcpre_en = true;
@@ -113,7 +113,7 @@ static bool mcpre_en = true;
 static bool mc_mem_alloc;
 
 static unsigned int di_pre_rdma_enable;
-
+static struct mutex di_event_mutex;
 
 static unsigned int di_force_bit_mode = 10;
 module_param(di_force_bit_mode, uint, 0664);
@@ -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-03-18a";
+static const char version_s[] = "2019-0422b:vscale_skip v is odd";
 
 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 = true;
+static unsigned int needbypass_flag = true;
 
 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,12 +608,17 @@ 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, "dumppostmif", 11) == 0) {
+               dump_post_mif_reg();
        } else if (strncmp(buf, "recycle_buf", 11) == 0) {
                recycle_keep_buffer();
        } else if (strncmp(buf, "recycle_post", 12) == 0) {
@@ -589,10 +626,38 @@ 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 dumppostmif\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)
@@ -1550,6 +1615,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 +1693,7 @@ unsigned char is_bypass(vframe_t *vf_in)
                        )
                        return 1;
        }
-
+       isbypass_flag = false;
        return 0;
 }
 
@@ -2072,7 +2138,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
 
        if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
                canvas_align_width = 64;
-
+       pr_info("di: %s -S\n", __func__);
        frame_count = 0;
        disp_frame_count = 0;
        cur_post_ready_di_buf = NULL;
@@ -2177,46 +2243,62 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
 
                        if (prog_flag) {
                                di_buf->canvas_height = canvas_height;
-                               di_buf->nr_adr = de_devp->mem_start +
-                                       di_buf_size * i;
+
+                               //use reserved memory
+                               if (de_devp->flag_cma == 0)
+                                       di_buf->nr_adr = de_devp->mem_start +
+                                               di_buf_size * i;
+
                                di_buf->canvas_config_flag = 1;
                        } else {
                                di_buf->canvas_height = (canvas_height>>1);
                                di_buf->canvas_height =
                                        roundup(di_buf->canvas_height,
                                        canvas_align_width);
-                               di_buf->nr_adr = de_devp->mem_start +
-                                       di_buf_size * i;
-                               di_buf->mtn_adr = de_devp->mem_start +
-                                       di_buf_size * i +
-                                       nr_size;
-                               di_buf->cnt_adr = de_devp->mem_start +
-                                       di_buf_size * i +
-                                       nr_size + mtn_size;
-
-                               if (mc_mem_alloc) {
-                                       di_buf->mcvec_adr = de_devp->mem_start +
+
+                               //use reserved memory
+                               if (de_devp->flag_cma == 0) {
+                                       di_buf->nr_adr = de_devp->mem_start +
+                                               di_buf_size * i;
+                                       di_buf->mtn_adr = de_devp->mem_start +
                                                di_buf_size * i +
-                                               nr_size + mtn_size + count_size;
-                                       di_buf->mcinfo_adr =
-                                               de_devp->mem_start +
-                                               di_buf_size * i + nr_size +
-                                               mtn_size + count_size + mv_size;
-                                       tmp = di_vmap(di_buf->mcinfo_adr,
-                                               di_pre_stru.mcinfo_size,
-                                               &di_buf->bflg_vmap);
+                                               nr_size;
+                                       di_buf->cnt_adr = de_devp->mem_start +
+                                               di_buf_size * i +
+                                               nr_size + mtn_size;
+
+                                       if (mc_mem_alloc) {
+                                               di_buf->mcvec_adr =
+                                                       de_devp->mem_start +
+                                                       di_buf_size * i +
+                                                       nr_size + mtn_size +
+                                                       count_size;
+                                               di_buf->mcinfo_adr =
+                                                       de_devp->mem_start +
+                                                       di_buf_size * i +
+                                                       nr_size +
+                                                       mtn_size +
+                                                       count_size + mv_size;
+                                               tmp = di_vmap(
+                                                       di_buf->mcinfo_adr,
+                                                       di_pre_stru.
+                                                       mcinfo_size,
+                                                       &di_buf->bflg_vmap);
 
                                        if (di_buf->bflg_vmap == true)
                                                di_buf->mcinfo_vaddr =
-                                                       (unsigned short *)tmp;
+                                               (unsigned short *)tmp;
                                        else {
                                                di_buf->mcinfo_vaddr = NULL;
                                                pr_err("DI: %s vmap fail\n",
                                                        __func__);
                                        }
+                                       }
                                }
+
                                di_buf->canvas_config_flag = 2;
                        }
+
                        di_buf->index = i;
                        di_buf->vframe = &(vframe_local[i]);
                        di_buf->vframe->private_data = di_buf;
@@ -2236,8 +2318,11 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
                up(&di_sema);
        }
 #endif
-       di_post_mem = de_devp->mem_start +
-               di_buf_size*de_devp->buf_num_avail;
+
+       //use reserved memory
+       if (de_devp->flag_cma == 0)
+               di_post_mem = de_devp->mem_start +
+                       di_buf_size*de_devp->buf_num_avail;
        if (post_wr_en && post_wr_support) {
                di_post_buf_size = nr_width * canvas_height * 2;
                /* pre buffer must 2 more than post buffer */
@@ -2285,8 +2370,11 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
                                                (nr_width << 1);
                                        di_buf->canvas_height = canvas_height;
                                        di_buf->canvas_config_flag = 1;
-                                       di_buf->nr_adr = di_post_mem +
-                                               di_post_buf_size*i;
+
+                                       //use reserved memory
+                                       if (de_devp->flag_cma == 0)
+                                               di_buf->nr_adr = di_post_mem +
+                                                       di_post_buf_size*i;
                                }
                                queue_in(di_buf, QUEUE_POST_FREE);
                        }
@@ -2298,6 +2386,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
                nr_ds_buf_init(de_devp->flag_cma, nrds_mem,
                        &(de_devp->pdev->dev));
        }
+       pr_info("di: %s -E\n", __func__);
        return 0;
 }
 
@@ -2456,6 +2545,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",
@@ -2926,6 +3020,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);
 
@@ -2989,9 +3084,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,
@@ -3463,6 +3555,11 @@ module_param_named(pps_position, pps_position, uint, 0644);
 static unsigned int pre_enable_mask = 3;/*bit0:ma bit1:mc*/
 module_param_named(pre_enable_mask, pre_enable_mask, uint, 0644);
 
+static bool pre_hsc_down_en;
+module_param_named(pre_hsc_down_en, pre_hsc_down_en, bool, 0644);
+static int pre_hsc_down_width = 480;
+module_param_named(pre_hsc_down_width, pre_hsc_down_width, int, 0644);
+
 static unsigned char pre_de_buf_config(void)
 {
        struct di_buf_s *di_buf = NULL;
@@ -3536,10 +3633,18 @@ static unsigned char pre_de_buf_config(void)
                if (vframe == NULL)
                        return 0;
 
-               if (vframe->type & VIDTYPE_COMPRESS) {
-                       vframe->width = vframe->compWidth;
-                       vframe->height = vframe->compHeight;
+               /*for support compress from dec*/
+               if (IS_COMP_MODE(vframe->type)) {
+                       if (IS_VDIN_SRC(vframe->source_type)
+                               && IS_I_SRC(vframe->type)) {
+                               vframe->width = vframe->compWidth;
+                               vframe->height = vframe->compHeight*2;
+                       } else {
+                               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));
@@ -3677,15 +3782,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) {
@@ -3893,6 +4008,18 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
                                }
                        }
                } else {
+               /*********************************/
+               if ((di_buf->vframe->width >= 1920) &&
+                       (di_buf->vframe->height >= 1080) &&
+                       is_meson_tl1_cpu()) {
+                       if (combing_fix_en) {
+                               combing_fix_en = false;
+                               fix_tl1_1080i_sawtooth_patch();
+                       }
+               } else
+                       combing_fix_en = true;
+
+               /*********************************/
                        if (
                                di_pre_stru.di_chan2_buf_dup_p == NULL) {
                                di_pre_stru.field_count_for_cont = 0;
@@ -3962,7 +4089,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, not from vdin*/
+       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 =
@@ -3984,7 +4115,15 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
                }
                if (pps_dsth != di_buf->vframe->height)
                        di_buf->vframe->height = pps_dsth;
+       } else if (de_devp->h_sc_down_en) {
+               if (pre_hsc_down_width != di_buf->vframe->width) {
+                       pr_info("di: hscd %d to %d\n", di_buf->vframe->width,
+                               pre_hsc_down_width);
+                       di_buf->vframe->width = pre_hsc_down_width;
+                       di_pre_stru.width_bk = pre_hsc_down_width;
+               }
        }
+
        if (di_force_bit_mode == 10) {
                di_buf->vframe->bitdepth |= (BITDEPTH_Y10);
                if (full_422_pack)
@@ -4017,7 +4156,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;
@@ -4742,9 +4880,16 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines,
        di_end_y = zoom_end_y_lines;
        di_height = di_end_y - di_start_y + 1;
        di_height = di_height / (di_vscale_skip_count_real + 1);
+
        /* make sure the height is even number */
-       if (di_height%2)
-               di_height++;
+       if (di_height%2) {
+               /*for skip mode,post only half line-1*/
+               if (((di_height > 150) && (di_height < 1080)) &&
+                       di_vscale_skip_count_real)
+                       di_height = di_height - 3;
+               else
+                       di_height++;
+       }
 
        if (Rd(DI_POST_SIZE) != ((di_width - 1) | ((di_height - 1) << 16)) ||
            di_post_stru.buf_type != di_buf->di_buf_dup_p[0]->type ||
@@ -5208,6 +5353,8 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines,
                        is_meson_txhd_cpu() ||
                        is_meson_g12a_cpu() ||
                        is_meson_g12b_cpu() ||
+                       is_meson_tl1_cpu() ||
+                       is_meson_tm2_cpu() ||
                        is_meson_sm1_cpu()) {
                di_post_read_reverse_irq(overturn, mc_pre_flag,
                        post_blend_en ? mcpre_en : false);
@@ -5990,11 +6137,21 @@ static void di_unreg_process_irq(void)
 #endif
        adpative_combing_exit();
        enable_di_pre_mif(false, mcpre_en);
-       afbc_reg_sw(false);
+       /*disable afbc module when afbc working in DI*/
+       afbc_reg_unreg_flag = 0;
+       #if 0
+       if (IS_COMP_MODE(di_pre_stru.cur_inp_type) &&
+               (!needbypass_flag && !isbypass_flag)) {
+               pr_info("DI: disable afbc\n");
+               afbc_reg_sw(false);
+               afbc_input_sw(false);
+       }
+       #endif
        di_hw_uninit();
        if (is_meson_txlx_cpu() || is_meson_txhd_cpu()
                || is_meson_g12a_cpu() || is_meson_g12b_cpu()
-               || is_meson_tl1_cpu() || is_meson_sm1_cpu()) {
+               || is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+               is_meson_tm2_cpu()) {
                di_pre_gate_control(false, mcpre_en);
                nr_gate_control(false);
        } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
@@ -6007,7 +6164,8 @@ static void di_unreg_process_irq(void)
                di_hw_disable(mcpre_en);
                if (is_meson_txlx_cpu() || is_meson_txhd_cpu()
                        || is_meson_g12a_cpu() || is_meson_g12b_cpu()
-                       || is_meson_tl1_cpu() || is_meson_sm1_cpu()) {
+                       || is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+                       is_meson_tm2_cpu()) {
                        enable_di_post_mif(GATE_OFF);
                        di_post_gate_control(false);
                        di_top_gate_control(false, false);
@@ -6120,7 +6278,7 @@ static void di_pre_size_change(unsigned short width,
                        is_meson_txhd_cpu() ||
                        is_meson_g12a_cpu() ||
                        is_meson_g12b_cpu() ||
-                       is_meson_tl1_cpu() ||
+                       is_meson_tl1_cpu() || is_meson_tm2_cpu() ||
                        is_meson_sm1_cpu())
                        film_mode_win_config(width, height);
        }
@@ -6153,6 +6311,15 @@ static void di_pre_size_change(unsigned short width,
                pps_h = di_pre_stru.cur_height>>1;
                di_pps_config(1, pps_w, pps_h, pps_dstw, (pps_dsth>>1));
        }
+
+       if (de_devp->h_sc_down_en) {
+               pps_w = di_pre_stru.cur_width;
+               di_inp_hsc_setting(pps_w, pre_hsc_down_width);
+       } else {
+               di_inp_hsc_setting(di_pre_stru.cur_width,
+                       di_pre_stru.cur_width);
+       }
+
        di_interrupt_ctrl(di_pre_stru.madi_enable,
                det3d_en?1:0,
                de_devp->nrds_enable,
@@ -6162,6 +6329,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;
 
@@ -6195,6 +6363,7 @@ static bool need_bypass(struct vframe_s *vf)
                (vf->width > 720))
                return true;
 
+       needbypass_flag = false;
        return false;
 }
 
@@ -6216,6 +6385,7 @@ static void di_reg_process_irq(void)
        if (pre_run_flag == DI_RUN_FLAG_STEP)
                pre_run_flag = DI_RUN_FLAG_STEP_DONE;
 
+       di_pre_stru.reg_irq_busy = true;
 
        vframe = vf_peek(VFM_NAME);
 
@@ -6227,6 +6397,7 @@ static void di_reg_process_irq(void)
                        }
                        di_pre_stru.bypass_flag = true;
                        di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false);
+                       di_pre_stru.reg_irq_busy = false;
                        return;
                } else {
                        di_pre_stru.bypass_flag = false;
@@ -6247,6 +6418,8 @@ static void di_reg_process_irq(void)
                }
                de_devp->nrds_enable = nrds_en;
                de_devp->pps_enable = pps_en;
+               /*di pre h scaling down: sm1 tm2*/
+               de_devp->h_sc_down_en = pre_hsc_down_en;
                switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON);
                if (post_wr_en && post_wr_support)
                        diwr_set_power_control(1);
@@ -6315,9 +6488,15 @@ static void di_reg_process_irq(void)
                        spin_unlock_irqrestore(&plist_lock, flags);
 #endif
                }
+               if (!reg_flag)
+                       pr_err("di: warning unreg in reg irq\n");
 
                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);
 
@@ -6335,6 +6514,7 @@ static void di_reg_process_irq(void)
                init_flag = 1;
                di_pre_stru.reg_req_flag_irq = 1;
        }
+       di_pre_stru.reg_irq_busy = false;
 }
 
 static void di_process(void)
@@ -6509,11 +6689,14 @@ static int di_task_handle(void *data)
                                di_pre_stru.disable_req_flag) &&
                                (di_pre_stru.pre_de_busy == 0)) {
                                di_unreg_process();
+                               #if 0
+                               /* if mirror mode, can't speed down the clk*/
                                /* set min rate for power saving */
                                if (de_devp->vpu_clkb) {
                                        clk_set_rate(de_devp->vpu_clkb,
                                                de_devp->clkb_min_rate);
                                }
+                               #endif
                        }
                        if (di_pre_stru.reg_req_flag_irq ||
                                di_pre_stru.reg_req_flag) {
@@ -6555,7 +6738,7 @@ static int di_task_handle(void *data)
                                }
                        }
                        if (is_meson_g12a_cpu() || is_meson_g12b_cpu()
-                               || is_meson_tl1_cpu() ||
+                               || is_meson_tl1_cpu() || is_meson_tm2_cpu() ||
                                is_meson_sm1_cpu()) {
                                #ifdef CLK_TREE_SUPPORT
                                clk_set_rate(de_devp->vpu_clkb,
@@ -6619,20 +6802,25 @@ static int di_receiver_event_fun(int type, void *data, void *arg)
 {
        int i;
        ulong flags;
+       char *provider_name = (char *)data;
 
        if (type == VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR) {
                return di_pre_stru.vdin2nr;
        } else if (type == VFRAME_EVENT_PROVIDER_UNREG) {
+               mutex_lock(&di_event_mutex);
                pr_dbg("%s , is_bypass() %d trick_mode %d bypass_all %d\n",
                        __func__, is_bypass(NULL), trick_mode, bypass_all);
-               pr_info("%s: vf_notify_receiver unreg\n", __func__);
+               di_pre_stru.vdin_source = false;
+               pr_info("DI: %s: unreg\n", __func__);
+               pr_info("DI: provider name:%s\n", provider_name);
 
                di_pre_stru.unreg_req_flag = 1;
                di_pre_stru.vdin_source = false;
                trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_UNREG);
                di_pre_stru.unreg_req_flag_cnt = 0;
-               while (di_pre_stru.unreg_req_flag) {
-                       usleep_range(10000, 10001);
+               while (di_pre_stru.unreg_req_flag ||
+                       di_pre_stru.reg_irq_busy) {
+                       usleep_range(1000, 1001);
                        if (di_pre_stru.unreg_req_flag_cnt++ >
                                di_reg_unreg_cnt) {
                                reg_unreg_timeout_cnt++;
@@ -6659,6 +6847,8 @@ static int di_receiver_event_fun(int type, void *data, void *arg)
                if (di_pre_stru.vdin_source)
                        DI_Wr_reg_bits(VDIN_WR_CTRL, 0x3, 24, 3);
 #endif
+               mutex_unlock(&di_event_mutex);
+               pr_info("DI: unreg f\n");
        } else if (type == VFRAME_EVENT_PROVIDER_RESET) {
                di_blocking = 1;
 
@@ -6819,14 +7009,17 @@ light_unreg:
                }
 #endif
        } else if (type == VFRAME_EVENT_PROVIDER_REG) {
-               char *provider_name = (char *)data;
                char *receiver_name = NULL;
+
+               mutex_lock(&di_event_mutex);
                if (de_devp->flags & DI_SUSPEND_FLAG) {
                        pr_err("[DI] reg event device hasn't resumed\n");
+                       mutex_unlock(&di_event_mutex);
                        return -1;
                }
                if (reg_flag) {
                        pr_err("[DI] no muti instance.\n");
+                       mutex_unlock(&di_event_mutex);
                        return -1;
                }
                pr_info("%s: vframe provider reg %s\n", __func__,
@@ -6834,11 +7027,11 @@ light_unreg:
 
                bypass_state = 0;
                di_pre_stru.reg_req_flag = 1;
-
                trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_REG);
+               /*check unreg process*/
                di_pre_stru.reg_req_flag_cnt = 0;
                while (di_pre_stru.reg_req_flag) {
-                       usleep_range(10000, 10001);
+                       usleep_range(1000, 1001);
                        if (di_pre_stru.reg_req_flag_cnt++ > di_reg_unreg_cnt) {
                                reg_unreg_timeout_cnt++;
                                pr_dbg("%s:reg_req_flag timeout!!!\n",
@@ -6866,6 +7059,8 @@ light_unreg:
                } else {
                        pr_info("%s error receiver is null.\n", __func__);
                }
+               mutex_unlock(&di_event_mutex);
+               pr_info("DI: reg f\n");
        }
 #ifdef DET3D
        else if (type == VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE) {
@@ -6884,7 +7079,7 @@ light_unreg:
 
        return 0;
 }
-
+#if 0
 static void fast_process(void)
 {
        int i;
@@ -6941,7 +7136,7 @@ static void fast_process(void)
                }
        }
 }
-
+#endif
 static vframe_t *di_vf_peek(void *arg)
 {
        vframe_t *vframe_ret = NULL;
@@ -6959,7 +7154,7 @@ static vframe_t *di_vf_peek(void *arg)
 
        log_buffer_state("pek");
 
-       fast_process();
+       /*fast_process();*/
 #ifdef SUPPORT_START_FRAME_HOLD
        if ((disp_frame_count == 0) && (is_bypass(NULL) == 0)) {
                int ready_count = list_count(QUEUE_POST_READY);
@@ -7504,7 +7699,7 @@ static void set_di_flag(void)
                is_meson_txhd_cpu() ||
                is_meson_g12a_cpu() ||
                is_meson_g12b_cpu() ||
-               is_meson_tl1_cpu() ||
+               is_meson_tl1_cpu() || is_meson_tm2_cpu() ||
                is_meson_sm1_cpu()) {
                mcpre_en = true;
                mc_mem_alloc = true;
@@ -7523,7 +7718,7 @@ static void set_di_flag(void)
                        is_meson_txhd_cpu() ||
                        is_meson_g12a_cpu() ||
                        is_meson_g12b_cpu() ||
-                       is_meson_tl1_cpu() ||
+                       is_meson_tl1_cpu() || is_meson_tm2_cpu() ||
                        is_meson_sm1_cpu()) {
                        full_422_pack = true;
                }
@@ -7536,7 +7731,7 @@ static void set_di_flag(void)
                }
                post_hold_line =
                        (is_meson_g12a_cpu() || is_meson_g12b_cpu()
-                               || is_meson_tl1_cpu() ||
+                               || is_meson_tl1_cpu() || is_meson_tm2_cpu() ||
                                is_meson_sm1_cpu())?10:17;
        } else {
                post_hold_line = 8;     /*2019-01-10: from VLSI feijun*/
@@ -7547,6 +7742,8 @@ static void set_di_flag(void)
                use_2_interlace_buff = 0;
                di_force_bit_mode = 8;
        }
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu())
+               pulldown_enable = true;
        if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
                intr_mode = 3;
        if (di_pre_rdma_enable) {
@@ -7651,6 +7848,8 @@ static int di_probe(struct platform_device *pdev)
                "nrds-enable", &(di_devp->nrds_enable));
        ret = of_property_read_u32(pdev->dev.of_node,
                "pps-enable", &(di_devp->pps_enable));
+       /*di pre h scaling down :sm1 tm2*/
+       di_devp->h_sc_down_en = pre_hsc_down_en;
 
        if (di_devp->flag_cma >= 1) {
 #ifdef CONFIG_CMA
@@ -7741,6 +7940,7 @@ static int di_probe(struct platform_device *pdev)
        device_create_file(di_devp->dev, &dev_attr_secam);
        pd_device_files_add(di_devp->dev);
        nr_drv_init(di_devp->dev);
+       mutex_init(&di_event_mutex);
 
        init_flag = 0;
        reg_flag = 0;
index 944aca2..5fa47f5 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,
@@ -237,6 +247,7 @@ struct di_dev_s {
        unsigned int       post_wr_support;
        unsigned int nrds_enable;
        unsigned int pps_enable;
+       u32 h_sc_down_en;/*sm1, tm2 ...*/
        /*struct        mutex      cma_mutex;*/
        unsigned int       flag_cma;
        struct page                     *total_pages;
@@ -289,6 +300,7 @@ struct di_pre_stru_s {
        int     reg_req_flag;
        int     reg_req_flag_irq;
        int     reg_req_flag_cnt;
+       int     reg_irq_busy;
        int     force_unreg_req_flag;
        int     disable_req_flag;
        /* current source info */
index 603ddf6..f28e869 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>
@@ -254,7 +255,7 @@ void dump_di_reg_g12(void)
                is_meson_txhd_cpu() ||
                is_meson_g12a_cpu() ||
                is_meson_g12b_cpu() ||
-               is_meson_tl1_cpu() ||
+               is_meson_tl1_cpu() || is_meson_tm2_cpu() ||
                is_meson_sm1_cpu())
                base_addr = 0xff900000;
        else
@@ -631,7 +632,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));
@@ -1046,6 +1049,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 70fd827..81e613f 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);
@@ -470,7 +472,8 @@ void di_hw_init(bool pd_enable, bool mc_enable)
        switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON);
        if (is_meson_txlx_cpu() || is_meson_txhd_cpu()
                || is_meson_g12a_cpu() || is_meson_g12b_cpu()
-               || is_meson_tl1_cpu() || is_meson_sm1_cpu())
+               || is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+               is_meson_tm2_cpu())
                di_top_gate_control(true, true);
        else if (is_meson_gxl_cpu()     || is_meson_gxm_cpu()
                || is_meson_gxlx_cpu())
@@ -484,7 +487,7 @@ void di_hw_init(bool pd_enable, bool mc_enable)
                is_meson_txhd_cpu() ||
                is_meson_g12a_cpu() ||
                is_meson_g12b_cpu() || is_meson_sm1_cpu() ||
-               is_meson_tl1_cpu()) {
+               is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
                /* vpp fifo max size on txl :128*3=384[0x180] */
                /* di fifo max size on txl :96*3=288[0x120] */
                fifo_size_vpp = 0x180;
@@ -520,7 +523,7 @@ void di_hw_init(bool pd_enable, bool mc_enable)
                is_meson_txhd_cpu() ||
                is_meson_g12a_cpu() ||
                is_meson_g12b_cpu() || is_meson_sm1_cpu() ||
-               is_meson_tl1_cpu()) {
+               is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
                di_pre_gate_control(true, true);
                di_post_gate_control(true);
        }
@@ -539,7 +542,7 @@ void di_hw_init(bool pd_enable, bool mc_enable)
                is_meson_txhd_cpu() ||
                is_meson_g12a_cpu() || is_meson_sm1_cpu() ||
                is_meson_g12b_cpu() ||
-               is_meson_tl1_cpu()) {
+               is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
                di_pre_gate_control(false, true);
                di_post_gate_control(false);
                di_top_gate_control(false, false);
@@ -820,6 +823,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() || is_meson_tm2_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() || is_meson_tm2_cpu())
+               ret = true;
+
+       return ret;
+
+}
+
 /*
  * after g12a, framereset will not reset simple
  * wr mif of pre such as mtn&cont&mv&mcinfo wr
@@ -904,163 +997,103 @@ 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;
-
-
-       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;
-
-}
-
-#define AFBC_DEC_SEL   (eAFBC_DEC1)
-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);
-       RDMA_WR(reg[eAFBC_CONV_CTRL], 0x100);
+
+       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+
+        */
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
+               if (vf->type & VIDTYPE_VIU_444)
+                       r |= (0 << 12);
+               else if (vf->type & VIDTYPE_VIU_422)
+                       r |= (1 << 12);
+               else
+                       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 */
@@ -1069,25 +1102,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;
 }
+#if 0
 static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on)     /*g12a*/
 {
        unsigned int reg_ctrl;
@@ -1102,22 +1156,23 @@ static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on)      /*g12a*/
                RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8);
 
 }
+#endif
 static void afbcx_sw(bool on)  /*g12a*/
 {
        unsigned int tmp;
        unsigned int mask;
        unsigned int reg_ctrl, reg_en;
        enum eAFBC_DEC dec_sel;
+       const unsigned int *reg = afbc_get_regbase();
 
        dec_sel = afbc_get_decnub();
 
        if (dec_sel == eAFBC_DEC0) {
                reg_ctrl = VD1_AFBCD0_MISC_CTRL;
-               reg_en = AFBC_ENABLE;
        } else {
                reg_ctrl = VD2_AFBCD1_MISC_CTRL;
-               reg_en = VD2_AFBC_ENABLE;
        }
+       reg_en = reg[eAFBC_ENABLE];
 
        mask = (3<<20)  | (1<<12) | (1<<9);
        /*clear*/
@@ -1129,36 +1184,30 @@ 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() || is_meson_tm2_cpu())
+                       RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 1, 22, 1);
        } else {
                RDMA_WR(reg_ctrl, tmp);
                RDMA_WR(reg_en, 0x1600);
                RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1);
+               if (is_meson_tl1_cpu() || is_meson_tm2_cpu())
+                       RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 0, 22, 1);
        }
-//     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*/
 {
        enum eAFBC_DEC dec_sel;
        unsigned int reg_en;
+       const unsigned int *reg = afbc_get_regbase();
 
        dec_sel = afbc_get_decnub();
-
-       if (dec_sel == eAFBC_DEC0) {
-               //reg_ctrl = VD1_AFBCD0_MISC_CTRL;
-               reg_en = AFBC_ENABLE;
-       } else {
-               //reg_ctrl = VD2_AFBCD1_MISC_CTRL;
-               reg_en = VD2_AFBC_ENABLE;
-       }
-
+       reg_en = reg[eAFBC_ENABLE];
 
        if (on) {
                /* DI inp(current data) switch to AFBC */
@@ -1179,26 +1228,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)
@@ -1206,6 +1249,7 @@ static void afbc_power_sw(bool on)
        /*afbc*/
        enum eAFBC_DEC dec_sel;
        unsigned int vpu_sel;
+       unsigned int reg_ctrl;
 
        dec_sel = afbc_get_decnub();
        if (dec_sel == eAFBC_DEC0)
@@ -1216,15 +1260,30 @@ 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)) {
+               if (dec_sel == eAFBC_DEC0)
+                       reg_ctrl = VD1_AFBCD0_MISC_CTRL;
+               else
+                       reg_ctrl = VD2_AFBCD1_MISC_CTRL;
+               if (on)
+                       RDMA_WR_BITS(reg_ctrl, 0, 0, 8);
+               else
+                       RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8);
+       }
+               /*afbcx_power_sw(dec_sel, on);*/
+}
 
-       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
-               afbcx_power_sw(dec_sel, on);
-
+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);
 }
-static int afbc_reg_unreg_flag;
+
 void afbc_reg_sw(bool on)
 {
-
        if (!afbc_is_supported())
                return;
 
@@ -1233,25 +1292,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;
@@ -3603,7 +3655,7 @@ static void di_pre_data_mif_ctrl(bool enable)
                        afbc_input_sw(true);
                } else {
                        DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1);
-                       afbc_input_sw(false);
+                       /*afbc_input_sw(false);*/
                }
                #endif
                /* nrwr no clk gate en=0 */
@@ -3622,9 +3674,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..d85c8b3 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,8 +208,11 @@ 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 int afbc_reg_unreg_flag;
 
 extern u8 *di_vmap(ulong addr, u32 size, bool *bflg);
 extern void di_unmap_phyaddr(u8 *vaddr);
index 7a912ed..81e0036 100644 (file)
@@ -297,7 +297,7 @@ struct combing_status_s *adpative_combing_config(unsigned int width,
 }
 void mtn_int_combing_glbmot(void)
 {
-       if (is_meson_tl1_cpu()) {/*from VLSI yanling.liu*/
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {/*from VLSI yanling.liu*/
                combing_glbmot_radprat[0] = 30;
        }
 }
@@ -629,6 +629,24 @@ static int di_debug_readreg;
 module_param(di_debug_readreg, int, 0644);
 MODULE_PARM_DESC(di_debug_readreg, "di_debug_readreg");
 
+/*from VLSI yanling.liu, the patch fix TL1 1080I in some dark */
+/*scenes and roller coasters have small sawtooth, when turn off*/
+/*combing_fix_en, set the registers*/
+void fix_tl1_1080i_sawtooth_patch(void)
+{
+       DI_Wr(0x1741, 0x0A0A1A22);
+       DI_Wr(0x1742, 0x0a100101);
+       DI_Wr(0x1743, 0x01020420);
+       DI_Wr(0x1744, 0x32210404);
+       DI_Wr(0x17a9, 0x0a100505);
+       DI_Wr(0x17aa, 0x04040101);
+       DI_Wr(0x17ab, 0x0a0a0a0a);
+       DI_Wr(0x17ac, 0x0f100101);
+       DI_Wr(0x17ad, 0x04040606);
+       DI_Wr(0x17ae, 0x02030202);
+       DI_Wr(0x17af, 0x60020a60);
+}
+
 static int combing_cnt;
 int combing_diff_min = 2000;
 int combing_diff_max = 2000;
index 206d1c3..13cc468 100644 (file)
@@ -39,6 +39,7 @@ struct combing_status_s *adpative_combing_config(unsigned int width,
        unsigned int height,
        enum vframe_source_type_e src_type, bool prog,
        enum tvin_sig_fmt_e fmt);
+extern void fix_tl1_1080i_sawtooth_patch(void);
 int adaptive_combing_fixing(
        struct combing_status_s *cmb_status,
        unsigned int field_diff, unsigned int frame_diff,
index 750be01..3025554 100644 (file)
@@ -388,10 +388,12 @@ static void f2v_get_vertical_phase(unsigned int zoom_ratio,
                vphase->phase = (offset_out - offset_in) >> 2;
        }
 }
+
 /*
  * patch 1: inp scaler 0: di wr scaler
+ * support: TM2
+ * not support: SM1
  */
-
 void di_pps_config(unsigned char path, int src_w, int src_h,
        int dst_w, int dst_h)
 {
@@ -1325,3 +1327,61 @@ RESTART:
 }
 #endif
 
+/*
+ * di pre h scaling down function
+ * only have h scaling down
+ * support: sm1 tm2 ...
+ * 0x37b0 ~ 0x37b5
+ */
+void di_inp_hsc_setting(uint32_t src_w, uint32_t dst_w)
+{
+       uint32_t  i;
+       uint32_t  hsc_en;
+       uint32_t horz_phase_step;
+       int *filt_coef0 = di_filt_coef0;
+       /*int *filt_coef1 = di_filt_coef1;*/
+       /*int *filt_coef2 = di_filt_coef2;*/
+
+       if (src_w == dst_w) {
+               hsc_en = 0;
+       } else {
+               hsc_en = 1;
+               /*write horz filter coefs*/
+               RDMA_WR(DI_VIU_HSC_COEF_IDX, 0x0100);
+               for (i = 0; i < 33; i++)
+                       RDMA_WR(DI_VIU_HSC_COEF, filt_coef0[i]); /*bicubic*/
+
+               horz_phase_step = (src_w << 20) / dst_w;
+               horz_phase_step = (horz_phase_step << 4);
+               RDMA_WR(DI_VIU_HSC_WIDTHM1, (src_w-1)<<16 | (dst_w-1));
+               RDMA_WR(DI_VIU_HSC_PHASE_STEP, horz_phase_step);
+               RDMA_WR(DI_VIU_HSC_PHASE_CTRL, 0);
+       }
+       RDMA_WR(DI_VIU_HSC_CTRL,
+               (4 << 20) |             /* initial receive number*/
+               (0 << 12) |             /* initial pixel ptr*/
+               (1 << 10) |             /* repeat first pixel number*/
+               (0 << 8) |              /* sp422 mode*/
+               (4 << 4) |      /* horz scaler bank length*/
+               (0 << 2) |      /* phase0 always en*/
+               (0 << 1) |      /* nearest_en*/
+               (hsc_en<<0));   /* hsc_en*/
+}
+
+/*
+ * 0x37b0 ~ 0x37b5
+ */
+void dump_hdownscler_reg(unsigned int base_addr)
+{
+       unsigned int i = 0x374e;
+
+       pr_info("-----dump hdownscler start-----\n");
+       for (i = 0x37b0; i < 0x37b5; i++) {
+               pr_info("[0x%x][0x%x]=0x%x\n",
+                       base_addr + (i << 2),
+                       i, RDMA_RD(i));
+       }
+       pr_info("-----dump hdownscler end-----\n");
+}
+
+
index 9ec789e..a607364 100644 (file)
@@ -54,6 +54,12 @@ enum f2v_vphase_type_e {
        F2V_TYPE_MAX
 }; /* frame to video conversion type */
 #endif
+
+enum hdr2_scaler_e {
+       hdr2_scaler_postdi = 0,
+       hdr2_scaler_predi = 1,
+};
+
 struct pps_f2v_vphase_s {
        unsigned char rcv_num;
        unsigned char rpt_num;
@@ -99,4 +105,7 @@ struct pps_frame_par_s {
 void di_pps_config(unsigned char path, int src_w, int src_h,
        int dst_w, int dst_h);
 void dump_pps_reg(unsigned int base_addr);
+void di_inp_hsc_setting(uint32_t src_w, uint32_t dst_w);
+void dump_hdownscler_reg(unsigned int base_addr);
+
 #endif
index 509117b..b251137 100644 (file)
@@ -280,7 +280,10 @@ static void dnr_config(struct DNR_PARM_s *dnr_parm_p,
        DI_Wr(DNR_DM_CTRL, Rd(DNR_DM_CTRL)|(1 << 11));
        DI_Wr_reg_bits(DNR_CTRL, dnr_en?1:0, 16, 1);
        /* dm for sd, hd will slower */
-       DI_Wr(DNR_CTRL, 0x1df00);
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu())
+               DI_Wr(DNR_CTRL, 0x1df00 | (0x03 << 18)); //5 line
+       else
+               DI_Wr(DNR_CTRL, 0x1df00);
        if (is_meson_gxlx_cpu()) {
                /* disable chroma dm according to baozheng */
                DI_Wr_reg_bits(DNR_DM_CTRL, 0, 8, 1);
@@ -354,7 +357,7 @@ static void nr2_config(unsigned short width, unsigned short height)
 {
        if (is_meson_txlx_cpu() || is_meson_g12a_cpu() ||
                is_meson_g12b_cpu() || is_meson_tl1_cpu() ||
-               is_meson_sm1_cpu()) {
+               is_meson_sm1_cpu() || is_meson_tm2_cpu()) {
                DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 2, 1);
                DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 15, 1);
                DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 17, 1);
@@ -404,7 +407,7 @@ void nr_all_config(unsigned short width, unsigned short height,
                cue_config(nr_param.pcue_parm, field_type);
        if (is_meson_txlx_cpu() || is_meson_g12a_cpu() ||
                is_meson_g12b_cpu() || is_meson_tl1_cpu() ||
-               is_meson_sm1_cpu()) {
+               is_meson_sm1_cpu() || is_meson_tm2_cpu()) {
                linebuffer_config(width);
                nr4_config(nr_param.pnr4_parm, width, height);
        }
@@ -596,7 +599,7 @@ static void dnr_process(struct DNR_PARM_s *pDnrPrm)
 #endif
        int ll, lr;
 
-       if (is_meson_tl1_cpu()) {
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
                ll = Rd(DNR_RO_GBS_STAT_LR);
                lr = Rd(DNR_RO_GBS_STAT_LL);
        } else {
@@ -742,6 +745,16 @@ module_param_named(glb_fieldck_en, glb_fieldck_en, bool, 0644);
 void adaptive_cue_adjust(unsigned int frame_diff, unsigned int field_diff)
 {
        struct CUE_PARM_s *pcue_parm = nr_param.pcue_parm;
+       unsigned int mask1, mask2;
+
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
+               /*value from VLSI(yanling.liu) 2018-12-07: */
+               mask1 = 0x50332;
+               mask2 = 0x00054357;
+       } else { /*ori value*/
+               mask1 = 0x50323;
+               mask2 = 0x00054375;
+       }
 
        if (frame_diff > pcue_parm->glb_mot_framethr) {
                pcue_parm->frame_count = pcue_parm->frame_count > 0 ?
@@ -827,7 +840,7 @@ void nr_process_in_irq(void)
                dnr_process(&dnr_param);
        if (is_meson_txlx_cpu() || is_meson_g12a_cpu()
                || is_meson_g12a_cpu() || is_meson_tl1_cpu() ||
-               is_meson_sm1_cpu()) {
+               is_meson_sm1_cpu() || is_meson_tm2_cpu()) {
                noise_meter_process(nr_param.pnr4_parm, nr_param.frame_count);
                luma_enhancement_process(nr_param.pnr4_parm,
                                nr_param.frame_count);
@@ -1064,19 +1077,11 @@ static void nr4_param_init(struct NR4_PARM_s *nr4_parm_p)
        nr4_parm_p->sw_nr4_sad2gain_lut[14] = 14;
        nr4_parm_p->sw_nr4_sad2gain_lut[15] = 9;
 
-       if (is_meson_tl1_cpu()) {
-               nr4_parm_p->sw_nr4_noise_thd = 32;
-               nr4_parm_p->sw_nr4_noise_sel = 0;
-               nr4_parm_p->sw_nr4_noise_ctrl_dm_en = 0;
-               nr4_parm_p->sw_nr4_scene_change_thd2 = 80;
-               nr4_parm_p->sw_dm_scene_change_en = 0;
-       } else {
-               nr4_parm_p->sw_nr4_noise_thd = 32;
-               nr4_parm_p->sw_nr4_noise_sel = 0;
-               nr4_parm_p->sw_nr4_noise_ctrl_dm_en = 0;
-               nr4_parm_p->sw_nr4_scene_change_thd2 = 80;
-               nr4_parm_p->sw_dm_scene_change_en = 0;
-       }
+       nr4_parm_p->sw_nr4_noise_thd = 32;
+       nr4_parm_p->sw_nr4_noise_sel = 0;
+       nr4_parm_p->sw_nr4_noise_ctrl_dm_en = 0;
+       nr4_parm_p->sw_nr4_scene_change_thd2 = 80;
+       nr4_parm_p->sw_dm_scene_change_en = 0;
 }
 
 static void cue_param_init(struct CUE_PARM_s *cue_parm_p)
@@ -1187,7 +1192,10 @@ void nr_hw_init(void)
 {
 
        nr_gate_control(true);
-       DI_Wr(DNR_CTRL, 0x1df00);
+       if (is_meson_tl1_cpu() || is_meson_tm2_cpu())
+               DI_Wr(DNR_CTRL, 0x1df00|(0x03<<18));//5 line
+       else
+               DI_Wr(DNR_CTRL, 0x1df00);
        DI_Wr(NR3_MODE, 0x3);
        DI_Wr(NR3_COOP_PARA, 0x28ff00);
        DI_Wr(NR3_CNOOP_GAIN, 0x881900);
@@ -1201,7 +1209,7 @@ void nr_gate_control(bool gate)
 {
        if (!is_meson_txlx_cpu() && !is_meson_g12a_cpu()
                && !is_meson_g12b_cpu() && !is_meson_sm1_cpu()
-               && !is_meson_tl1_cpu())
+               && !is_meson_tl1_cpu() && !is_meson_tm2_cpu())
                return;
        if (gate) {
                /* enable nr auto gate */
index 5ce602d..5d8a36a 100644 (file)
@@ -212,6 +212,15 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr,
 #define DI_HSC_INI_PAT_CTRL                            0x376b
 #define DI_SC_GCLK_CTRL                                        0x376c
 #define DI_SC_HOLD_LINE                                        0x376d
+
+/* DI H DOWN SCALER */
+#define DI_VIU_HSC_WIDTHM1                             0x37b0
+#define DI_VIU_HSC_PHASE_STEP                          0x37b1
+#define DI_VIU_HSC_CTRL                                        0x37b2
+#define DI_VIU_HSC_PHASE_CTRL                          0x37b3
+#define DI_VIU_HSC_COEF                                        0x37b4
+#define DI_VIU_HSC_COEF_IDX                            0x37b5
+
 /* NR DOWNSAMPLE */
 #define NRDSWR_X                                               0x37f9
 #define NRDSWR_Y                                               0x37fa
index 61ecf76..b2b3c24 100644 (file)
@@ -548,6 +548,7 @@ const char video_dev_id2[] = "amvideo-dev2";
 int onwaitendframe;
 
 static u32 vpp_hold_line = 8;
+static u32 stop_update;
 
 struct video_dev_s video_dev[2] = {
        {0x1d00 - 0x1d00, 0x1a50 - 0x1a50},
@@ -4069,6 +4070,8 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line)
 #endif
                }
        }
+       if (stop_update)
+               frame_par_ready_to_set = 0;
        ATRACE_COUNTER(__func__,  0);
 }
 
@@ -7212,7 +7215,15 @@ SET_FILTER:
                        u32 zoom_start_y, zoom_end_y;
                        correct_vd1_mif_size_for_DV(cur_frame_par);
                        if (cur_dispbuf->type & VIDTYPE_INTERLACE) {
-                               if (cur_dispbuf->type & VIDTYPE_VIU_FIELD) {
+                               if (cur_dispbuf->type
+                                       & VIDTYPE_COMPRESS) {
+                                       /* for vdin afbc and interlace case */
+                                       zoom_start_y =
+                                       cur_frame_par->VPP_vd_start_lines_;
+                                       zoom_end_y =
+                                       cur_frame_par->VPP_vd_end_lines_;
+                               } else if (cur_dispbuf->type
+                                       & VIDTYPE_VIU_FIELD) {
                                        zoom_start_y =
                                        cur_frame_par->VPP_vd_start_lines_
                                        >> 1;
@@ -13061,6 +13072,9 @@ module_param(toggle_count, uint, 0664);
 MODULE_PARM_DESC(vpp_hold_line, "\n vpp_hold_line\n");
 module_param(vpp_hold_line, uint, 0664);
 
+MODULE_PARM_DESC(stop_update, "\n stop_update\n");
+module_param(stop_update, uint, 0664);
+
 MODULE_PARM_DESC(reference_zorder, "\n reference_zorder\n");
 module_param(reference_zorder, uint, 0664);
 
index a1d1ac0..734364c 100644 (file)
@@ -2976,7 +2976,10 @@ int vpp_set_filters(
        aspect_ratio = (vf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK)
                                   >> DISP_RATIO_ASPECT_RATIO_BIT;
 
-       if (vf->type & VIDTYPE_INTERLACE)
+       /* the height from vdin afbc will be half */
+       /* so need no interlace in */
+       if ((vf->type & VIDTYPE_INTERLACE)
+               && !(vf->type & VIDTYPE_COMPRESS))
                vpp_flags = VPP_FLAG_INTERLACE_IN;
 
        if (vf->ratio_control & DISP_RATIO_PORTRAIT_MODE)