vdin: optimize game mode process [1/1]
authorDezhi Kong <dezhi.kong@amlogic.com>
Mon, 12 Nov 2018 10:00:29 +0000 (18:00 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 10 Dec 2018 14:16:01 +0000 (06:16 -0800)
PD#SWPL-2145

Problem:
HDMI Rx Video path display latency of Game mode and Normal mode

Solution:
optimize game mode

Verify:
T962X-R311

Change-Id: Ib0a41915dfb088495c976d56ab812f90e31602f4
Signed-off-by: Dezhi Kong <dezhi.kong@amlogic.com>
drivers/amlogic/media/vin/tvin/vdin/Makefile
drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h

index 7f0c556..b8092e9 100644 (file)
@@ -1,6 +1,11 @@
 #
 # Makefile for Vdin.
 #
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+ccflags-y := -DDEBUG_SUPPORT
+else
+ccflags-y := -DDEBUG
+endif
 obj-$(CONFIG_AMLOGIC_MEDIA_VDIN) = tvin_vdin.o
 tvin_vdin-objs += vdin_v4l2.o
 tvin_vdin-objs += vdin_vf.o
index cf16fb1..0a1a5a0 100644 (file)
@@ -745,7 +745,7 @@ static void vdin_dump_state(struct vdin_dev_s *devp)
        pr_info("vdin_irq_flag: %d, vdin_rest_flag: %d, irq_cnt: %d, rdma_irq_cnt: %d\n",
                devp->vdin_irq_flag, devp->vdin_reset_flag,
                devp->irq_cnt, devp->rdma_irq_cnt);
-       pr_info("rdma_enable :  %d\n", devp->rdma_enable);
+       pr_info("game_mode :  %d\n", devp->game_mode);
        pr_info("dolby_input :  %d\n", devp->dv.dolby_input);
        if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100))
                pr_info("dolby_mem_start = %ld, dolby_mem_size = %d\n",
index 1fe7dde..7047012 100644 (file)
@@ -87,6 +87,8 @@ static unsigned int use_reserved_mem;
 static int canvas_config_mode = 2;
 static bool work_mode_simple;
 static int max_ignore_frames = 2;
+/*game_mode_switch_frames:min num is 5 by 1080p60hz input test*/
+static int game_mode_switch_frames = 10;
 static int ignore_frames;
 static unsigned int dv_work_delby;
 /* viu isr select:
@@ -112,6 +114,9 @@ MODULE_PARM_DESC(dv_work_delby, "dv_work_delby");
 
 module_param(viu_hw_irq, bool, 0664);
 MODULE_PARM_DESC(viu_hw_irq, "viu_hw_irq");
+
+module_param(game_mode_switch_frames, int, 0664);
+MODULE_PARM_DESC(game_mode_switch_frames, "game mode switch <n> frames");
 #endif
 
 static bool vdin_dbg_en;
@@ -266,10 +271,20 @@ static void vdin_game_mode_check(struct vdin_dev_s *devp)
                (devp->parm.port != TVIN_PORT_CVBS3)) {
                if (devp->h_active > 720 && ((devp->parm.info.fps == 50) ||
                        (devp->parm.info.fps == 60)))
-                       devp->game_mode = 3;
+                       devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1 |
+                               VDIN_GAME_MODE_SWITCH_EN);
                else
-                       devp->game_mode = 1;
-       } else
+                       devp->game_mode = VDIN_GAME_MODE_0;
+       } else if (game_mode == 2)/*for debug force game mode*/
+               devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1);
+       else if (game_mode == 3)/*for debug force game mode*/
+               devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2);
+       else if (game_mode == 4)/*for debug force game mode*/
+               devp->game_mode = VDIN_GAME_MODE_0;
+       else if (game_mode == 5)/*for debug force game mode*/
+               devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1 |
+                       VDIN_GAME_MODE_SWITCH_EN);
+       else
                devp->game_mode = 0;
 }
 /*
@@ -383,10 +398,7 @@ static void vdin_rdma_irq(void *arg)
        return;
 }
 
-static struct rdma_op_s vdin_rdma_op = {
-       vdin_rdma_irq,
-       NULL
-};
+static struct rdma_op_s vdin_rdma_op[VDIN_MAX_DEVS];
 #endif
 
 /*
@@ -530,6 +542,7 @@ void vdin_start_dec(struct vdin_dev_s *devp)
        devp->abnormal_cnt = 0;
        devp->last_wr_vfe = NULL;
        irq_max_count = 0;
+       vdin_drop_cnt = 0;
        /* devp->stamp_valid = false; */
        devp->stamp = 0;
        devp->cycle = 0;
@@ -606,6 +619,7 @@ void vdin_start_dec(struct vdin_dev_s *devp)
 #endif
        devp->irq_cnt = 0;
        devp->rdma_irq_cnt = 0;
+       devp->frame_cnt = 0;
        if (time_en)
                pr_info("vdin.%d start time: %ums, run time:%ums.\n",
                                devp->index, jiffies_to_msecs(jiffies),
@@ -1258,7 +1272,8 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
                goto irq_handled;
        }
        if (devp->last_wr_vfe && (devp->flags&VDIN_FLAG_RDMA_ENABLE) &&
-               !(devp->game_mode & (1 << 1))) {
+               !(devp->game_mode & VDIN_GAME_MODE_1) &&
+               !(devp->game_mode & VDIN_GAME_MODE_2)) {
                /*dolby vision metadata process*/
                if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK
                        && devp->dv.dv_config) {
@@ -1450,8 +1465,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
        /*if vdin-nr,di must get
         * vdin current field type which di pre will read
         */
-       if ((vdin2nr || (devp->flags & VDIN_FLAG_RDMA_ENABLE)) &&
-               !(devp->game_mode & (1 << 1)))
+       if (vdin2nr || (devp->flags & VDIN_FLAG_RDMA_ENABLE))
                curr_wr_vf->type = devp->curr_field_type;
        else
                curr_wr_vf->type = last_field_type;
@@ -1507,9 +1521,9 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
                (devp->parm.port <= TVIN_PORT_CVBS3))
                vdin_set_display_ratio(devp, curr_wr_vf);
        if ((devp->flags&VDIN_FLAG_RDMA_ENABLE) &&
-               !(devp->game_mode & (1 << 1))) {
+               !(devp->game_mode & VDIN_GAME_MODE_1)) {
                devp->last_wr_vfe = curr_wr_vfe;
-       } else {
+       } else if (!(devp->game_mode & VDIN_GAME_MODE_2)) {
                /*dolby vision metadata process*/
                if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK
                        && devp->dv.dv_config) {
@@ -1543,6 +1557,14 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
                if (devp->vfp->skip_vf_num > 0)
                        vdin_vf_disp_mode_update(curr_wr_vfe, devp->vfp);
        }
+       /*switch to game mode 2 from game mode 1,otherwise may appear blink*/
+       if ((devp->frame_cnt >= game_mode_switch_frames) &&
+               (devp->game_mode & VDIN_GAME_MODE_SWITCH_EN)) {
+               if (vdin_dbg_en)
+                       pr_info("switch game mode (%d-->5)\n", devp->game_mode);
+               devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2);
+       }
+
        /* prepare for next input data */
        next_wr_vfe = provider_vf_get(devp->vfp);
        if (devp->afbce_mode == 0) {
@@ -1566,7 +1588,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
        next_wr_vfe->vf.ready_clock[0] = sched_clock();
 
        if (!(devp->flags&VDIN_FLAG_RDMA_ENABLE) ||
-               (devp->game_mode & (1 << 1))) {
+               (devp->game_mode & VDIN_GAME_MODE_1)) {
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
                if (((devp->dv.dolby_input & (1 << devp->index)) ||
                        (devp->dv.dv_flag && is_dolby_vision_enable())) &&
@@ -1577,7 +1599,18 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
 #endif
                        vf_notify_receiver(devp->name,
                                VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+       } else if (devp->game_mode & VDIN_GAME_MODE_2) {
+               provider_vf_put(next_wr_vfe, devp->vfp);
+               vf_notify_receiver(devp->name,
+                       VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+               if (vdin_dbg_en) {
+                       next_wr_vfe->vf.ready_clock[1] = sched_clock();
+                       pr_info("vdin put latency %lld us. first %lld us.\n",
+                               func_div(next_wr_vfe->vf.ready_clock[1], 1000),
+                               func_div(next_wr_vfe->vf.ready_clock[0], 1000));
+               }
        }
+       devp->frame_cnt++;
 
 irq_handled:
        /*hdmi skip policy should adapt to all drop vframe case*/
@@ -2434,8 +2467,9 @@ static int vdin_drv_probe(struct platform_device *pdev)
        }
        vdin_devp[vdevp->index] = vdevp;
 #ifdef CONFIG_AMLOGIC_MEDIA_RDMA
-       vdin_rdma_op.arg = vdin_devp;
-       vdevp->rdma_handle = rdma_register(&vdin_rdma_op,
+       vdin_rdma_op[vdevp->index].irq_cb = vdin_rdma_irq;
+       vdin_rdma_op[vdevp->index].arg = vdevp;
+       vdevp->rdma_handle = rdma_register(&vdin_rdma_op[vdevp->index],
                                NULL, RDMA_TABLE_SIZE);
        pr_info("%s:vdin.%d rdma hanld %d.\n", __func__, vdevp->index,
                        vdevp->rdma_handle);
index 6067055..ea7a9f6 100644 (file)
@@ -45,7 +45,7 @@
 #include "vdin_vf.h"
 #include "vdin_regs.h"
 
-#define VDIN_VER "Ref.2018/11/07a"
+#define VDIN_VER "Ref.2018/11/21a"
 
 /*the counter of vdin*/
 #define VDIN_MAX_DEVS                  2
 #define VDIN_BYPASS_VGA_CHECK           0x00000008
 #define VDIN_CANVAS_MAX_CNT                            9
 
+/*values of vdin game mode process flag */
+#define VDIN_GAME_MODE_0                (1 << 0)
+#define VDIN_GAME_MODE_1                (1 << 1)
+#define VDIN_GAME_MODE_2                (1 << 2)
+#define VDIN_GAME_MODE_SWITCH_EN        (1 << 3)
+
 /*flag for flush vdin buff*/
 #define VDIN_FLAG_BLACK_SCREEN_ON      1
 #define VDIN_FLAG_BLACK_SCREEN_OFF     0
@@ -312,6 +318,8 @@ struct vdin_dev_s {
         *game_mode:
         *bit0:enable/disable
         *bit1:for true bypas and put vframe in advance one vsync
+        *bit2:for true bypas and put vframe in advance two vsync,
+        *vdin & vpp read/write same buffer may happen
         */
        unsigned int game_mode;
        unsigned int rdma_enable;
@@ -331,6 +339,7 @@ struct vdin_dev_s {
        /*use frame rate to cal duraton*/
        unsigned int use_frame_rate;
        unsigned int irq_cnt;
+       unsigned int frame_cnt;
        unsigned int rdma_irq_cnt;
        unsigned int vdin_irq_flag;
        unsigned int vdin_reset_flag;