di: fix time out issue
authorDezhi Kong <dezhi.kong@amlogic.com>
Thu, 21 Jun 2018 00:28:07 +0000 (08:28 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Mon, 2 Jul 2018 04:12:29 +0000 (21:12 -0700)
PD#167967: di: fix time out issue

Change-Id: Ic535742a4227704e289372401aa077290ddd1ed7
Signed-off-by: Dezhi Kong <dezhi.kong@amlogic.com>
drivers/amlogic/media/deinterlace/deinterlace.c
drivers/amlogic/media/deinterlace/deinterlace.h
drivers/amlogic/media/deinterlace/deinterlace_dbg.c
drivers/amlogic/media/deinterlace/deinterlace_hw.c

index 91f0c79..02a5ea9 100644 (file)
@@ -2178,6 +2178,7 @@ static void di_uninit_buf(unsigned int disable_mirror)
                vframe_in[i] = NULL;
        di_pre_stru.pre_de_process_done = 0;
        di_pre_stru.pre_de_busy = 0;
+       di_pre_stru.pre_de_process_flag = 0;
        if (post_wr_en && post_wr_support) {
                di_post_stru.cur_post_buf = NULL;
                di_post_stru.post_de_busy = 0;
@@ -2615,7 +2616,7 @@ static void pre_de_process(void)
        unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK;
        unsigned short int_mask = 0x7f;
 
-       di_pre_stru.pre_de_busy = 1;
+       di_pre_stru.pre_de_process_flag = 1;
        di_pre_stru.pre_de_busy_timer_count = 0;
        #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
        pre_inp_canvas_config(di_pre_stru.di_inp_buf->vframe);
@@ -2780,17 +2781,22 @@ static void pre_de_process(void)
                /* enable mc pre mif*/
                enable_di_pre_mif(true, mcpre_en);
        }
+       /*reinit pre busy flag*/
+       di_pre_stru.pre_de_busy_timer_count = 0;
+       di_pre_stru.pre_de_busy = 1;
        #ifdef SUPPORT_MPEG_TO_VDIN
        if (mpeg2vdin_flag)
                RDMA_WR_BITS(DI_PRE_CTRL, 1, 13, 1);
        #endif
-       di_pre_stru.irq_time = sched_clock()/NSEC_PER_MSEC;
+       di_pre_stru.irq_time[0] = sched_clock()/NSEC_PER_MSEC;
+       di_pre_stru.irq_time[1] = sched_clock()/NSEC_PER_MSEC;
 #ifdef CONFIG_AMLOGIC_MEDIA_RDMA
        if (di_pre_rdma_enable & 0x2)
                rdma_config(de_devp->rdma_handle, RDMA_TRIGGER_MANUAL);
        else if (di_pre_rdma_enable & 1)
                rdma_config(de_devp->rdma_handle, RDMA_DEINT_IRQ);
 #endif
+       di_pre_stru.pre_de_process_flag = 0;
 }
 
 static void pre_de_done_buf_clear(void)
@@ -2871,7 +2877,6 @@ static void pre_de_done_buf_config(void)
                                di_pre_stru.di_wr_buf->vframe);
                }
 #endif
-       }
                if (!di_pre_rdma_enable)
                        di_pre_stru.di_post_wr_buf = di_pre_stru.di_wr_buf;
                post_wr_buf = di_pre_stru.di_post_wr_buf;
@@ -3036,7 +3041,7 @@ static void pre_de_done_buf_config(void)
                                di_pre_stru.di_wr_buf = NULL;
                        }
                }
-
+       }
        if (di_pre_stru.di_post_inp_buf && di_pre_rdma_enable) {
 #ifdef DI_BUFFER_DEBUG
                di_print("%s: %s[%d] => recycle_list\n", __func__,
@@ -4075,11 +4080,11 @@ static irqreturn_t de_irq(int irq, void *dev_instance)
        }
 
        if (flag) {
-               di_pre_stru.irq_time =
-                       (sched_clock()/NSEC_PER_MSEC - di_pre_stru.irq_time);
+               di_pre_stru.irq_time[0] =
+                       (sched_clock()/NSEC_PER_MSEC - di_pre_stru.irq_time[0]);
                trace_di_pre("PRE-IRQ-0",
                        di_pre_stru.field_count_for_cont,
-                       di_pre_stru.irq_time);
+                       di_pre_stru.irq_time[0]);
                if (mcpre_en) {
                        get_mcinfo_from_reg_in_irq();
                        if ((is_meson_gxlx_cpu() &&
@@ -6031,18 +6036,17 @@ static void di_process(void)
                        }
                }
                di_unlock_irqfiq_restore(irq_flag2);
-
-                       if ((di_pre_stru.pre_de_busy == 0) &&
-                               (di_pre_stru.pre_de_process_done == 0)) {
-                               if ((pre_run_flag == DI_RUN_FLAG_RUN) ||
-                                       (pre_run_flag == DI_RUN_FLAG_STEP)) {
-                                       if (pre_run_flag == DI_RUN_FLAG_STEP)
-                                               pre_run_flag =
-                                                       DI_RUN_FLAG_STEP_DONE;
-                                       if (pre_de_buf_config())
-                                               pre_de_process();
-                               }
+               if ((di_pre_stru.pre_de_busy == 0) &&
+                       (di_pre_stru.pre_de_process_done == 0)) {
+                       if ((pre_run_flag == DI_RUN_FLAG_RUN) ||
+                               (pre_run_flag == DI_RUN_FLAG_STEP)) {
+                               if (pre_run_flag == DI_RUN_FLAG_STEP)
+                                       pre_run_flag = DI_RUN_FLAG_STEP_DONE;
+                               if (pre_de_buf_config() &&
+                                       (di_pre_stru.pre_de_process_flag == 0))
+                                       pre_de_process();
                        }
+               }
                di_post_stru.di_post_process_cnt = 0;
                while (process_post_vframe()) {
                        if (di_post_stru.di_post_process_cnt++ >
@@ -6072,7 +6076,9 @@ static void di_pre_trigger_work(struct di_pre_stru_s *pre_stru_p)
 
        if (pre_stru_p->pre_de_busy && init_flag) {
                pre_stru_p->pre_de_busy_timer_count++;
-               if (pre_stru_p->pre_de_busy_timer_count >= nr_done_check_cnt) {
+               if (pre_stru_p->pre_de_busy_timer_count >= nr_done_check_cnt &&
+               ((sched_clock()/NSEC_PER_MSEC - di_pre_stru.irq_time[1]) >
+               (10*nr_done_check_cnt))) {
                        if (di_dbg_mask & 4) {
                                dump_mif_size_state(&di_pre_stru,
                                        &di_post_stru);
@@ -6087,9 +6093,12 @@ static void di_pre_trigger_work(struct di_pre_stru_s *pre_stru_p)
                        pre_stru_p->pre_de_clear_flag = 2;
                        if ((pre_stru_p->field_count_for_cont < 10) ||
                                (di_dbg_mask&0x2)) {
-                               pr_info("DI*****wait %d timeout 0x%x*****\n",
+                               pr_info("DI*****wait %d timeout 0x%x(%d ms)*****\n",
                                        pre_stru_p->field_count_for_cont,
-                                       Rd(DI_INTR_CTRL));
+                                       Rd(DI_INTR_CTRL),
+                                       (unsigned int)(sched_clock()/
+                                       NSEC_PER_MSEC -
+                                       di_pre_stru.irq_time[1]));
                        }
                }
        } else {
@@ -6528,7 +6537,8 @@ static void fast_process(void)
                                        if (pre_run_flag == DI_RUN_FLAG_STEP)
                                                pre_run_flag =
                                                        DI_RUN_FLAG_STEP_DONE;
-                                       if (pre_de_buf_config())
+                                       if (pre_de_buf_config() &&
+                                       (di_pre_stru.pre_de_process_flag == 0))
                                                pre_de_process();
                                }
                        }
@@ -7659,6 +7669,8 @@ module_param_named(nr10bit_support, nr10bit_support, uint, 0664);
 module_param_named(di_stop_reg_flag, di_stop_reg_flag, uint, 0664);
 module_param(di_dbg_mask, uint, 0664);
 MODULE_PARM_DESC(di_dbg_mask, "\n di_dbg_mask\n");
+module_param(nr_done_check_cnt, uint, 0664);
+MODULE_PARM_DESC(nr_done_check_cnt, "\n nr_done_check_cnt\n");
 module_param_array(di_stop_reg_addr, uint, &num_di_stop_reg_addr,
        0664);
 module_param_named(mcpre_en, mcpre_en, bool, 0664);
index defccd2..6cee195 100644 (file)
@@ -262,6 +262,7 @@ struct di_pre_stru_s {
        int     pre_de_busy;            /* 1 if pre_de is not done */
        int     pre_de_busy_timer_count;
        int     pre_de_process_done;    /* flag when irq done */
+       int     pre_de_process_flag;    /* flag when pre_de_process done */
        int     pre_de_clear_flag;
        /* flag is set when VFRAME_EVENT_PROVIDER_UNREG*/
        int     unreg_req_flag;
@@ -335,7 +336,7 @@ struct di_pre_stru_s {
        int cma_alloc_done;
        int cma_release_req;
        /* for performance debug */
-       unsigned long irq_time;
+       unsigned long irq_time[2];
        /* combing adaptive */
        struct combing_status_s *mtn_status;
 };
index 62f13ed..0da7133 100644 (file)
@@ -401,6 +401,8 @@ void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p)
                di_pre_stru_p->pre_de_busy_timer_count);
        pr_info("pre_de_process_done   = %d\n",
                di_pre_stru_p->pre_de_process_done);
+       pr_info("pre_de_process_flag   = %d\n",
+               di_pre_stru_p->pre_de_process_flag);
        pr_info("pre_de_irq_timeout_count=%d\n",
                di_pre_stru_p->pre_de_irq_timeout_count);
        pr_info("unreg_req_flag            = %d\n",
@@ -423,6 +425,8 @@ void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p)
                di_pre_stru_p->cur_prog_flag);
        pr_info("source_change_flag        = %d\n",
                di_pre_stru_p->source_change_flag);
+       pr_info("bypass_flag = %s\n",
+               di_pre_stru_p->bypass_flag?"true":"false");
        pr_info("prog_proc_type            = %d\n",
                di_pre_stru_p->prog_proc_type);
        pr_info("madi_enable               = %u\n",
index 77ead81..0486847 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/workqueue.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/atomic.h>
 
 #include <linux/amlogic/media/vpu/vpu.h>
 #include <linux/amlogic/cpu_version.h>
@@ -1862,7 +1863,7 @@ static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line,
                        mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
                demux_mode = mif->video_mode;
                DI_VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG,
-(0 << 29) | /* reset on go field */
+(1 << 29) | /* reset on go field */
 (urgent << 28)         |       /* urgent */
 (urgent << 27)         |       /* luma urgent */
 (1 << 25)              |       /* no dummy data. */
@@ -2999,10 +3000,16 @@ static void di_pre_data_mif_ctrl(bool enable)
 }
 
 static bool pre_mif_gate;
+static atomic_t mif_flag;
 void enable_di_pre_mif(bool en, bool mc_enable)
 {
+       if (atomic_read(&mif_flag))
+               return;
+
        if (pre_mif_gate && !en)
                return;
+       atomic_set(&mif_flag, 1);
+
        if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
                if (mc_enable)
                        mc_pre_mif_ctrl_g12(en);
@@ -3013,6 +3020,7 @@ void enable_di_pre_mif(bool en, bool mc_enable)
                ma_pre_mif_ctrl(en);
        }
        di_pre_data_mif_ctrl(en);
+       atomic_set(&mif_flag, 0);
 }
 
 void combing_pd22_window_config(unsigned int width, unsigned int height)