From dc0d79e6fa2658f2dd99b52501479dece1fc5b48 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Fri, 5 Apr 2019 20:52:27 +0800 Subject: [PATCH] vdin: config vdin mif/afbc path directly [1/1] PD#SWPL-6277 Problem: switch hdmi port maybe display green screen Solution: 1.optimize vdin stop sequence, reduce afbc state polling interval, and rest afbc to get a clean state 2.change vdin mif/afbc patch directly, not rdma method, for vdin0/1 rdma are independent Verify: x301 Change-Id: I0ddf5d27dcfc0fd930eeb681f876c4c5e92e8d70 Signed-off-by: Evoke Zhang --- .../amlogic/media/vin/tvin/vdin/vdin_afbce.c | 32 +++++++----- .../amlogic/media/vin/tvin/vdin/vdin_afbce.h | 1 + .../amlogic/media/vin/tvin/vdin/vdin_drv.c | 50 +++++++++++-------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c index 35032f402671..f34179b1205e 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c @@ -363,6 +363,7 @@ void vdin_afbce_cma_release(struct vdin_dev_s *devp) devp->cma_mem_alloc = 0; } +/*can not use RDMA, because vdin0/1 both use the register */ void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, enum vdin_output_mif_e sel) { @@ -370,37 +371,37 @@ void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, if (offset == 0) { if (sel == VDIN_OUTPUT_TO_MIF) { - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_MIF_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_AFBCE_BIT, 1); } else if (sel == VDIN_OUTPUT_TO_AFBCE) { - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_MIF_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1); } } else { if (sel == VDIN_OUTPUT_TO_MIF) { - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_MIF_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_AFBCE_BIT, 1); } else if (sel == VDIN_OUTPUT_TO_AFBCE) { /*sel vdin1 afbce: not support in sw now, *just reserved interface */ - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_MIF_BIT, 1); - rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_AFBCE_BIT, 1); } } @@ -694,3 +695,10 @@ void vdin_afbce_hw_enable(struct vdin_dev_s *devp) //enable afbce rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1); } + +void vdin_afbce_soft_reset(void) +{ + W_VCBUS_BIT(AFBCE_MODE, 0, 30, 1); + W_VCBUS_BIT(AFBCE_MODE, 1, 30, 1); + W_VCBUS_BIT(AFBCE_MODE, 0, 30, 1); +} diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h index 9cc81e3a47f6..b2a6882eea2f 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h @@ -312,5 +312,6 @@ extern void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp); extern int vdin_afbce_read_writedown_flag(void); extern void vdin_afbce_hw_disable(void); extern void vdin_afbce_hw_enable(struct vdin_dev_s *devp); +extern void vdin_afbce_soft_reset(void); #endif diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index 758661dd8605..12850dc6ed96 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -79,7 +79,6 @@ static struct vdin_dev_s *vdin_devp[VDIN_MAX_DEVS]; static unsigned long mem_start, mem_end; static unsigned int use_reserved_mem; static int afbc_init_flag[VDIN_MAX_DEVS]; -static int afbc_write_down_flag[VDIN_MAX_DEVS]; static unsigned int pr_times; unsigned int tl1_vdin1_preview_flag; static unsigned int tl1_vdin1_data_readied; @@ -107,8 +106,8 @@ static int tl1_vdin1_preview_ready_flag; static unsigned int vdin_afbc_force_drop_frame = 1; static struct vf_entry *vfe_drop_force; -unsigned int vdin_afbc_preview_force_drop_frame_cnt = 1; -unsigned int vdin_afbc_force_drop_frame_cnt = 2; +unsigned int vdin_afbc_preview_force_drop_frame_cnt; +unsigned int vdin_afbc_force_drop_frame_cnt; unsigned int max_ignore_frame_cnt = 2; unsigned int skip_frame_debug; @@ -533,7 +532,6 @@ void vdin_start_dec(struct vdin_dev_s *devp) } #endif - afbc_write_down_flag[devp->index] = 0; /* h_active/v_active will be used by bellow calling */ if (devp->afbce_mode == 0) { if (canvas_config_mode == 1) @@ -682,7 +680,8 @@ void vdin_start_dec(struct vdin_dev_s *devp) */ void vdin_stop_dec(struct vdin_dev_s *devp) { - int afbc_write_down_test_times = 7; + int afbc_write_down_timeout = 500; /* 50ms to cover a 24Hz vsync */ + int i = 0; /* avoid null pointer oops */ if (!devp || !devp->frontend) @@ -693,16 +692,19 @@ void vdin_stop_dec(struct vdin_dev_s *devp) return; } #endif + disable_irq_nosync(devp->irq); afbc_init_flag[devp->index] = 0; if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) { - while (++afbc_write_down_flag[devp->index] < - afbc_write_down_test_times) { - if (vdin_afbce_read_writedown_flag() == 0) - usleep_range(5000, 5001); - else + while (i++ < afbc_write_down_timeout) { + if (vdin_afbce_read_writedown_flag()) break; + usleep_range(100, 105); + } + if (i >= afbc_write_down_timeout) { + pr_info("vdin.%d afbc write done timeout\n", + devp->index); } } if (is_meson_tl1_cpu() && (tl1_vdin1_preview_flag == 1)) { @@ -736,8 +738,10 @@ void vdin_stop_dec(struct vdin_dev_s *devp) vf_unreg_provider(&devp->vprov); devp->dv.dv_config = 0; - if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) + if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) { vdin_afbce_hw_disable(); + vdin_afbce_soft_reset(); + } #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION vdin_dolby_addr_release(devp, devp->vfp->size); @@ -1414,17 +1418,16 @@ irqreturn_t vdin_isr(int irq, void *dev_id) offset = devp->addr_offset; - if (afbc_init_flag[devp->index] == 0) { - afbc_init_flag[devp->index] = 1; - /*set mem power on*/ - if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) { + if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) { + if (afbc_init_flag[devp->index] == 0) { + afbc_init_flag[devp->index] = 1; + /*set mem power on*/ vdin_afbce_hw_enable(devp); return IRQ_HANDLED; - } - } else if (afbc_init_flag[devp->index] == 1) { - afbc_init_flag[devp->index] = 2; - if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) + } else if (afbc_init_flag[devp->index] == 1) { + afbc_init_flag[devp->index] = 2; return IRQ_HANDLED; + } } isr_log(devp->vfp); @@ -1436,8 +1439,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id) */ spin_lock_irqsave(&devp->isr_lock, flags); - /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */ - devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); + if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) { + /* no need reset mif under afbc mode */ + devp->vdin_reset_flag = 0; + } else { + /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */ + devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); + } if ((devp->flags & VDIN_FLAG_DEC_STOP_ISR) && (!(isr_flag & VDIN_BYPASS_STOP_CHECK))) { vdin_hw_disable(offset);