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 <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2019-04-05 20:52:27 +08:00
committed by Jianxin Pan
parent 6913eaacf9
commit 5a825f14bd
3 changed files with 50 additions and 33 deletions

View File

@@ -360,6 +360,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)
{
@@ -367,37 +368,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);
}
}
@@ -692,3 +693,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);
}

View File

@@ -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

View File

@@ -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;
@@ -553,7 +552,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)
@@ -703,7 +701,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)
@@ -714,16 +713,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)) {
@@ -757,8 +759,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);
@@ -1435,17 +1439,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);
@@ -1457,8 +1460,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);