From 9bb55f92240c4ca93d35839e2eeac74506138d3f Mon Sep 17 00:00:00 2001 From: "zhiwei.yuan" Date: Thu, 28 Feb 2019 15:30:09 +0800 Subject: [PATCH] di: TL1 enable lmv_lock_win_en cause crash [1/1] PD#SWPL-4999 Problem: use vmalloc in interrupt context Solution: move di_map to cma allocate function(kernel thread) Verify: verified by t962x2_x301 Change-Id: I8cf8d9caf9703ba039b32da98d2382a4c875de30 Signed-off-by: zhiwei.yuan --- drivers/amlogic/media/deinterlace/deinterlace.c | 35 ++++++++++++++++++++-- drivers/amlogic/media/deinterlace/deinterlace.h | 2 ++ drivers/amlogic/media/deinterlace/deinterlace_hw.c | 17 +++++------ drivers/amlogic/media/deinterlace/deinterlace_hw.h | 3 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index d9ef4cf..5e793b8 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -1878,6 +1878,7 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp) unsigned int start_time, end_time, delta_time; struct di_buf_s *buf_p = NULL; int itmp, alloc_cnt = 0; + u8 *tmp; start_time = jiffies_to_msecs(jiffies); queue_for_each_entry(buf_p, ptmp, QUEUE_LOCAL_FREE, list) { @@ -1923,6 +1924,18 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp) di_pre_stru.mtn_size + di_pre_stru.count_size + di_pre_stru.mv_size; + tmp = di_vmap(buf_p->mcinfo_adr, + di_pre_stru.mcinfo_size, + &buf_p->bflg_vmap); + + if (buf_p->bflg_vmap == true) + buf_p->mcinfo_vaddr = + (unsigned short *)tmp; + else { + buf_p->mcinfo_vaddr = NULL; + pr_err("DI: %s vmap fail\n", + __func__); + } } } } @@ -1987,6 +2000,12 @@ static void di_cma_release(struct di_dev_s *devp) } if ((ii >= USED_LOCAL_BUF_MAX) && (buf_p->pages != NULL)) { + + if (buf_p->bflg_vmap == true) { + di_unmap_phyaddr((u8 *)buf_p->mcinfo_vaddr); + buf_p->bflg_vmap = false; + } + if (dma_release_from_contiguous(&(devp->pdev->dev), buf_p->pages, devp->buffer_size >> PAGE_SHIFT)) { @@ -2049,6 +2068,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) unsigned int mv_canvas_width = width, canvas_align_width = 32; unsigned long di_post_mem = 0, nrds_mem = 0; struct di_buf_s *keep_buf = di_post_stru.keep_buf; + u8 *tmp; if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) canvas_align_width = 64; @@ -2177,6 +2197,18 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) de_devp->mem_start + di_buf_size * i + nr_size + mtn_size + count_size + mv_size; + tmp = di_vmap(di_buf->mcinfo_adr, + di_pre_stru.mcinfo_size, + &di_buf->bflg_vmap); + + if (di_buf->bflg_vmap == true) + di_buf->mcinfo_vaddr = + (unsigned short *)tmp; + else { + di_buf->mcinfo_vaddr = NULL; + pr_err("DI: %s vmap fail\n", + __func__); + } } di_buf->canvas_config_flag = 2; } @@ -4272,8 +4304,7 @@ static irqreturn_t de_irq(int irq, void *dev_instance) is_meson_txhd_cpu()) mc_pre_mv_irq(); calc_lmv_base_mcinfo((di_pre_stru.cur_height>>1), - di_pre_stru.di_wr_buf->mcinfo_adr, - di_pre_stru.mcinfo_size); + di_pre_stru.di_wr_buf->mcinfo_vaddr); } nr_process_in_irq(); if ((data32&0x200) && de_devp->nrds_enable) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index 0e38fdd..9aa19e2 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -117,6 +117,8 @@ struct di_buf_s { int cnt_canvas_idx; unsigned long mcinfo_adr; int mcinfo_canvas_idx; + unsigned short *mcinfo_vaddr; + bool bflg_vmap; unsigned long mcvec_adr; int mcvec_canvas_idx; struct mcinfo_pre_s { diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index 14827c7..0b1bf38 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -314,28 +314,25 @@ static struct mcinfo_lmv_s lines_mv[540]; static short offset_lmv = 100; module_param_named(offset_lmv, offset_lmv, short, 0644); -void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr, - unsigned int mcinfo_size) +void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned short *mcinfo_vadr) { unsigned short i, top_str, bot_str, top_end, bot_end, j = 0; - unsigned short *mcinfo_vadr = NULL, lck_num; + unsigned short lck_num; unsigned short flg_m1 = 0, flg_i = 0, nLmvLckSt = 0; unsigned short lmv_lckstext[3] = {0, 0, 0}, nLmvLckEd; unsigned short lmv_lckedext[3] = {0, 0, 0}, nLmvLckNum; - bool bflg_vmap = false; - u8 *tmp; + //bool bflg_vmap = false; //mcinfo_vadr = (unsigned short *)phys_to_virt(mcinfo_adr); if (!lmv_lock_win_en) return; - tmp = di_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap); - if (tmp == NULL) { + //tmp = di_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap); + if (mcinfo_vadr == NULL) { di_print("err:di_vmap failed\n"); return; } - mcinfo_vadr = (unsigned short *)tmp; for (i = 0; i < (vf_height>>1); i++) { lmvs_init(&lines_mv[i], *(mcinfo_vadr+i)); @@ -349,8 +346,8 @@ void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr, pr_info("\n"); } } - if (bflg_vmap) - di_unmap_phyaddr(tmp); + //if (bflg_vmap) + //di_unmap_phyaddr(tmp); pr_mcinfo_cnt ? pr_mcinfo_cnt-- : (pr_mcinfo_cnt = 0); top_str = 0; diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index d6b44d5..dbaa344 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -165,8 +165,7 @@ void enable_di_post_mif(enum gate_mode_e mode); void di_hw_uninit(void); void combing_pd22_window_config(unsigned int width, unsigned int height); void calc_lmv_init(void); -void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr, - unsigned int mcinfo_size); +void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned short *mcinfo_vadr); void init_field_mode(unsigned short height); void film_mode_win_config(unsigned int width, unsigned int height); void pulldown_vof_win_config(struct pulldown_detected_s *wins); -- 2.7.4