diff --git a/MAINTAINERS b/MAINTAINERS index 767c416c2b7c..fddd11e6af54 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13679,6 +13679,7 @@ F: include/linux/amlogic/media/amvecm/amvecm.h F: arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts F: arch/arm64/boot/dts/amlogic/txlx_t962x_r311.dts F: arch/arm64/boot/dts/amlogic/g12a_pxp.dts +F: arch/arm64/boot/dts/amlogic/g12a_skt.dts AMLOGIC TVIN M: Dezhi Kong diff --git a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts index 75d7a1a1bded..6ca4bc77d6e6 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts @@ -89,7 +89,7 @@ * 10x4736064=45.2M(0x2e) support 12bit * 10x4074560=40M(0x28) support 10bit */ - size = <0x0 0x02900000>; + size = <0x0 0x02800000>; alignment = <0x0 0x400000>; }; codec_mm_cma:linux,codec_mm_cma { @@ -370,15 +370,11 @@ interrupts = <0 46 1 0 40 1>; interrupt-names = "pre_irq", "post_irq"; - clocks = <&clkc CLKID_VPU_MUX>, - <&clkc CLKID_FCLK_DIV4>, - <&clkc CLKID_VPU_CLKB_TMP_COMP>, + clocks = <&clkc CLKID_VPU_CLKB_TMP_COMP>, <&clkc CLKID_VPU_CLKB_COMP>; - clock-names = "vpu_mux", - "fclk_div4", - "vpu_clkb_tmp_composite", + clock-names = "vpu_clkb_tmp_composite", "vpu_clkb_composite"; - clock-range = <333 666>; + clock-range = <334 667>; /* buffer-size = <3621952>;(yuv422 8bit) */ buffer-size = <4074560>;/*yuv422 fullpack*/ /* reserve-iomap = "true"; */ diff --git a/arch/arm64/boot/dts/amlogic/g12a_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_skt.dts index 9423f250cd7e..ac2304a569d2 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_skt.dts @@ -692,15 +692,11 @@ interrupts = <0 46 1 0 40 1>; interrupt-names = "pre_irq", "post_irq"; - clocks = <&clkc CLKID_VPU_MUX>, - <&clkc CLKID_FCLK_DIV4>, - <&clkc CLKID_VPU_CLKB_TMP_COMP>, + clocks = <&clkc CLKID_VPU_CLKB_TMP_COMP>, <&clkc CLKID_VPU_CLKB_COMP>; - clock-names = "vpu_mux", - "fclk_div4", - "vpu_clkb_tmp_composite", + clock-names = "vpu_clkb_tmp_composite", "vpu_clkb_composite"; - clock-range = <333 666>; + clock-range = <334 667>; /* buffer-size = <3621952>;(yuv422 8bit) */ buffer-size = <4074560>;/*yuv422 fullpack*/ /* reserve-iomap = "true"; */ diff --git a/drivers/amlogic/media/deinterlace/Makefile b/drivers/amlogic/media/deinterlace/Makefile index ea280fbd7b63..1e2e5de429f2 100644 --- a/drivers/amlogic/media/deinterlace/Makefile +++ b/drivers/amlogic/media/deinterlace/Makefile @@ -3,7 +3,6 @@ ifeq ($(TARGET_BUILD_VARIANT),userdebug) ccflags-y := -D DEBUG_SUPPORT endif CFLAGS_deinterlace.o := -I$(src) -obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += film_mode_fmw/ obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += di.o di-objs += deinterlace.o di-objs += deinterlace_hw.o @@ -14,5 +13,8 @@ di-objs += pulldown_drv.o di-objs += detect3d.o di-objs += nr_downscale.o di-objs += di_pps.o +di-objs += film_mode_fmw/vof_soft_top.o +di-objs += film_mode_fmw/flm_mod_xx.o +di-objs += film_mode_fmw/film_fw1.o ccflags-y += -Idrivers/amlogic/media/common/rdma/ diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 9fb5f71e0518..58a11775a335 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -118,7 +118,7 @@ static di_dev_t *de_devp; static dev_t di_devno; static struct class *di_clsp; -static const char version_s[] = "2018-01-04a"; +static const char version_s[] = "2018-02-11a"; static int bypass_state = 1; static int bypass_all; @@ -135,7 +135,6 @@ static int bypass_post; static bool post_wr_en; static unsigned int post_wr_support; static int bypass_post_state; -static int timeout_miss_policy; /* 0, use di_wr_buf still; * 1, call pre_de_done_buf_clear to clear di_wr_buf; * 2, do nothing @@ -223,8 +222,8 @@ static unsigned long reg_unreg_timeout_cnt; static int di_vscale_skip_count; static int di_vscale_skip_count_real; static int vpp_3d_mode; -#ifdef DET3D static bool det3d_en; +#ifdef DET3D static unsigned int det3d_mode; static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf); #endif @@ -258,8 +257,6 @@ static int post_urgent = 1; /*pre process speed debug */ static int pre_process_time; -static int pre_process_time_force; -/**/ static int di_receiver_event_fun(int type, void *data, void *arg); static void di_uninit_buf(unsigned int disable_mirror); static unsigned char is_bypass(vframe_t *vf_in); @@ -502,7 +499,7 @@ store_dbg(struct device *dev, dump_di_reg_g12(); else dump_di_reg(); - } else if (strncmp(buf, "dump_mif", 8) == 0) { + } else if (strncmp(buf, "dumpmif", 7) == 0) { dump_mif_size_state(&di_pre_stru, &di_post_stru); } else if (strncmp(buf, "recycle_buf", 11) == 0) { recycle_keep_buffer(); @@ -1456,7 +1453,8 @@ static unsigned char is_bypass(vframe_t *vf_in) if (vf_in && (vf_in->type & VIDTYPE_COMPRESS)) return 1; - if ((di_vscale_skip_enable & 0x4) && vf_in) { + if ((di_vscale_skip_enable & 0x4) && + vf_in && !post_wr_en) { /*backup vtype,set type as progressive*/ vtype = vf_in->type; vf_in->type &= (~VIDTYPE_TYPEMASK); @@ -2606,7 +2604,6 @@ static void pre_de_process(void) unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK; unsigned short int_mask = 0x7f; - di_print("%s: start\n", __func__); di_pre_stru.pre_de_busy = 1; di_pre_stru.pre_de_busy_timer_count = 0; #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC @@ -2711,7 +2708,6 @@ static void pre_de_process(void) nr_ds_hw_ctrl(true); int_mask = 0x3f; } else { - RDMA_WR_BITS(DI_PRE_CTRL, 0, 11, 1); nr_ds_hw_ctrl(false); } } @@ -2721,20 +2717,7 @@ static void pre_de_process(void) * to prevent multiple entry for de_irq */ - RDMA_WR(DI_INTR_CTRL, - /* mask nrwr interrupt. */ - (2 << 16) | - /* mask diwr intrpt. */ - (((post_wr_en && post_wr_support)?0:1) << 18) | - (int_mask << 19) | /* mask hist check interrupt. */ - #ifdef DET3D - ((det3d_en ? 0 : 1) << 24) | /* mask det3d interrupt. */ - #else - (1 << 24) | /* mask det3d interrupt. */ - #endif - ((de_devp->nrds_enable ? 0 : 1) << 25) | - ((post_wr_en && post_wr_support)?0xb:0xf)); - /* clean all pending interrupt bits. */ + enable_di_pre_aml(&di_pre_stru.di_inp_mif, &di_pre_stru.di_mem_mif, @@ -2779,12 +2762,10 @@ static void pre_de_process(void) #endif enable_di_pre_mif(true, mcpre_en); if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { - RDMA_WR(DI_PRE_GL_CTRL, 0xc3200005); - RDMA_WR(DI_PRE_GL_CTRL, 0x83200005); - reset_pre_simple_mif(); + pre_frame_reset_g12a(di_pre_stru.madi_enable, + di_pre_stru.mcdi_enable); } else { - /* frame + soft reset for the pre modules. */ - RDMA_WR(DI_PRE_CTRL, Rd(DI_PRE_CTRL) | 3 << 30); + pre_frame_reset(); /* enable mc pre mif*/ enable_di_pre_mif(true, mcpre_en); } @@ -2899,6 +2880,7 @@ static void pre_de_done_buf_config(void) if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) adaptive_cue_adjust(glb_frame_mot_num, glb_field_mot_num); + pulldown_info_clear_g12a(); } if (di_pre_stru.cur_prog_flag) { @@ -4025,15 +4007,17 @@ static void set_post_mcinfo(struct mcinfo_pre_s *curr_field_mcinfo) DI_VSYNC_WR_MPEG_REG(0x2f78 + i, value); } } -static bool nrwr_dbg; -module_param_named(nrwr_dbg, nrwr_dbg, bool, 0644); +static unsigned char intr_mode; static irqreturn_t de_irq(int irq, void *dev_instance) { #ifndef CHECK_DI_DONE unsigned int data32 = Rd(DI_INTR_CTRL); - unsigned int mask32 = (data32 >> 16) & 0x1ff; - int flag = 0; + unsigned int mask32 = (data32 >> 16) & 0x3ff; + unsigned int flag = 0; + data32 &= 0x3fffffff; + if ((data32 & 1) == 0 && di_dbg_mask&8) + pr_info("irq[%d]pre|post=0 write done.\n", irq); if (di_pre_stru.pre_de_busy) { /* only one inetrrupr mask should be enable */ if ((data32 & 2) && !(mask32 & 2)) { @@ -4062,23 +4046,9 @@ static irqreturn_t de_irq(int irq, void *dev_instance) DI_Wr(DI_INTR_CTRL, data32); } #else - DI_Wr(DI_INTR_CTRL, data32); + if (flag) + DI_Wr(DI_INTR_CTRL, (data32&0xfffffffb)|(intr_mode<<30)); #endif - if ((post_wr_en && post_wr_support) && (data32&0x4)) { - di_post_stru.de_post_process_done = 1; - di_post_stru.post_de_busy = 0; - di_post_stru.irq_time = - (sched_clock()/NSEC_PER_MSEC - di_post_stru.irq_time); - trace_di_post("POST-IRQ-1", - di_post_stru.post_wr_cnt, - di_post_stru.irq_time); - if (!(data32 & 0x2)) { - DI_Wr(DI_INTR_CTRL, data32); - goto end; - } - } - if (pre_process_time_force) - return IRQ_HANDLED; if (di_pre_stru.pre_de_busy == 0) { di_print("%s: wrong enter %x\n", __func__, Rd(DI_INTR_CTRL)); @@ -4086,12 +4056,6 @@ static irqreturn_t de_irq(int irq, void *dev_instance) } if (flag) { - if (nrwr_dbg) { - pr_info("%dth bc %u bd %u.\n", - di_pre_stru.field_count_for_cont, - RDMA_RD(0x20bc), - RDMA_RD(0x20bd)); - } di_pre_stru.irq_time = (sched_clock()/NSEC_PER_MSEC - di_pre_stru.irq_time); trace_di_pre("PRE-IRQ-0", @@ -4114,16 +4078,40 @@ static irqreturn_t de_irq(int irq, void *dev_instance) di_pre_stru.pre_de_process_done = 1; di_pre_stru.pre_de_busy = 0; -end: if (init_flag) /* pr_dbg("%s:up di sema\n", __func__); */ trigger_pre_di_process(TRIGGER_PRE_BY_DE_IRQ); } - return IRQ_HANDLED; } +static irqreturn_t post_irq(int irq, void *dev_instance) +{ + unsigned int data32 = Rd(DI_INTR_CTRL); + + data32 &= 0x3fffffff; + if ((data32 & 4) == 0) { + if (di_dbg_mask&8) + pr_info("irq[%d]post write undone.\n", irq); + return IRQ_HANDLED; + } + if ((post_wr_en && post_wr_support) && (data32&0x4)) { + di_post_stru.de_post_process_done = 1; + di_post_stru.post_de_busy = 0; + di_post_stru.irq_time = + (sched_clock()/NSEC_PER_MSEC - di_post_stru.irq_time); + trace_di_post("POST-IRQ-1", + di_post_stru.post_wr_cnt, + di_post_stru.irq_time); + DI_Wr(DI_INTR_CTRL, (data32&0xffff0004)|(intr_mode<<30)); + } + + if (init_flag) + trigger_pre_di_process(TRIGGER_PRE_BY_DE_IRQ); + + return IRQ_HANDLED; +} /* * di post process */ @@ -4215,7 +4203,8 @@ static void vscale_skip_disable_post(struct di_buf_s *di_buf, vframe_t *disp_vf) } static void process_vscale_skip(struct di_buf_s *di_buf, vframe_t *disp_vf) { - int ret = 0, vpp_3d_mode = 0; + int ret = 0, vpp_3d_mode = 0; + if ((di_buf->di_buf[0] != NULL) && (di_vscale_skip_enable & 0x5) && (di_buf->process_fun_index != PROCESS_FUN_NULL)) { ret = get_current_vscale_skip_count(disp_vf); @@ -4237,7 +4226,11 @@ static void process_vscale_skip(struct di_buf_s *di_buf, vframe_t *disp_vf) } } } - +static int do_post_wr_fun(void *arg, vframe_t *disp_vf) +{ + di_post_stru.toggle_flag = true; + return 1; +} static int de_post_disable_fun(void *arg, vframe_t *disp_vf) { struct di_buf_s *di_buf = (struct di_buf_s *)arg; @@ -4411,9 +4404,6 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, if (get_vpp_reg_update_flag(zoom_start_x_lines) || post_refresh) di_post_stru.update_post_reg_flag = 1; -/* pr_dbg("%s set update_post_reg_flag to %d\n", __func__, - * di_post_stru.update_post_reg_flag); - */ zoom_start_x_lines = zoom_start_x_lines & 0xffff; zoom_end_x_lines = zoom_end_x_lines & 0xffff; @@ -4433,10 +4423,6 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, /* make sure the height is even number */ if (di_height%2) di_height++; -/* pr_dbg("height = (%d %d %d %d %d)\n", - * di_buf->vframe->height, zoom_start_x_lines, zoom_end_x_lines, - * zoom_start_y_lines, zoom_end_y_lines); - */ if (Rd(DI_POST_SIZE) != ((di_width - 1) | ((di_height - 1) << 16)) || di_post_stru.buf_type != di_buf->di_buf_dup_p[0]->type || @@ -4557,7 +4543,8 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, } di_post_stru.update_post_reg_flag = 1; /* if height decrease, mtn will not enough */ - if (di_buf->pd_config.global_mode != PULL_DOWN_BUF1) + if (di_buf->pd_config.global_mode != PULL_DOWN_BUF1 && + !post_wr_en) di_buf->pd_config.global_mode = PULL_DOWN_EI; } @@ -4852,8 +4839,9 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, } if (is_meson_txlx_cpu() || - is_meson_gxlx_cpu()) { - di_post_read_reverse_irq(overturn, mc_pre_flag, mcpre_en); + is_meson_gxlx_cpu() || is_meson_g12a_cpu()) { + di_post_read_reverse_irq(overturn, mc_pre_flag, + post_blend_en ? mcpre_en : false); /* disable mc for first 2 fieldes mv unreliable */ if (di_buf->seq < 2) DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); @@ -4913,31 +4901,33 @@ static void di_post_process(void) struct di_buf_s *di_buf = NULL; vframe_t *vf_p = NULL; - - if (!queue_empty(QUEUE_POST_DOING) && !di_post_stru.post_de_busy) { - di_buf = get_di_buf_head(QUEUE_POST_DOING); - if (check_di_buf(di_buf, 20)) - return; - vf_p = di_buf->vframe; - if (di_post_stru.run_early_proc_fun_flag) { - if (vf_p->early_process_fun) - vf_p->early_process_fun( - vf_p->private_data, vf_p); - } - if (di_buf->process_fun_index) { - RDMA_WR_BITS(DI_INTR_CTRL, 0, 18, 1); - RDMA_WR_BITS(DI_INTR_CTRL, 0, 2, 1); - di_post_stru.post_wr_cnt++; - de_post_process( - di_buf, 0, vf_p->width-1, - 0, vf_p->height-1, vf_p); - di_post_stru.post_de_busy = 1; - di_post_stru.irq_time = sched_clock()/NSEC_PER_MSEC; - } else { - di_post_stru.de_post_process_done = 1; - } - di_post_stru.cur_post_buf = di_buf; + if (di_post_stru.post_de_busy) + return; + if (queue_empty(QUEUE_POST_DOING)) { + di_post_stru.post_peek_underflow++; + return; } + + di_buf = get_di_buf_head(QUEUE_POST_DOING); + if (check_di_buf(di_buf, 20)) + return; + vf_p = di_buf->vframe; + if (di_post_stru.run_early_proc_fun_flag) { + if (vf_p->early_process_fun) + vf_p->early_process_fun = do_post_wr_fun; + } + if (di_buf->process_fun_index) { + + di_post_stru.post_wr_cnt++; + de_post_process( + di_buf, 0, vf_p->width-1, + 0, vf_p->height-1, vf_p); + di_post_stru.post_de_busy = 1; + di_post_stru.irq_time = sched_clock()/NSEC_PER_MSEC; + } else { + di_post_stru.de_post_process_done = 1; + } + di_post_stru.cur_post_buf = di_buf; } static void recycle_vframe_type_post(struct di_buf_s *di_buf) @@ -5775,6 +5765,8 @@ 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); } static bool need_bypass(struct vframe_s *vf) @@ -5854,20 +5846,24 @@ static void di_reg_process_irq(void) diwr_set_power_control(1); if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { if (!use_2_interlace_buff) { - #ifdef CLK_TREE_SUPPORT - /* nr only clkb upto 500M*/ - clk_set_rate(de_devp->vpu_clkb, - de_devp->clkb_min_rate); - #endif + 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 { - #ifdef CLK_TREE_SUPPORT - clk_set_rate(de_devp->vpu_clkb, - de_devp->clkb_max_rate); - #endif + 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); } enable_di_pre_mif(true, mcpre_en); @@ -6049,23 +6045,23 @@ 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 (di_dbg_mask & 4) { + dump_mif_size_state(&di_pre_stru, + &di_post_stru); + } enable_di_pre_mif(false, mcpre_en); if (de_devp->nrds_enable) nr_ds_hw_ctrl(false); pre_stru_p->pre_de_busy_timer_count = 0; pre_stru_p->pre_de_irq_timeout_count++; - if (timeout_miss_policy == 0) { - pre_stru_p->pre_de_process_done = 1; - pre_stru_p->pre_de_busy = 0; - pre_stru_p->pre_de_clear_flag = 2; - } else if (timeout_miss_policy == 1) { - pre_stru_p->pre_de_clear_flag = 1; - pre_stru_p->pre_de_busy = 0; - } + pre_stru_p->pre_de_process_done = 1; + pre_stru_p->pre_de_busy = 0; + 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*****\n", - pre_stru_p->field_count_for_cont); + pr_info("DI*****wait %d timeout 0x%x*****\n", + pre_stru_p->field_count_for_cont, + Rd(DI_INTR_CTRL)); } } } else { @@ -6627,7 +6623,7 @@ get_vframe: vframe_ret->canvas1Addr = di_wr_idx; } #endif - vframe_ret->early_process_fun = NULL; + vframe_ret->early_process_fun = do_post_wr_fun; vframe_ret->process_fun = NULL; } di_buf->seq = disp_frame_count; @@ -7068,6 +7064,7 @@ static void set_di_flag(void) is_meson_g12a_cpu()) { full_422_pack = true; } + post_hold_line = is_meson_g12a_cpu()?10:17; } else { mcpre_en = false; pulldown_enable = false; @@ -7076,7 +7073,8 @@ static void set_di_flag(void) use_2_interlace_buff = 0; di_force_bit_mode = 8; } - + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + intr_mode = 3; if (di_pre_rdma_enable) { pldn_dly = 1; pldn_dly1 = 1; @@ -7221,10 +7219,8 @@ static int di_probe(struct platform_device *pdev) clk_prepare_enable(di_devp->vpu_clkb); pr_info("DI:enable vpu clkb.\n"); #else - aml_write_hiubus(HHI_VPU_CLKB_CNTL, 0x1200300); + aml_write_hiubus(HHI_VPU_CLKB_CNTL, 0x1000100); #endif - pr_info("DI:clkb cnt 0x%x.\n", - aml_read_hiubus(HHI_VPU_CLKB_CNTL)); } di_devp->flags &= (~DI_SUSPEND_FLAG); ret = of_property_read_u32(pdev->dev.of_node, @@ -7283,7 +7279,7 @@ static int di_probe(struct platform_device *pdev) ret = request_irq(di_devp->pre_irq, &de_irq, IRQF_SHARED, "pre_di", (void *)"pre_di"); if (di_devp->post_wr_support) { - ret = request_irq(di_devp->post_irq, &de_irq, + ret = request_irq(di_devp->post_irq, &post_irq, IRQF_SHARED, "post_di", (void *)"post_di"); } sema_init(&di_sema, 1); @@ -7570,7 +7566,6 @@ MODULE_PARM_DESC(force_recovery, "\n force_recovery\n"); module_param(force_recovery, uint, 0664); module_param_named(force_recovery_count, force_recovery_count, uint, 0664); -module_param_named(pre_process_time_force, pre_process_time_force, uint, 0664); module_param_named(pre_process_time, pre_process_time, uint, 0664); module_param_named(bypass_post, bypass_post, uint, 0664); module_param_named(post_wr_en, post_wr_en, bool, 0664); @@ -7603,8 +7598,6 @@ module_param_named(input2pre_proc_miss_count, input2pre_proc_miss_count, module_param_named(input2pre_miss_policy, input2pre_miss_policy, uint, 0664); module_param_named(input2pre_throw_count, input2pre_throw_count, uint, 0664); #endif - -module_param_named(timeout_miss_policy, timeout_miss_policy, uint, 0664); #ifdef SUPPORT_MPEG_TO_VDIN module_param_named(mpeg2vdin_en, mpeg2vdin_en, int, 0664); module_param_named(mpeg2vdin_flag, mpeg2vdin_flag, int, 0664); diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index a06b5cc26c67..11672a80de30 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -64,7 +64,7 @@ /* canvas defination */ #define DI_USE_FIXED_CANVAS_IDX -#define DET3D +//#define DET3D #undef SUPPORT_MPEG_TO_VDIN #define CLK_TREE_SUPPORT #ifndef CONFIG_AMLOGIC_MEDIA_RDMA @@ -361,6 +361,7 @@ struct di_post_stru_s { int de_post_process_done; int post_de_busy; int di_post_num; + unsigned int post_peek_underflow; unsigned int di_post_process_cnt; unsigned int check_recycle_buf_cnt; /* performance debug */ diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c index 99e0d6905096..ed8d14425676 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c @@ -355,9 +355,13 @@ static void dump_mif_state(struct DI_MIF_s *mif) pr_info("luma <%u, %u> <%u %u>.\n", mif->luma_x_start0, mif->luma_x_end0, mif->luma_y_start0, mif->luma_y_end0); - pr_info("if0 chroma <%u, %u> <%u %u>.\n", + pr_info("chroma <%u, %u> <%u %u>.\n", mif->chroma_x_start0, mif->chroma_x_end0, mif->chroma_y_start0, mif->chroma_y_end0); + pr_info("canvas id <%u %u %u>.\n", + mif->canvas0_addr0, + mif->canvas0_addr1, + mif->canvas0_addr2); } static void dump_simple_mif_state(struct DI_SIM_MIF_s *simp_mif) @@ -365,6 +369,8 @@ static void dump_simple_mif_state(struct DI_SIM_MIF_s *simp_mif) pr_info("<%u %u> <%u %u>.\n", simp_mif->start_x, simp_mif->end_x, simp_mif->start_y, simp_mif->end_y); + pr_info("canvas num <%u>.\n", + simp_mif->canvas_num); } static void dump_mc_mif_state(struct DI_MC_MIF_s *mc_mif) @@ -449,33 +455,50 @@ void dump_di_post_stru(struct di_post_stru_s *di_post_stru_p) di_post_stru_p->post_de_busy); pr_info("de_post_process_done = %d\n", di_post_stru_p->de_post_process_done); - pr_info("cur_post_buf = 0x%p\n,", + pr_info("cur_post_buf = 0x%p\n", di_post_stru_p->cur_post_buf); + pr_info("post_peek_underflow = %u\n", + di_post_stru_p->post_peek_underflow); } void dump_mif_size_state(struct di_pre_stru_s *pre_stru_p, struct di_post_stru_s *post_stru_p) { pr_info("======pre mif status======\n"); - pr_info("DI_PRE_SIZE=0x%x", Rd(DI_PRE_SIZE)); + pr_info("DI_PRE_CTRL=0x%x\n", Rd(DI_PRE_CTRL)); + pr_info("DI_PRE_SIZE=0x%x\n", Rd(DI_PRE_SIZE)); pr_info("DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE)); - pr_info("CONTWR_CAN_SIZE=0x%x", Rd(0x37ec)); + pr_info("CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec)); pr_info("MTNWR_CAN_SIZE=0x%x\n", Rd(0x37f0)); - pr_info("DNR_STAT_X_START_END=0x%x", Rd(0x2d08)); + pr_info("DNR_STAT_X_START_END=0x%x\n", Rd(0x2d08)); pr_info("DNR_STAT_Y_START_END=0x%x\n", Rd(0x2d09)); - pr_info("MCDI_HV_SIZEIN=0x%x", Rd(0x2f00)); + pr_info("MCDI_HV_SIZEIN=0x%x\n", Rd(0x2f00)); pr_info("MCDI_HV_BLKSIZEIN=0x%x\n", Rd(0x2f01)); - pr_info("MCVECWR_CAN_SIZE=0x%x", Rd(0x37f4)); + pr_info("MCVECWR_CAN_SIZE=0x%x\n", Rd(0x37f4)); pr_info("MCINFWR_CAN_SIZE=0x%x\n", Rd(0x37f8)); - pr_info("NRDSWR_CAN_SIZE=0x%x", Rd(0x37fc)); + pr_info("NRDSWR_CAN_SIZE=0x%x\n", Rd(0x37fc)); pr_info("NR_DS_BUF_SIZE=0x%x\n", Rd(0x3740)); pr_info("=====inp mif:\n"); +#if 0 + Wr(DI_DBG_CTRL, 0x1b); + Wr(DI_DBG_CTRL1, 0x640064); + Wr_reg_bits(DI_PRE_GL_CTRL, 0, 31, 1); + Wr_reg_bits(DI_PRE_CTRL, 0, 11, 1); + Wr_reg_bits(DI_PRE_CTRL, 1, 31, 1); + Wr_reg_bits(DI_PRE_GL_CTRL, 1, 31, 1); + pr_info("DI_DBG_SRDY_INF=0x%x\n", Rd(DI_DBG_SRDY_INF)); + pr_info("DI_DBG_RRDY_INF=0x%x\n", Rd(DI_DBG_RRDY_INF)); +#endif + pr_info("DI_INP_GEN_REG=0x%x\n", Rd(DI_INP_GEN_REG)); dump_mif_state(&pre_stru_p->di_inp_mif); pr_info("=====mem mif:\n"); + pr_info("DI_MEM_GEN_REG=0x%x\n", Rd(DI_MEM_GEN_REG)); dump_mif_state(&pre_stru_p->di_mem_mif); pr_info("=====chan2 mif:\n"); + pr_info("DI_CHAN2_GEN_REG=0x%x\n", Rd(DI_CHAN2_GEN_REG)); dump_mif_state(&pre_stru_p->di_chan2_mif); pr_info("=====nrwr mif:\n"); + pr_info("DI_NRWR_CTRL=0x%x\n", Rd(DI_NRWR_CTRL)); dump_simple_mif_state(&pre_stru_p->di_nrwr_mif); pr_info("=====mtnwr mif:\n"); dump_simple_mif_state(&pre_stru_p->di_mtnwr_mif); @@ -492,13 +515,16 @@ void dump_mif_size_state(struct di_pre_stru_s *pre_stru_p, pr_info("=====mcvecwr mif:\n"); dump_mc_mif_state(&pre_stru_p->di_mcvecwr_mif); pr_info("======post mif status======\n"); - pr_info("DI_POST_SIZE=0x%x", Rd(DI_POST_SIZE)); + pr_info("DI_POST_SIZE=0x%x\n", Rd(DI_POST_SIZE)); pr_info("DECOMB_FRM_SIZE=0x%x\n", Rd(0x2d8f)); pr_info("=====if0 mif:\n"); + pr_info("DI_IF0_GEN_REG=0x%x\n", Rd(0x2030)); dump_mif_state(&post_stru_p->di_buf0_mif); pr_info("=====if1 mif:\n"); + pr_info("DI_IF1_GEN_REG=0x%x\n", Rd(0x17e8)); dump_mif_state(&post_stru_p->di_buf1_mif); pr_info("=====if2 mif:\n"); + pr_info("DI_IF2_GEN_REG=0x%x\n", Rd(0x2010)); dump_mif_state(&post_stru_p->di_buf2_mif); pr_info("=====diwr mif:\n"); dump_simple_mif_state(&post_stru_p->di_diwr_mif); @@ -507,9 +533,9 @@ void dump_mif_size_state(struct di_pre_stru_s *pre_stru_p, pr_info("=====mcvecrd mif:\n"); dump_mc_mif_state(&post_stru_p->di_mcvecrd_mif); pr_info("======pps size status======\n"); - pr_info("DI_SC_LINE_IN_LENGTH=0x%x", Rd(0x3751)); + pr_info("DI_SC_LINE_IN_LENGTH=0x%x\n", Rd(0x3751)); pr_info("DI_SC_PIC_IN_HEIGHT=0x%x\n", Rd(0x3752)); - pr_info("DI_HDR_IN_HSIZE=0x%x", Rd(0x376e)); + pr_info("DI_HDR_IN_HSIZE=0x%x\n", Rd(0x376e)); pr_info("DI_HDR_IN_VSIZE=0x%x\n", Rd(0x376f)); } void dump_di_buf(struct di_buf_s *di_buf) @@ -626,27 +652,16 @@ void dump_pre_mif_state(void) Wr_reg_bits(DI_CHAN2_GEN_REG3, 3, 10, 2); pr_info("DI_INP_GEN_REG2=0x%x.\n", Rd(DI_INP_GEN_REG2)); pr_info("DI_INP_GEN_REG3=0x%x.\n", Rd(DI_INP_GEN_REG3)); - pr_info("DI_INP_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_INP_LUMA_FIFO_SIZE)); - pr_info("DI_INP_RANGE_MAP_Y=0x%x.\n", Rd(DI_INP_RANGE_MAP_Y)); - pr_info("DI_INP_RANGE_MAP_CB=0x%x.\n", Rd(DI_INP_RANGE_MAP_CB)); - pr_info("DI_INP_RANGE_MAP_CR=0x%x.\n", Rd(DI_INP_RANGE_MAP_CR)); - pr_info("DI_INP_URGENT_CTRL=0x%x.\n", Rd(DI_INP_URGENT_CTRL)); for (i = 0; i < 10; i++) pr_info("0x%x=0x%x.\n", 0x17ce + i, Rd(0x17ce + i)); pr_info("DI_MEM_GEN_REG2=0x%x.\n", Rd(DI_MEM_GEN_REG2)); pr_info("DI_MEM_GEN_REG3=0x%x.\n", Rd(DI_MEM_GEN_REG3)); pr_info("DI_MEM_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_MEM_LUMA_FIFO_SIZE)); - pr_info("DI_MEM_RANGE_MAP_CB=0x%x.\n", Rd(DI_MEM_RANGE_MAP_CB)); - pr_info("DI_MEM_RANGE_MAP_CR=0x%x.\n", Rd(DI_MEM_RANGE_MAP_CR)); - pr_info("DI_MEM_URGENT_CTRL=0x%x.\n", Rd(DI_MEM_URGENT_CTRL)); for (i = 0; i < 10; i++) pr_info("0x%x=0x%x.\n", 0x17db + i, Rd(0x17db + i)); pr_info("DI_CHAN2_GEN_REG2=0x%x.\n", Rd(DI_CHAN2_GEN_REG2)); pr_info("DI_CHAN2_GEN_REG3=0x%x.\n", Rd(DI_CHAN2_GEN_REG3)); pr_info("DI_CHAN2_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_CHAN2_LUMA_FIFO_SIZE)); - pr_info("DI_CHAN2_RANGE_MAP_CB=0x%x.\n", Rd(DI_CHAN2_RANGE_MAP_CB)); - pr_info("DI_CHAN2_RANGE_MAP_CR=0x%x.\n", Rd(DI_CHAN2_RANGE_MAP_CR)); - pr_info("DI_CHAN2_URGENT_CTRL=0x%x.\n", Rd(DI_CHAN2_URGENT_CTRL)); for (i = 0; i < 10; i++) pr_info("0x%x=0x%x.\n", 0x17f5 + i, Rd(0x17f5 + i)); } diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index 0323f12db1d8..1090e87c8651 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -126,6 +126,7 @@ static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent, int hold_line, int vskip_cnt, int wr_en); +static void post_frame_reset_g12a(void); static void ma_di_init(void) { @@ -183,6 +184,8 @@ void init_field_mode(unsigned short height) DI_Wr(DIPD_COMB_CTRL5, 0x04040804); if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) DI_Wr(DIPD_COMB_CTRL6, 0x00107064); + DI_Wr_reg_bits(DI_MC_32LVL0, 16, 0, 8); + DI_Wr_reg_bits(DI_MC_22LVL0, 256, 0, 16); } static void mc_pd22_check_irq(void) @@ -413,6 +416,8 @@ static void pre_hold_block_mode_config(void) } } +static unsigned short line_num_post_frst = 5; +static unsigned short line_num_pre_frst = 5; void di_hw_init(bool pd_enable, bool mc_enable) { unsigned short fifo_size_vpp = 0xc0; @@ -465,9 +470,11 @@ void di_hw_init(bool pd_enable, bool mc_enable) pre_hold_block_mode_config(); - if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { DI_Wr(DI_PRE_HOLD, 0); - else + /* go field after 2 lines */ + DI_Wr(DI_PRE_GL_CTRL, (0x80000000|line_num_pre_frst)); + } else DI_Wr(DI_PRE_HOLD, (1 << 31) | (31 << 16) | 31); ma_di_init(); @@ -537,9 +544,6 @@ static void set_ma_pre_mif(struct DI_SIM_MIF_s *mtnwr_mif, RDMA_WR(DI_CONTWR_CTRL, contwr_mif->canvas_num| (urgent << 8));/* urgent. */ } - -static bool ma_mif_dbg; -module_param_named(ma_mif_dbg, ma_mif_dbg, bool, 0644); static void set_ma_pre_mif_g12(struct DI_SIM_MIF_s *mtnwr_mif, struct DI_SIM_MIF_s *contprd_mif, struct DI_SIM_MIF_s *contp2rd_mif, @@ -585,29 +589,6 @@ static void set_ma_pre_mif_g12(struct DI_SIM_MIF_s *mtnwr_mif, (contwr_mif->end_y - contwr_mif->start_y), 0, 13); RDMA_WR_BITS(CONTWR_CAN_SIZE, (contwr_mif->end_x - contwr_mif->start_x), 16, 13); - if (ma_mif_dbg) { - pr_info("contrd x<%u, %u> y<%u %u>.\n", - contprd_mif->start_x, - contprd_mif->end_x, - contprd_mif->start_y, - contprd_mif->end_y); - pr_info("cont2rd x<%u, %u> y<%u %u>.\n", - contp2rd_mif->start_x, - contp2rd_mif->end_x, - contp2rd_mif->start_y, - contp2rd_mif->end_y); - pr_info("mtnwr x<%u, %u> y<%u %u>.\n", - mtnwr_mif->start_x, - mtnwr_mif->end_x, - mtnwr_mif->start_y, - mtnwr_mif->end_y); - pr_info("contwr x<%u, %u> y<%u %u>.\n", - contwr_mif->start_x, - contwr_mif->end_x, - contwr_mif->start_y, - contwr_mif->end_y); - ma_mif_dbg = false; - } } static void set_di_nrwr_mif(struct DI_SIM_MIF_s *nrwr_mif, @@ -629,8 +610,35 @@ static void set_di_nrwr_mif(struct DI_SIM_MIF_s *nrwr_mif, RDMA_WR_BITS(DI_NRWR_CTRL, 0x3, 22, 2); } -static bool cont_en = true; -static bool mtn_en = true; +void di_interrupt_ctrl(unsigned char vf_type, + 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); + } + /* 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); + 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 */ + RDMA_WR_BITS(DI_INTR_CTRL, 0xffff, 0, 16); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + RDMA_WR_BITS(DI_INTR_CTRL, 3, 30, 2); + else + RDMA_WR_BITS(DI_INTR_CTRL, 0, 30, 2); +} + static unsigned int pre_ctrl; void enable_di_pre_aml( struct DI_MIF_s *di_inp_mif, @@ -666,46 +674,25 @@ void enable_di_pre_aml( di_mem_mif->luma_x_start0 + 1; mem_vsize = di_mem_mif->luma_y_end0 - di_mem_mif->luma_y_start0 + 1; - - if ((chan2_hsize != nrwr_hsize) || (chan2_vsize != nrwr_vsize)) { + if ((chan2_hsize != nrwr_hsize) || (chan2_vsize != nrwr_vsize)) chan2_disable = true; - pr_info("[DI] pre size not match bypass chan2.\n"); - } - if ((mem_hsize != nrwr_hsize) || (mem_vsize != nrwr_vsize)) { + if ((mem_hsize != nrwr_hsize) || (mem_vsize != nrwr_vsize)) mem_bypass = true; - pr_info("[DI] pre size not match bypass mem.\n"); - } - if (madi_en) { - /* - * not mask cont wr & mtn wr interrupt - */ - RDMA_WR_BITS(DI_INTR_CTRL, cont_en?0:1, 20, 1); - RDMA_WR_BITS(DI_INTR_CTRL, mtn_en?0:1, 17, 1); - /* - * enable contwr txt - */ - RDMA_WR_BITS(DI_MTN_1_CTRL1, 5, 29, 3); - } else { - /* - * mask cont wr & mtn wr interrupt - */ - RDMA_WR_BITS(DI_INTR_CTRL, 1, 20, 1); - RDMA_WR_BITS(DI_INTR_CTRL, 1, 17, 1); - /* - * disable contwr txt - */ - RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 29, 3); - } + /* + * enable&disable contwr txt + */ + RDMA_WR_BITS(DI_MTN_1_CTRL1, madi_en?5:0, 29, 3); if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { if (madi_en) { set_ma_pre_mif_g12(di_mtnwr_mif, - di_contp2rd_mif, di_contprd_mif, + di_contp2rd_mif, di_contwr_mif, pre_urgent); + } else { + chan2_disable = true; } - RDMA_WR_BITS(DI_PRE_CTRL, pre_field_num, 29, 1); RDMA_WR_BITS(DI_PRE_GL_THD, pre_hold_line, 16, 6); if (pre_ctrl) RDMA_WR_BITS(DI_PRE_CTRL, pre_ctrl, 0, 29); @@ -720,21 +707,21 @@ void enable_di_pre_aml( /* hist check use data before noise reduction. */ ((chan2_disable ? 0 : 1) << 8)| /* chan 2 enable for 2:2 pull down check.*/ - (madi_en << 9) |/* line buffer 2 enable */ + ((chan2_disable ? 0 : 1) << 9) |/* line buffer 2 enable */ (0 << 10) | /* pre drop first. */ - (0 << 11) | /* di pre repeat */ + (1 << 11) | /* mem enable */ (0 << 12) | /* pre viu link */ (pre_vdin_link << 13) | (pre_vdin_link << 14) |/* pre go line link */ (1 << 22) |/* MTN after NR. */ - (madi_en << 25) |/* contrd en */ - (mem_bypass ? 1 : 0) << 28 - ); + (0 << 25) |/* contrd en */ + ((mem_bypass ? 1 : 0) << 28) | + pre_field_num << 29); } else { if (madi_en) { set_ma_pre_mif(di_mtnwr_mif, - di_contp2rd_mif, di_contprd_mif, + di_contp2rd_mif, di_contwr_mif, pre_urgent); } RDMA_WR(DI_PRE_CTRL, 1 | /* nr enable */ @@ -765,18 +752,7 @@ void enable_di_pre_aml( * after g12a, framereset will not reset simple * wr mif of pre such as mtn&cont&mv&mcinfo wr */ -void reset_pre_simple_mif(void) -{ - RDMA_WR_BITS(CONTWR_CAN_SIZE, 1, 14, 1); - RDMA_WR_BITS(MTNWR_CAN_SIZE, 1, 14, 1); - RDMA_WR_BITS(MCVECWR_CAN_SIZE, 1, 14, 1); - RDMA_WR_BITS(MCINFWR_CAN_SIZE, 1, 14, 1); - RDMA_WR_BITS(CONTWR_CAN_SIZE, 0, 14, 1); - RDMA_WR_BITS(MTNWR_CAN_SIZE, 0, 14, 1); - RDMA_WR_BITS(MCVECWR_CAN_SIZE, 0, 14, 1); - RDMA_WR_BITS(MCINFWR_CAN_SIZE, 0, 14, 1); -} void enable_afbc_input(struct vframe_s *vf) { @@ -855,8 +831,7 @@ void enable_mc_di_pre_g12(struct DI_MC_MIF_s *mcinford_mif, struct DI_MC_MIF_s *mcvecwr_mif, unsigned char mcdi_en) { - /* enable int of mcdi */ - RDMA_WR_BITS(DI_INTR_CTRL, mcdi_en?0:7, 21, 3); + RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en?3:0), 0, 2); RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? 0x1bfff7ff : 0)); @@ -894,8 +869,7 @@ void enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif, ctrl_mode = (me_auto_en ? 0x1bfff7ff : 0x1bfe37ff); RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? ctrl_mode : 0)); RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en?3:0), 0, 2); - /* mask mcve&mcinfo&me interrupt */ - RDMA_WR_BITS(DI_INTR_CTRL, mcdi_en?0:7, 21, 3); + RDMA_WR(MCDI_MCVECWR_X, di_mcvecwr_mif->size_x); RDMA_WR(MCDI_MCVECWR_Y, di_mcvecwr_mif->size_y); @@ -948,17 +922,21 @@ void enable_mc_di_post_g12(struct DI_MC_MIF_s *mcvecrd_mif, DI_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL2, urgent, 16, 1); DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcvecrd_mif->vecrd_offset, 12, 3); - if (mcvecrd_mif->blend_en) + if (mcvecrd_mif->blend_en) { DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcen_mode, 0, 2); - else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 3, 18, 2); + } else { DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 2, 18, 2); + } DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcuv_en, 10, 1); - DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1); DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, invert_mv, 17, 1); - DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, - 3, 18, 2); - DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcdebug_mode, 2, 3); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcdebug_mode, 2, 3); } void enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif, @@ -2092,7 +2070,8 @@ void initial_di_post_2(int hsize_post, int vsize_post, DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_X, (hsize_post-1)); if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { if (post_write_en) { - DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x80000005); + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, + 0x80000000|line_num_post_frst); DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 20, 1); DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, @@ -2234,13 +2213,11 @@ void di_post_switch_buffer( di_buf2_mif->bit_mode, di_diwr_mif->bit_mode); } - if ((pldn_ctrl_rflsh == 1) && pd_enable) { - DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_en, 31, 1); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_en, 31, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode, 20, 2); + if ((pldn_ctrl_rflsh == 1) && pd_enable) DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); - DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode, 20, 2); - } else - DI_VSYNC_WR_MPEG_REG(DI_BLEND_CTRL, Rd(DI_BLEND_CTRL)| - (blend_en<<31) | (blend_mode<<20) | 0x1c0001f); if (mc_enable) { if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) @@ -2248,12 +2225,19 @@ void di_post_switch_buffer( invert_mv, 17, 1);/* invert mv */ DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, di_mcvecrd_mif->vecrd_offset, 12, 3); - if (di_mcvecrd_mif->blend_en) + if (di_mcvecrd_mif->blend_en) { DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcen_mode, 0, 2); - else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1); DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, - 0, 0, 2); + 3, 18, 2); + } else { + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 0, 0, 2); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 2, 18, 2); + } } if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { DI_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD, @@ -2287,10 +2271,9 @@ void di_post_switch_buffer( ); } - if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) { - DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0xc0200005); - DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x80200005); - } else if (di_ddr_en && mc_enable) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) + post_frame_reset_g12a(); + else if (di_ddr_en && mc_enable) DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1); } @@ -2358,8 +2341,12 @@ void enable_di_post_2( set_di_if1_mif(di_buf1_mif, di_vpp_en, hold_line, vskip_cnt); if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { - set_di_if2_mif(di_buf2_mif, - di_vpp_en, hold_line, vskip_cnt); + if (blend_en) { + set_di_if2_mif(di_buf2_mif, + di_vpp_en, hold_line, vskip_cnt); + } else { + DI_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, 0); + } } /* motion for current display field. */ if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) @@ -2417,10 +2404,8 @@ void enable_di_post_2( (0x3 << 30) /* post soft rst post frame rst. */ ); - if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) { - DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0xc0200005); - DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x80200005); - } + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) + post_frame_reset_g12a(); } void disable_post_deinterlace_2(void) @@ -2441,6 +2426,7 @@ void disable_post_deinterlace_2(void) * Rd(DI_IF1_GEN_REG) & 0xfffffffe); */ if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0); DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 8, 2); DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 20, 2); } @@ -2458,18 +2444,18 @@ void enable_di_post_mif(enum gate_mode_e mode) gate = 2; break; case GATE_AUTO: - gate = 0; + gate = 2; break; default: gate = 0; } if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { /* enable if0 external gate freerun hw issue */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, ((gate == 0)?2:gate), 2, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 2, 2); /* enable if1 external gate freerun hw issue */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, ((gate == 0)?2:gate), 4, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 4, 2); /* enable if1 external gate freerun hw issue */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, ((gate == 0)?2:gate), 6, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 6, 2); /* enable di wr external gate */ DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 8, 2); /* enable mtn rd external gate */ @@ -2577,29 +2563,75 @@ void read_new_pulldown_info(struct FlmModReg_t *pFMReg) for (i = 0; i < 9; i++) pFMReg->rROCmbInf[i] = Rd(DIPD_RO_COMB_12+i); } - -void di_post_read_reverse(bool reverse, bool mc_enable) +/* + * DIPD_RO_COMB_0~DIPD_RO_COMB11 and DI_INFO_DATA + * will be reset, so call this function after all + * data have be fetched + */ +void pulldown_info_clear_g12a(void) { - if (reverse) { - DI_Wr_reg_bits(DI_IF1_GEN_REG2, 3, 2, 2); - DI_Wr_reg_bits(VD1_IF0_GEN_REG2, 0xf, 2, 4); - DI_Wr_reg_bits(VD2_IF0_GEN_REG2, 0xf, 2, 4); - if (mc_enable) { - /* motion vector read reverse*/ - DI_Wr_reg_bits(MCDI_MCVECRD_X, 1, 30, 1); - DI_Wr_reg_bits(MCDI_MCVECRD_Y, 1, 30, 1); - DI_Wr_reg_bits(MCDI_MC_CRTL, 0, 8, 1); - } - } else { - DI_Wr_reg_bits(DI_IF1_GEN_REG2, 0, 2, 2); - DI_Wr_reg_bits(VD1_IF0_GEN_REG2, 0, 2, 4); - DI_Wr_reg_bits(VD2_IF0_GEN_REG2, 0, 2, 4); - if (mc_enable) { - DI_Wr_reg_bits(MCDI_MCVECRD_X, 0, 30, 1); - DI_Wr_reg_bits(MCDI_MCVECRD_Y, 0, 30, 1); - DI_Wr_reg_bits(MCDI_MC_CRTL, 1, 8, 1); - } + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + RDMA_WR_BITS(DI_PRE_CTRL, 1, 30, 1); +} + +/* + * frame reset for pre which have nothing with encoder + * go field + */ +void pre_frame_reset_g12a(unsigned char madi_en, unsigned char mcdi_en) +{ + unsigned int reg_val = 0; + + if (madi_en || mcdi_en) { + RDMA_WR_BITS(CONTRD_CTRL2, 1, 31, 1); + RDMA_WR_BITS(CONT2RD_CTRL2, 1, 31, 1); + RDMA_WR_BITS(MCINFRD_CTRL2, 1, 31, 1); + reg_val = RDMA_RD(DI_PRE_CTRL); + if (madi_en) + reg_val |= (1<<25); + if (mcdi_en) + reg_val |= (1<<10); + /* enable cont rd&mcinfo rd, manual start */ + RDMA_WR(DI_PRE_CTRL, reg_val); + RDMA_WR_BITS(CONTRD_CTRL2, 0, 31, 1); + RDMA_WR_BITS(CONT2RD_CTRL2, 0, 31, 1); + RDMA_WR_BITS(MCINFRD_CTRL2, 0, 31, 1); + /* reset simple mif which framereset not cover */ + RDMA_WR_BITS(CONTWR_CAN_SIZE, 1, 14, 1); + RDMA_WR_BITS(MTNWR_CAN_SIZE, 1, 14, 1); + RDMA_WR_BITS(MCVECWR_CAN_SIZE, 1, 14, 1); + RDMA_WR_BITS(MCINFWR_CAN_SIZE, 1, 14, 1); + + RDMA_WR_BITS(CONTWR_CAN_SIZE, 0, 14, 1); + RDMA_WR_BITS(MTNWR_CAN_SIZE, 0, 14, 1); + RDMA_WR_BITS(MCVECWR_CAN_SIZE, 0, 14, 1); + RDMA_WR_BITS(MCINFWR_CAN_SIZE, 0, 14, 1); } + + reg_val = 0xc3200000 | line_num_pre_frst; + RDMA_WR(DI_PRE_GL_CTRL, reg_val); + reg_val = 0x83200000 | line_num_pre_frst; + RDMA_WR(DI_PRE_GL_CTRL, reg_val); +} +/* + * frame + soft reset for the pre modules + */ +void pre_frame_reset(void) +{ + RDMA_WR_BITS(DI_PRE_CTRL, 3, 30, 2); +} +/* + * frame reset for post which have nothing with encoder + * go field + */ +static void post_frame_reset_g12a(void) +{ + unsigned int reg_val = 0; + + reg_val = (0xc0200000|line_num_post_frst); + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val); + reg_val = (0x80200000|line_num_post_frst); + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val); } static bool if2_disable; @@ -2720,7 +2752,7 @@ void di_top_gate_control(bool top_en, bool mc_en) /* enable slow clk */ DI_Wr_reg_bits(VIUB_GCLK_CTRL0, mc_en?1:0, 10, 1); /* enable di arb */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 0, 0, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 0, 2); } else { /* disable clkb input */ DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 0, 1); @@ -2746,15 +2778,15 @@ void di_pre_gate_control(bool gate, bool mc_enable) /* enable deband clk gate freerun for hw issue */ DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 6, 2); /* enable input mif external gate */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 0, 16, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 16, 2); /* enable mem mif external gate */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 0, 18, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 18, 2); /* enable chan2 mif external gate */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 0, 20, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 20, 2); /* enable nr wr mif external gate */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 0, 22, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 22, 2); /* enable mtn wr mif external gate */ - DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 0, 24, 2); + DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 24, 2); if (mc_enable) { if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 0, 12, 2); @@ -2766,7 +2798,7 @@ void di_pre_gate_control(bool gate, bool mc_enable) * mif external gate */ DI_Wr_reg_bits(VIUB_GCLK_CTRL1, - 0, 26, 2); + 2, 26, 2); } /* cowork with auto gate to config reg */ DI_Wr_reg_bits(DI_PRE_CTRL, 3, 2, 2); @@ -2839,7 +2871,7 @@ static void mc_pre_mif_ctrl_g12(bool enable) mif_ctrl = enable ? 1 : 0; /* enable mcinfo rd mif */ - RDMA_WR_BITS(DI_PRE_CTRL, mif_ctrl, 10, 1); + RDMA_WR_BITS(DI_PRE_CTRL, 0, 10, 1); /* enable mv wr mif */ RDMA_WR_BITS(MCVECWR_CTRL, mif_ctrl, 12, 1); /* enable mcinfo wr mif */ @@ -2879,11 +2911,10 @@ static void ma_pre_mif_ctrl_g12(bool enable) { if (enable) { /* enable cont wr mif */ - RDMA_WR_BITS(CONTWR_CTRL, cont_en?1:0, 12, 1); + RDMA_WR_BITS(CONTWR_CTRL, 1, 12, 1); /* enable mtn wr mif */ - RDMA_WR_BITS(MTNWR_CTRL, mtn_en?1:0, 12, 1); + RDMA_WR_BITS(MTNWR_CTRL, 1, 12, 1); /* enable cont rd mif */ - RDMA_WR_BITS(DI_PRE_CTRL, cont_en?1:0, 25, 1); } else { RDMA_WR_BITS(MTNWR_CTRL, 0, 12, 1); RDMA_WR_BITS(CONTWR_CTRL, 0, 12, 1); @@ -3058,14 +3089,11 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr) value, Rd(addr) != value?"fail":"success"); } } -#ifndef DEBUG_SUPPORT -#define DEBUG_SUPPORT -#endif #ifdef DEBUG_SUPPORT module_param_named(pre_mif_gate, pre_mif_gate, bool, 0644); module_param_named(pre_urgent, pre_urgent, ushort, 0644); -module_param_named(pre_hold_line, pre_urgent, ushort, 0644); +module_param_named(pre_hold_line, pre_hold_line, ushort, 0644); module_param_named(pre_ctrl, pre_ctrl, uint, 0644); -module_param_named(cont_en, cont_en, bool, 0644); -module_param_named(mtn_en, mtn_en, bool, 0644); +module_param_named(line_num_post_frst, line_num_post_frst, ushort, 0644); +module_param_named(line_num_pre_frst, line_num_pre_frst, ushort, 0644); #endif diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index 53672d2eba5b..11d0f1154509 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -92,7 +92,7 @@ struct di_pq_parm_s { void read_pulldown_info(unsigned int *glb_frm_mot_num, unsigned int *glb_fid_mot_num); void read_new_pulldown_info(struct FlmModReg_t *pFMRegp); - +void pulldown_info_clear_g12a(void); void combing_pd22_window_config(unsigned int width, unsigned int height); void di_hw_init(bool pulldown_en, bool mc_enable); void di_hw_uninit(void); @@ -151,7 +151,6 @@ void di_post_switch_buffer( int invert_mv, bool pd_en, bool mc_enable, int vskip_cnt ); -void di_post_read_reverse(bool reverse, bool mc_enable); void di_post_read_reverse_irq(bool reverse, unsigned char mc_pre_flag, bool mc_enable); void di_top_gate_control(bool top_en, bool mc_en); @@ -160,7 +159,6 @@ void di_post_gate_control(bool gate); void diwr_set_power_control(unsigned char enable); void di_hw_disable(bool mc_enable); void enable_di_pre_mif(bool enable, bool mc_enable); -void reset_pre_simple_mif(void); 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); @@ -170,4 +168,9 @@ 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); 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, + unsigned char det3d_en, unsigned char nrds_en, + unsigned char post_wr, unsigned char mc_en); #endif diff --git a/drivers/amlogic/media/deinterlace/film_mode_fmw/Makefile b/drivers/amlogic/media/deinterlace/film_mode_fmw/Makefile deleted file mode 100644 index 5448575d5ecb..000000000000 --- a/drivers/amlogic/media/deinterlace/film_mode_fmw/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -ifeq ($(TARGET_BUILD_VARIANT),userdebug) -ccflags-y := -D DEBUG_SUPPORT -endif -obj-y += film_mode.o -film_mode-objs += vof_soft_top.o -film_mode-objs += flm_mod_xx.o -film_mode-objs += film_fw1.o diff --git a/drivers/amlogic/media/deinterlace/nr_downscale.c b/drivers/amlogic/media/deinterlace/nr_downscale.c index dbc9811a2747..5008baf449fa 100644 --- a/drivers/amlogic/media/deinterlace/nr_downscale.c +++ b/drivers/amlogic/media/deinterlace/nr_downscale.c @@ -134,7 +134,6 @@ void nr_ds_mif_config(void) NR_DS_WIDTH, NR_DS_HEIGHT, 0, 0); RDMA_WR_BITS(NRDSWR_CTRL, nrds_dev.canvas_idx, 0, 8); - RDMA_WR_BITS(DI_PRE_CTRL, 1, 11, 1); nr_ds_hw_ctrl(true); } diff --git a/drivers/amlogic/media/deinterlace/nr_drv.c b/drivers/amlogic/media/deinterlace/nr_drv.c index 69bc081d8b99..0d2faa108ca2 100644 --- a/drivers/amlogic/media/deinterlace/nr_drv.c +++ b/drivers/amlogic/media/deinterlace/nr_drv.c @@ -316,7 +316,7 @@ static void nr4_config(struct NR4_PARM_s *nr4_parm_p, DI_Wr_reg_bits(NR4_TOP_CTRL, 1, 16, 1); DI_Wr_reg_bits(NR4_TOP_CTRL, 1, 18, 1); DI_Wr_reg_bits(NR4_TOP_CTRL, 1, 3, 1); - DI_Wr_reg_bits(NR4_TOP_CTRL, (val&0x1), 5, 1); + DI_Wr_reg_bits(NR4_TOP_CTRL, 1, 5, 1); nr4_parm_p->width = width - val - val - 1; nr4_parm_p->height = height - val - val - 1; } @@ -350,9 +350,11 @@ static void linebuffer_config(unsigned short width) static void nr2_config(unsigned short width, unsigned short height) { - if (is_meson_txlx_cpu() || is_meson_g12a_cpu()) + if (is_meson_txlx_cpu() || is_meson_g12a_cpu()) { DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 2, 1); - else { + DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 15, 1); + DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 17, 1); + } else { /*set max height to disable nfram cnt in cue*/ if (is_meson_gxlx_cpu()) DI_Wr(NR2_FRM_SIZE, (0xfff<<16)|width); diff --git a/drivers/amlogic/media/deinterlace/register.h b/drivers/amlogic/media/deinterlace/register.h index 4b1638585634..fa3f2202fc2f 100644 --- a/drivers/amlogic/media/deinterlace/register.h +++ b/drivers/amlogic/media/deinterlace/register.h @@ -53,6 +53,11 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, #define VIUB_GCLK_CTRL1 0x2008 #define VIUB_GCLK_CTRL2 0x2009 #define VIUB_GCLK_CTRL3 0x200a +/* g12a add debug reg */ +#define DI_DBG_CTRL 0x200b +#define DI_DBG_CTRL1 0x200c +#define DI_DBG_SRDY_INF 0x200d +#define DI_DBG_RRDY_INF 0x200e /* txl add if2 */ #define DI_IF2_GEN_REG 0x2010 #define DI_IF2_CANVAS0 0x2011 diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 33349cf0dcfa..1307d3151dd3 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -2185,7 +2185,8 @@ static void vsync_toggle_frame(struct vframe_s *vf) VSYNC_WR_MPEG_REG(AFBC_BODY_BADDR, vf->compBodyAddr>>4); } if ((vf->canvas0Addr != 0) && - (DI_POST_REG_RD(DI_IF1_GEN_REG) & 0x1) == 0) { + (DI_POST_REG_RD(DI_POST_CTRL) & 0x1000) == 0) { + #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA if (vf->canvas0Addr != (u32)-1) { canvas_copy(vf->canvas0Addr & 0xff,