From f938eedd95919e6c6d3cb1680abf9b7342c6e0e0 Mon Sep 17 00:00:00 2001 From: Dezhi Kong Date: Mon, 12 Nov 2018 18:00:29 +0800 Subject: [PATCH] vdin: optimize game mode process [1/1] 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 --- drivers/amlogic/media/vin/tvin/vdin/Makefile | 5 ++ drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c | 2 +- drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c | 64 ++++++++++++++++++------ drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h | 11 +++- 4 files changed, 65 insertions(+), 17 deletions(-) diff --git a/drivers/amlogic/media/vin/tvin/vdin/Makefile b/drivers/amlogic/media/vin/tvin/vdin/Makefile index 7f0c556..b8092e9 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/Makefile +++ b/drivers/amlogic/media/vin/tvin/vdin/Makefile @@ -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 diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c index cf16fb1..0a1a5a0 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c @@ -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", diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index 1fe7dde..7047012 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -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 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); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h index 6067055..ea7a9f6 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h @@ -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 @@ -85,6 +85,12 @@ #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; -- 2.7.4