From 8887d2515df6bbf7fe8f614c11d2bf70cad0b40c Mon Sep 17 00:00:00 2001 From: kele bai Date: Fri, 23 Feb 2018 18:26:25 +0800 Subject: [PATCH] di: turn on cont wr interrupt, fine tune cue PD#156734: di: turn on cont wr interrupt, fine tune cue 1) turn on cont wr int, disable me int 2) modify cue mode for abnormal mode 2/4/7/8/9 3) move clk adjustment into thread env 4) set min clk rate when di disable 5) modify txlx clk tree Change-Id: I759324806bb9c9bfa4e83ee4a39e5283c5653f3b Signed-off-by: kele bai --- drivers/amlogic/clk/txlx/txlx_clk_media.c | 2 + .../amlogic/media/deinterlace/deinterlace.c | 83 +++++++++++++------ .../amlogic/media/deinterlace/deinterlace.h | 1 + .../media/deinterlace/deinterlace_hw.c | 22 ++--- .../media/deinterlace/deinterlace_hw.h | 2 +- drivers/amlogic/media/deinterlace/di_pps.c | 5 +- drivers/amlogic/media/deinterlace/nr_drv.c | 4 +- drivers/amlogic/media/deinterlace/register.h | 2 +- 8 files changed, 75 insertions(+), 46 deletions(-) diff --git a/drivers/amlogic/clk/txlx/txlx_clk_media.c b/drivers/amlogic/clk/txlx/txlx_clk_media.c index 8d9dca5c3a90..01bad3d873ac 100644 --- a/drivers/amlogic/clk/txlx/txlx_clk_media.c +++ b/drivers/amlogic/clk/txlx/txlx_clk_media.c @@ -651,4 +651,6 @@ void meson_txlx_media_init(void) clks[CLKID_IEC958_MUX] = clk_register(NULL, &cts_iec958_spdif.hw); WARN_ON(IS_ERR(clks[CLKID_IEC958_MUX])); + /* todo: set default div4 parent for tmp clkb */ + clk_set_parent(clks[CLKID_VPU_CLKB_TMP_COMP], clks[CLKID_FCLK_DIV4]); } diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 58a11775a335..345a45bd7c9d 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -1512,9 +1512,10 @@ static unsigned char is_input2pre(void) #ifdef DI_USE_FIXED_CANVAS_IDX static int di_post_idx[2][6]; static int di_pre_idx[2][10]; -static int di_wr_idx; #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC static unsigned int di_inp_idx[3]; +#else +static int di_wr_idx; #endif static int di_get_canvas(void) { @@ -1570,6 +1571,8 @@ static int di_get_canvas(void) #endif if (de_devp->post_wr_support == 0) return 0; + +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC if (canvas_pool_alloc_canvas_table("di_wr", &di_wr_idx, 1, CANVAS_MAP_TYPE_1)) { pr_err("%s allocat di write back canvas error.\n", @@ -1577,6 +1580,7 @@ static int di_get_canvas(void) return 1; } pr_info("DI: support post write back %u.\n", di_wr_idx); +#endif return 0; } @@ -1739,8 +1743,10 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp) buf_p->index, buf_p->pages); } } else { - pr_err("DI buf[%d] page:0x%p cma alloced skip\n", + if (cma_print) { + pr_err("DI buf[%d] page:0x%p cma alloced skip\n", buf_p->index, buf_p->pages); + } } buf_p->nr_adr = page_to_phys(buf_p->pages); if (cma_print) @@ -1945,8 +1951,6 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) di_buf_size = nr_size + mtn_size + count_size; } di_buf_size = roundup(di_buf_size, PAGE_SIZE); - pr_info("[DI] %s buffer size %u.\n", __func__, - di_buf_size); de_devp->buf_num_avail = de_devp->mem_size / di_buf_size; if (post_wr_en && post_wr_support) { @@ -5765,8 +5769,11 @@ static void di_pre_size_change(unsigned short width, pps_h = di_pre_stru.cur_height>>1; di_pps_config(1, pps_w, pps_h, pps_dstw, (pps_dsth>>1)); } - di_interrupt_ctrl(vf_type, det3d_en?1:0, - de_devp->nrds_enable, post_wr_en, mcpre_en?1:0); + di_interrupt_ctrl(di_pre_stru.madi_enable, + det3d_en?1:0, + de_devp->nrds_enable, + post_wr_en, + di_pre_stru.mcdi_enable); } static bool need_bypass(struct vframe_s *vf) @@ -5844,28 +5851,18 @@ static void di_reg_process_irq(void) switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); if (post_wr_en && post_wr_support) diwr_set_power_control(1); + /* up for vpu clkb rate change */ + up(&di_sema); if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { if (!use_2_interlace_buff) { - if (is_meson_txlx_cpu()) { - #ifdef CLK_TREE_SUPPORT - /* nr only clkb upto 500M*/ - clk_set_rate(de_devp->vpu_clkb, - de_devp->clkb_min_rate); - #endif - } di_top_gate_control(true, true); di_post_gate_control(true); /* freerun for reg configuration */ enable_di_post_mif(GATE_AUTO); } else { - if (is_meson_txlx_cpu()) { - #ifdef CLK_TREE_SUPPORT - clk_set_rate(de_devp->vpu_clkb, - de_devp->clkb_max_rate); - #endif - } di_top_gate_control(true, false); } + de_devp->flags |= DI_VPU_CLKB_SET; enable_di_pre_mif(true, mcpre_en); di_pre_gate_control(true, mcpre_en); } else { @@ -6100,6 +6097,11 @@ static int di_task_handle(void *data) di_pre_stru.disable_req_flag) && (di_pre_stru.pre_de_busy == 0)) { di_unreg_process(); + /* set min rate for power saving */ + if (de_devp->vpu_clkb) { + clk_set_rate(de_devp->vpu_clkb, + de_devp->clkb_min_rate); + } } if (di_pre_stru.reg_req_flag_irq || di_pre_stru.reg_req_flag) { @@ -6126,6 +6128,28 @@ static int di_task_handle(void *data) mutex_unlock(&de_devp->cma_mutex); #endif } + if (de_devp->flags & DI_VPU_CLKB_SET) { + if (is_meson_txlx_cpu()) { + if (!use_2_interlace_buff) { + #ifdef CLK_TREE_SUPPORT + clk_set_rate(de_devp->vpu_clkb, + de_devp->clkb_min_rate); + #endif + } else { + #ifdef CLK_TREE_SUPPORT + clk_set_rate(de_devp->vpu_clkb, + de_devp->clkb_max_rate); + #endif + } + } + if (is_meson_g12a_cpu()) { + #ifdef CLK_TREE_SUPPORT + clk_set_rate(de_devp->vpu_clkb, + de_devp->clkb_max_rate); + #endif + } + de_devp->flags &= (~DI_VPU_CLKB_SET); + } } return 0; @@ -6559,7 +6583,7 @@ static bool show_nrwr; static vframe_t *di_vf_get(void *arg) { vframe_t *vframe_ret = NULL; - struct di_buf_s *di_buf = NULL; + struct di_buf_s *di_buf = NULL, *nr_buf = NULL; ulong irq_flag2 = 0; if (di_pre_stru.bypass_flag) @@ -6596,11 +6620,10 @@ get_vframe: if (di_buf) { vframe_ret = di_buf->vframe; - + nr_buf = di_buf->di_buf_dup_p[1]; if ((post_wr_en && post_wr_support) && (di_buf->process_fun_index != PROCESS_FUN_NULL)) { - #if 0 - CONFIG_MULTI_DEC + #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC vframe_ret->canvas0_config[0].phy_addr = di_buf->nr_adr; vframe_ret->canvas0_config[0].width = @@ -6611,13 +6634,20 @@ get_vframe: vframe_ret->plane_num = 1; vframe_ret->canvas0Addr = -1; vframe_ret->canvas1Addr = -1; + if (show_nrwr) { + vframe_ret->canvas0_config[0].phy_addr = + nr_buf->nr_adr; + vframe_ret->canvas0_config[0].width = + nr_buf->canvas_width[NR_CANVAS]; + vframe_ret->canvas0_config[0].height = + nr_buf->canvas_height; + } #else config_canvas_idx(di_buf, di_wr_idx, -1); vframe_ret->canvas0Addr = di_buf->nr_canvas_idx; vframe_ret->canvas1Addr = di_buf->nr_canvas_idx; if (show_nrwr) { - config_canvas_idx( - di_buf->di_buf_dup_p[1], + config_canvas_idx(nr_buf, di_wr_idx, -1); vframe_ret->canvas0Addr = di_wr_idx; vframe_ret->canvas1Addr = di_wr_idx; @@ -7131,8 +7161,7 @@ static void di_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev) pdev->vpu_clkb = clk_get(dev, "vpu_clkb_composite"); if (IS_ERR(pdev->vpu_clkb)) pr_err("%s: get vpu clkb gate error.\n", __func__); - clk_set_rate(pdev->vpu_clkb, pdev->clkb_max_rate); - clk_set_rate(pdev->vpu_clkb, pdev->clkb_max_rate); + clk_set_rate(pdev->vpu_clkb, pdev->clkb_min_rate); #endif } diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index 11672a80de30..269fd3f1847c 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -192,6 +192,7 @@ extern bool is_vsync_rdma_enable(void); #define DI_MAP_FLAG 0x1 #define DI_SUSPEND_FLAG 0x2 #define DI_LOAD_REG_FLAG 0x4 +#define DI_VPU_CLKB_SET 0x8 struct di_dev_s { dev_t devt; struct cdev cdev; /* The cdev structure */ diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index 1090e87c8651..244ba7b45e52 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -610,25 +610,21 @@ static void set_di_nrwr_mif(struct DI_SIM_MIF_s *nrwr_mif, RDMA_WR_BITS(DI_NRWR_CTRL, 0x3, 22, 2); } -void di_interrupt_ctrl(unsigned char vf_type, +void di_interrupt_ctrl(unsigned char ma_en, unsigned char det3d_en, unsigned char nrds_en, unsigned char post_wr, unsigned char mc_en) { - if (vf_type & VIDTYPE_TYPEMASK) { - RDMA_WR_BITS(DI_INTR_CTRL, 0, 17, 1); - RDMA_WR_BITS(DI_INTR_CTRL, 1, 20, 1); - RDMA_WR_BITS(DI_INTR_CTRL, mc_en?0:7, 21, 3); - } else { - RDMA_WR_BITS(DI_INTR_CTRL, 1, 17, 1); - RDMA_WR_BITS(DI_INTR_CTRL, 1, 20, 1); - /* mask mc int */ - RDMA_WR_BITS(DI_INTR_CTRL, 7, 21, 3); - } + RDMA_WR_BITS(DI_INTR_CTRL, ma_en?0:1, 17, 1); + RDMA_WR_BITS(DI_INTR_CTRL, ma_en?0:1, 20, 1); + RDMA_WR_BITS(DI_INTR_CTRL, mc_en?0:3, 22, 2); /* enable nr wr int */ RDMA_WR_BITS(DI_INTR_CTRL, 0, 16, 1); - RDMA_WR_BITS(DI_INTR_CTRL, 1, 19, 1); RDMA_WR_BITS(DI_INTR_CTRL, post_wr?0:1, 18, 1); + /* mask me interrupt hit abnormal */ + RDMA_WR_BITS(DI_INTR_CTRL, 1, 21, 1); + /* mask hist interrupt */ + RDMA_WR_BITS(DI_INTR_CTRL, 1, 19, 1); RDMA_WR_BITS(DI_INTR_CTRL, det3d_en?0:1, 24, 1); RDMA_WR_BITS(DI_INTR_CTRL, nrds_en?0:1, 25, 1); /* clean all pending interrupt bits */ @@ -678,7 +674,6 @@ void enable_di_pre_aml( chan2_disable = true; if ((mem_hsize != nrwr_hsize) || (mem_vsize != nrwr_vsize)) mem_bypass = true; - /* * enable&disable contwr txt */ @@ -713,6 +708,7 @@ void enable_di_pre_aml( (0 << 12) | /* pre viu link */ (pre_vdin_link << 13) | (pre_vdin_link << 14) |/* pre go line link */ + (1 << 21) |/* invert NR field num */ (1 << 22) |/* MTN after NR. */ (0 << 25) |/* contrd en */ ((mem_bypass ? 1 : 0) << 28) | diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index 11d0f1154509..1ee22e483261 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -170,7 +170,7 @@ void pulldown_vof_win_config(struct pulldown_detected_s *wins); void di_load_regs(struct di_pq_parm_s *di_pq_ptr); void pre_frame_reset_g12a(unsigned char madi_en, unsigned char mcdi_en); void pre_frame_reset(void); -void di_interrupt_ctrl(unsigned char vf_type, +void di_interrupt_ctrl(unsigned char ma_en, unsigned char det3d_en, unsigned char nrds_en, unsigned char post_wr, unsigned char mc_en); #endif diff --git a/drivers/amlogic/media/deinterlace/di_pps.c b/drivers/amlogic/media/deinterlace/di_pps.c index 2ba916017fb1..8c9f7f317e64 100644 --- a/drivers/amlogic/media/deinterlace/di_pps.c +++ b/drivers/amlogic/media/deinterlace/di_pps.c @@ -415,8 +415,6 @@ void di_pps_config(unsigned char path, int src_w, int src_h, vsc_en = 1; if (src_w != dst_w) hsc_en = 1; - pr_info("[pps] %s input %d %d output %d %d.\n", - path?"pre":"post", src_w, src_h, dst_w, dst_h); /* config hdr size */ Wr_reg_bits(DI_HDR_IN_HSIZE, dst_w, 0, 13); Wr_reg_bits(DI_HDR_IN_VSIZE, dst_h, 0, 13); @@ -533,6 +531,9 @@ void di_pps_config(unsigned char path, int src_w, int src_h, (0 << 4) | // vert nonlinear 4region enable (vert_bank_length << 0) // vert scaler bank length ); + + pr_info("[pps] %s input %d %d output %d %d.\n", + path?"pre":"post", src_w, src_h, dst_w, dst_h); } /* * 0x374e ~ 0x376d, 20 regs diff --git a/drivers/amlogic/media/deinterlace/nr_drv.c b/drivers/amlogic/media/deinterlace/nr_drv.c index 0d2faa108ca2..d9da90682d81 100644 --- a/drivers/amlogic/media/deinterlace/nr_drv.c +++ b/drivers/amlogic/media/deinterlace/nr_drv.c @@ -719,10 +719,10 @@ void adaptive_cue_adjust(unsigned int frame_diff, unsigned int field_diff) /* for clockfuliness clip */ if (pcue_parm->field_count > (pcue_parm->glb_mot_fieldnum - 6)) { - Wr(NR2_CUE_MODE, 0x50322|(Rd(NR2_CUE_MODE)&0xc00)); + Wr(NR2_CUE_MODE, 0x50323|(Rd(NR2_CUE_MODE)&0xc00)); Wr(NR2_CUE_CON_MOT_TH, 0x03010e01); } else { - Wr(NR2_CUE_MODE, 0x00054377|(Rd(NR2_CUE_MODE)&0xc00)); + Wr(NR2_CUE_MODE, 0x00054375|(Rd(NR2_CUE_MODE)&0xc00)); Wr(NR2_CUE_CON_MOT_TH, 0xa03c8c3c); } } diff --git a/drivers/amlogic/media/deinterlace/register.h b/drivers/amlogic/media/deinterlace/register.h index fa3f2202fc2f..6d20bf406624 100644 --- a/drivers/amlogic/media/deinterlace/register.h +++ b/drivers/amlogic/media/deinterlace/register.h @@ -1294,7 +1294,7 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, */ /* // NR2 REG DEFINE END //// */ /* // DET 3D REG DEFINE BEGIN //// */ -/* // 8'h80~8'h8f */ +/* for gxlx */ #define DI_EI_DRT_CTRL_GXLX ((0x2028)) #define DI_EI_DRT_PIXTH_GXLX ((0x2029))