diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 5dbc68c7ead6..ed5595e80666 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -105,7 +105,7 @@ static int mpeg2vdin_en; #endif static int queue_print_flag = -1; -static int di_reg_unreg_cnt = 100; +static int di_reg_unreg_cnt = 1000; static bool overturn; static bool check_start_drop_prog; static bool mcpre_en = true; @@ -113,7 +113,7 @@ static bool mcpre_en = true; static bool mc_mem_alloc; static unsigned int di_pre_rdma_enable; - +static struct mutex di_event_mutex; static unsigned int di_force_bit_mode = 10; module_param(di_force_bit_mode, uint, 0664); @@ -129,7 +129,7 @@ static di_dev_t *de_devp; static dev_t di_devno; static struct class *di_clsp; -static const char version_s[] = "2019-03-18a"; +static const char version_s[] = "2019-0422b:vscale_skip v is odd"; static int bypass_state = 1; static int bypass_all; @@ -272,6 +272,8 @@ static int di_receiver_event_fun(int type, void *data, void *arg); static void di_uninit_buf(unsigned int disable_mirror); static void log_buffer_state(unsigned char *tag); /* static void put_get_disp_buf(void); */ +static unsigned int isbypass_flag = true; +static unsigned int needbypass_flag = true; static const struct vframe_receiver_op_s di_vf_receiver = { @@ -526,27 +528,57 @@ int get_di_dump_state_flag(void) } /*--------------------------*/ +static void parse_param_di(char *buf_orig, char **parm) +{ + char *ps, *token; + unsigned int n = 0; + char delim1[3] = " "; + char delim2[2] = "\n"; + + ps = buf_orig; + strcat(delim1, delim2); + while (1) { + token = strsep(&ps, delim1); + if (token == NULL) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } +} + static ssize_t store_dbg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + u32 val; + char *buf_orig, *parm[8] = {NULL}; + + buf_orig = kstrdup(buf, GFP_KERNEL); + parse_param_di(buf_orig, (char **)&parm); if (strncmp(buf, "buf", 3) == 0) { struct di_buf_s *di_buf_tmp = 0; - if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp)) + if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp)) { + kfree(buf_orig); return count; + } dump_di_buf(di_buf_tmp); } else if (strncmp(buf, "vframe", 6) == 0) { vframe_t *vf = 0; - if (kstrtoul(buf + 6, 16, (unsigned long *)&vf)) + if (kstrtoul(buf + 6, 16, (unsigned long *)&vf)) { + kfree(buf_orig); return count; + } dump_vframe(vf); } else if (strncmp(buf, "pool", 4) == 0) { unsigned long idx = 0; - if (kstrtoul(buf + 4, 10, &idx)) + if (kstrtoul(buf + 4, 10, &idx)) { + kfree(buf_orig); return count; + } dump_pool(get_queue_by_idx(idx)); } else if (strncmp(buf, "state", 4) == 0) { dump_state(); @@ -576,12 +608,17 @@ store_dbg(struct device *dev, } else if (strncmp(buf, "pstep", 5) == 0) { pre_run_flag = DI_RUN_FLAG_STEP; } else if (strncmp(buf, "dumpreg", 7) == 0) { - if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { dump_di_reg_g12(); - else + dump_afbcd_reg(); + } else pr_info("add new debugfs: cat /sys/kernel/debug/di/dumpreg\n"); + } else if (strncmp(buf, "dumpafbc", 8) == 0) { + dump_afbcd_reg(); } else if (strncmp(buf, "dumpmif", 7) == 0) { dump_mif_size_state(&di_pre_stru, &di_post_stru); + } else if (strncmp(buf, "dumppostmif", 11) == 0) { + dump_post_mif_reg(); } else if (strncmp(buf, "recycle_buf", 11) == 0) { recycle_keep_buffer(); } else if (strncmp(buf, "recycle_post", 12) == 0) { @@ -589,10 +626,38 @@ store_dbg(struct device *dev, di_vf_put(di_vf_get(NULL), NULL); } else if (strncmp(buf, "mem_map", 7) == 0) { dump_buf_addr(di_buf_local, MAX_LOCAL_BUF_NUM * 2); + } else if (strncmp(buf, "afbc_on", 7) == 0) { + if (kstrtoint(parm[1], 10, &val) < 0) { + kfree(buf_orig); + return count; + } + if (!val) + afbc_sw(false); + afbc_disable_flag = val > 0 ? 0:1; + pr_info("afbc_disable_flag:%d\n", afbc_disable_flag); } else { - pr_info("DI no support cmd %s!!!\n", buf); + pr_info("DI no support cmd %s\n", buf); + pr_info("supported cmd list:\n"); + pr_info("\t vframe\n"); + pr_info("\t state\n"); + pr_info("\t prog_proc_config 0/1\n"); + pr_info("\t init_flag 0/1\n"); + pr_info("\t run\n"); + pr_info("\t pause\n"); + pr_info("\t step\n"); + pr_info("\t prun\n"); + pr_info("\t ppause\n"); + pr_info("\t pstep\n"); + pr_info("\t dumpreg\n"); + pr_info("\t dumpmif\n"); + pr_info("\t dumppostmif\n"); + pr_info("\t recycle_buf\n"); + pr_info("\t recycle_post\n"); + pr_info("\t mem_map\n"); + pr_info("\t afbc_on 0/1\n"); } + kfree(buf_orig); return count; } static int __init di_read_canvas_reverse(char *str) @@ -1548,6 +1613,7 @@ unsigned char is_bypass(vframe_t *vf_in) int ret = 0; static vframe_t vf_tmp; + isbypass_flag = true; if (di_debug_flag & 0x10000) /* for debugging */ return (di_debug_flag >> 17) & 0x1; @@ -1627,7 +1693,7 @@ unsigned char is_bypass(vframe_t *vf_in) ) return 1; } - + isbypass_flag = false; return 0; } @@ -2072,7 +2138,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) canvas_align_width = 64; - + pr_info("di: %s -S\n", __func__); frame_count = 0; disp_frame_count = 0; cur_post_ready_di_buf = NULL; @@ -2177,46 +2243,62 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) if (prog_flag) { di_buf->canvas_height = canvas_height; - di_buf->nr_adr = de_devp->mem_start + - di_buf_size * i; + + //use reserved memory + if (de_devp->flag_cma == 0) + di_buf->nr_adr = de_devp->mem_start + + di_buf_size * i; + di_buf->canvas_config_flag = 1; } else { di_buf->canvas_height = (canvas_height>>1); di_buf->canvas_height = roundup(di_buf->canvas_height, canvas_align_width); - di_buf->nr_adr = de_devp->mem_start + - di_buf_size * i; - di_buf->mtn_adr = de_devp->mem_start + - di_buf_size * i + - nr_size; - di_buf->cnt_adr = de_devp->mem_start + - di_buf_size * i + - nr_size + mtn_size; - if (mc_mem_alloc) { - di_buf->mcvec_adr = de_devp->mem_start + + //use reserved memory + if (de_devp->flag_cma == 0) { + di_buf->nr_adr = de_devp->mem_start + + di_buf_size * i; + di_buf->mtn_adr = de_devp->mem_start + di_buf_size * i + - nr_size + mtn_size + count_size; - di_buf->mcinfo_adr = - 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); + nr_size; + di_buf->cnt_adr = de_devp->mem_start + + di_buf_size * i + + nr_size + mtn_size; + + if (mc_mem_alloc) { + di_buf->mcvec_adr = + de_devp->mem_start + + di_buf_size * i + + nr_size + mtn_size + + count_size; + di_buf->mcinfo_adr = + 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; + (unsigned short *)tmp; else { di_buf->mcinfo_vaddr = NULL; pr_err("DI: %s vmap fail\n", __func__); } + } } + di_buf->canvas_config_flag = 2; } + di_buf->index = i; di_buf->vframe = &(vframe_local[i]); di_buf->vframe->private_data = di_buf; @@ -2236,8 +2318,11 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) up(&di_sema); } #endif - di_post_mem = de_devp->mem_start + - di_buf_size*de_devp->buf_num_avail; + + //use reserved memory + if (de_devp->flag_cma == 0) + di_post_mem = de_devp->mem_start + + di_buf_size*de_devp->buf_num_avail; if (post_wr_en && post_wr_support) { di_post_buf_size = nr_width * canvas_height * 2; /* pre buffer must 2 more than post buffer */ @@ -2285,8 +2370,11 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) (nr_width << 1); di_buf->canvas_height = canvas_height; di_buf->canvas_config_flag = 1; - di_buf->nr_adr = di_post_mem + - di_post_buf_size*i; + + //use reserved memory + if (de_devp->flag_cma == 0) + di_buf->nr_adr = di_post_mem + + di_post_buf_size*i; } queue_in(di_buf, QUEUE_POST_FREE); } @@ -2298,6 +2386,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) nr_ds_buf_init(de_devp->flag_cma, nrds_mem, &(de_devp->pdev->dev)); } + pr_info("di: %s -E\n", __func__); return 0; } @@ -2456,6 +2545,11 @@ static void dump_state(void) dump_state_flag = 1; pr_info("version %s, init_flag %d, is_bypass %d\n", version_s, init_flag, is_bypass(NULL)); + pr_info("isbypass_flag %d, needbypass_flag %d\n", + isbypass_flag, needbypass_flag); + pr_info("di_pre_stru.bypass_flag=%d\n", + di_pre_stru.bypass_flag); + pr_info("afbcd support %d\n", afbc_is_supported()); pr_info("recovery_flag = %d, recovery_log_reason=%d, di_blocking=%d", recovery_flag, recovery_log_reason, di_blocking); pr_info("recovery_log_queue_idx=%d, recovery_log_di_buf=0x%p\n", @@ -2926,6 +3020,7 @@ static void pre_de_process(void) } else config_di_mif(&di_pre_stru.di_chan2_mif, di_pre_stru.di_chan2_buf_dup_p); + config_di_wr_mif(&di_pre_stru.di_nrwr_mif, &di_pre_stru.di_mtnwr_mif, di_pre_stru.di_wr_buf); @@ -2989,9 +3084,6 @@ static void pre_de_process(void) * we need to only leave one mask open * to prevent multiple entry for de_irq */ - - - enable_di_pre_aml(&di_pre_stru.di_inp_mif, &di_pre_stru.di_mem_mif, &di_pre_stru.di_chan2_mif, @@ -3463,6 +3555,11 @@ module_param_named(pps_position, pps_position, uint, 0644); static unsigned int pre_enable_mask = 3;/*bit0:ma bit1:mc*/ module_param_named(pre_enable_mask, pre_enable_mask, uint, 0644); +static bool pre_hsc_down_en; +module_param_named(pre_hsc_down_en, pre_hsc_down_en, bool, 0644); +static int pre_hsc_down_width = 480; +module_param_named(pre_hsc_down_width, pre_hsc_down_width, int, 0644); + static unsigned char pre_de_buf_config(void) { struct di_buf_s *di_buf = NULL; @@ -3537,10 +3634,18 @@ static unsigned char pre_de_buf_config(void) if (vframe == NULL) return 0; - if (vframe->type & VIDTYPE_COMPRESS) { - vframe->width = vframe->compWidth; - vframe->height = vframe->compHeight; + /*for support compress from dec*/ + if (IS_COMP_MODE(vframe->type)) { + if (IS_VDIN_SRC(vframe->source_type) + && IS_I_SRC(vframe->type)) { + vframe->width = vframe->compWidth; + vframe->height = vframe->compHeight*2; + } else { + vframe->width = vframe->compWidth; + vframe->height = vframe->compHeight; + } } + di_print("DI: get %dth vf[0x%p] from frontend %u ms.\n", di_pre_stru.in_seq, vframe, jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); @@ -3675,15 +3780,25 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); di_buf->vframe->width, di_buf->vframe->height, di_buf->vframe->source_type); - if (di_buf->type & VIDTYPE_COMPRESS) { - di_pre_stru.cur_width = - di_buf->vframe->compWidth; - di_pre_stru.cur_height = - di_buf->vframe->compHeight; + + if (IS_COMP_MODE(di_buf->vframe->type)) { + if (IS_VDIN_SRC(di_buf->vframe->source_type) && + IS_I_SRC(di_buf->vframe->type)) { + di_pre_stru.cur_width = + di_buf->vframe->compWidth; + di_pre_stru.cur_height = + di_buf->vframe->compHeight*2; + } else { + di_pre_stru.cur_width = + di_buf->vframe->compWidth; + di_pre_stru.cur_height = + di_buf->vframe->compHeight; + } } else { di_pre_stru.cur_width = di_buf->vframe->width; di_pre_stru.cur_height = di_buf->vframe->height; } + di_pre_stru.cur_prog_flag = is_progressive(di_buf->vframe); if (di_pre_stru.cur_prog_flag) { @@ -3895,6 +4010,18 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); } } } else { + /*********************************/ + if ((di_buf->vframe->width >= 1920) && + (di_buf->vframe->height >= 1080) && + is_meson_tl1_cpu()) { + if (combing_fix_en) { + combing_fix_en = false; + fix_tl1_1080i_sawtooth_patch(); + } + } else + combing_fix_en = true; + + /*********************************/ if ( di_pre_stru.di_chan2_buf_dup_p == NULL) { di_pre_stru.field_count_for_cont = 0; @@ -3963,7 +4090,11 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); vframe_type_name[di_buf->di_wr_linked_buf->type], di_buf->di_wr_linked_buf->index); #endif - if (di_pre_stru.cur_inp_type & VIDTYPE_COMPRESS) { + + /*for support compress from dec, not from vdin*/ + if (IS_COMP_MODE(di_pre_stru.cur_inp_type) && + (!(di_pre_stru.cur_inp_type & VIDTYPE_VIU_422))) { + /*compress type and not from vdin*/ di_pre_stru.di_inp_buf->vframe->width = di_pre_stru.di_inp_buf->vframe->compWidth; di_pre_stru.di_inp_buf->vframe->height = @@ -3985,7 +4116,15 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); } if (pps_dsth != di_buf->vframe->height) di_buf->vframe->height = pps_dsth; + } else if (de_devp->h_sc_down_en) { + if (pre_hsc_down_width != di_buf->vframe->width) { + pr_info("di: hscd %d to %d\n", di_buf->vframe->width, + pre_hsc_down_width); + di_buf->vframe->width = pre_hsc_down_width; + di_pre_stru.width_bk = pre_hsc_down_width; + } } + if (di_force_bit_mode == 10) { di_buf->vframe->bitdepth |= (BITDEPTH_Y10); if (full_422_pack) @@ -4018,7 +4157,6 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); if (bypass_state == 0) di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; } - if (is_bypass_post()) { if (bypass_post_state == 0) di_pre_stru.source_change_flag = 1; @@ -4742,9 +4880,16 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, di_end_y = zoom_end_y_lines; di_height = di_end_y - di_start_y + 1; di_height = di_height / (di_vscale_skip_count_real + 1); + /* make sure the height is even number */ - if (di_height%2) - di_height++; + if (di_height%2) { + /*for skip mode,post only half line-1*/ + if (((di_height > 150) && (di_height < 1080)) && + di_vscale_skip_count_real) + di_height = di_height - 3; + else + di_height++; + } 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 || @@ -5208,6 +5353,8 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || is_meson_sm1_cpu()) { di_post_read_reverse_irq(overturn, mc_pre_flag, post_blend_en ? mcpre_en : false); @@ -5986,11 +6133,21 @@ static void di_unreg_process_irq(void) #endif adpative_combing_exit(); enable_di_pre_mif(false, mcpre_en); - afbc_reg_sw(false); + /*disable afbc module when afbc working in DI*/ + afbc_reg_unreg_flag = 0; + #if 0 + if (IS_COMP_MODE(di_pre_stru.cur_inp_type) && + (!needbypass_flag && !isbypass_flag)) { + pr_info("DI: disable afbc\n"); + afbc_reg_sw(false); + afbc_input_sw(false); + } + #endif di_hw_uninit(); if (is_meson_txlx_cpu() || is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu() || is_meson_sm1_cpu()) { + || is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) { di_pre_gate_control(false, mcpre_en); nr_gate_control(false); } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { @@ -6003,7 +6160,8 @@ static void di_unreg_process_irq(void) di_hw_disable(mcpre_en); if (is_meson_txlx_cpu() || is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu() || is_meson_sm1_cpu()) { + || is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) { enable_di_post_mif(GATE_OFF); di_post_gate_control(false); di_top_gate_control(false, false); @@ -6116,7 +6274,7 @@ static void di_pre_size_change(unsigned short width, is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu() || + is_meson_tl1_cpu() || is_meson_tm2_cpu() || is_meson_sm1_cpu()) film_mode_win_config(width, height); } @@ -6149,6 +6307,15 @@ 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)); } + + if (de_devp->h_sc_down_en) { + pps_w = di_pre_stru.cur_width; + di_inp_hsc_setting(pps_w, pre_hsc_down_width); + } else { + di_inp_hsc_setting(di_pre_stru.cur_width, + di_pre_stru.cur_width); + } + di_interrupt_ctrl(di_pre_stru.madi_enable, det3d_en?1:0, de_devp->nrds_enable, @@ -6158,6 +6325,7 @@ static void di_pre_size_change(unsigned short width, static bool need_bypass(struct vframe_s *vf) { + needbypass_flag = true; if (vf->type & VIDTYPE_MVC) return true; @@ -6191,6 +6359,7 @@ static bool need_bypass(struct vframe_s *vf) (vf->width > 720)) return true; + needbypass_flag = false; return false; } @@ -6212,6 +6381,7 @@ static void di_reg_process_irq(void) if (pre_run_flag == DI_RUN_FLAG_STEP) pre_run_flag = DI_RUN_FLAG_STEP_DONE; + di_pre_stru.reg_irq_busy = true; vframe = vf_peek(VFM_NAME); @@ -6223,6 +6393,7 @@ static void di_reg_process_irq(void) } di_pre_stru.bypass_flag = true; di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); + di_pre_stru.reg_irq_busy = false; return; } else { di_pre_stru.bypass_flag = false; @@ -6243,6 +6414,8 @@ static void di_reg_process_irq(void) } de_devp->nrds_enable = nrds_en; de_devp->pps_enable = pps_en; + /*di pre h scaling down: sm1 tm2*/ + de_devp->h_sc_down_en = pre_hsc_down_en; switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); if (post_wr_en && post_wr_support) diwr_set_power_control(1); @@ -6311,9 +6484,15 @@ static void di_reg_process_irq(void) spin_unlock_irqrestore(&plist_lock, flags); #endif } + if (!reg_flag) + pr_err("di: warning unreg in reg irq\n"); calc_lmv_init(); first_field_type = (vframe->type & VIDTYPE_TYPEMASK); + + //pr_info("%s , %d\n", __func__, __LINE__); + //pr_info("filed type:0x%x, in H=%d, V=%d\n", + // first_field_type, vframe->width, nr_height); di_pre_size_change(vframe->width, nr_height, first_field_type); @@ -6331,6 +6510,7 @@ static void di_reg_process_irq(void) init_flag = 1; di_pre_stru.reg_req_flag_irq = 1; } + di_pre_stru.reg_irq_busy = false; } static void di_process(void) @@ -6505,11 +6685,14 @@ static int di_task_handle(void *data) di_pre_stru.disable_req_flag) && (di_pre_stru.pre_de_busy == 0)) { di_unreg_process(); + #if 0 + /* if mirror mode, can't speed down the clk*/ /* set min rate for power saving */ if (de_devp->vpu_clkb) { clk_set_rate(de_devp->vpu_clkb, de_devp->clkb_min_rate); } + #endif } if (di_pre_stru.reg_req_flag_irq || di_pre_stru.reg_req_flag) { @@ -6551,7 +6734,7 @@ static int di_task_handle(void *data) } } if (is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu() || + || is_meson_tl1_cpu() || is_meson_tm2_cpu() || is_meson_sm1_cpu()) { #ifdef CLK_TREE_SUPPORT clk_set_rate(de_devp->vpu_clkb, @@ -6615,20 +6798,25 @@ static int di_receiver_event_fun(int type, void *data, void *arg) { int i; ulong flags; + char *provider_name = (char *)data; if (type == VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR) { return di_pre_stru.vdin2nr; } else if (type == VFRAME_EVENT_PROVIDER_UNREG) { + mutex_lock(&di_event_mutex); pr_dbg("%s , is_bypass() %d trick_mode %d bypass_all %d\n", __func__, is_bypass(NULL), trick_mode, bypass_all); - pr_info("%s: vf_notify_receiver unreg\n", __func__); + di_pre_stru.vdin_source = false; + pr_info("DI: %s: unreg\n", __func__); + pr_info("DI: provider name:%s\n", provider_name); di_pre_stru.unreg_req_flag = 1; di_pre_stru.vdin_source = false; trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_UNREG); di_pre_stru.unreg_req_flag_cnt = 0; - while (di_pre_stru.unreg_req_flag) { - usleep_range(10000, 10001); + while (di_pre_stru.unreg_req_flag || + di_pre_stru.reg_irq_busy) { + usleep_range(1000, 1001); if (di_pre_stru.unreg_req_flag_cnt++ > di_reg_unreg_cnt) { reg_unreg_timeout_cnt++; @@ -6655,6 +6843,8 @@ static int di_receiver_event_fun(int type, void *data, void *arg) if (di_pre_stru.vdin_source) DI_Wr_reg_bits(VDIN_WR_CTRL, 0x3, 24, 3); #endif + mutex_unlock(&di_event_mutex); + pr_info("DI: unreg f\n"); } else if (type == VFRAME_EVENT_PROVIDER_RESET) { di_blocking = 1; @@ -6815,14 +7005,17 @@ light_unreg: } #endif } else if (type == VFRAME_EVENT_PROVIDER_REG) { - char *provider_name = (char *)data; char *receiver_name = NULL; + + mutex_lock(&di_event_mutex); if (de_devp->flags & DI_SUSPEND_FLAG) { pr_err("[DI] reg event device hasn't resumed\n"); + mutex_unlock(&di_event_mutex); return -1; } if (reg_flag) { pr_err("[DI] no muti instance.\n"); + mutex_unlock(&di_event_mutex); return -1; } pr_info("%s: vframe provider reg %s\n", __func__, @@ -6830,11 +7023,11 @@ light_unreg: bypass_state = 0; di_pre_stru.reg_req_flag = 1; - trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_REG); + /*check unreg process*/ di_pre_stru.reg_req_flag_cnt = 0; while (di_pre_stru.reg_req_flag) { - usleep_range(10000, 10001); + usleep_range(1000, 1001); if (di_pre_stru.reg_req_flag_cnt++ > di_reg_unreg_cnt) { reg_unreg_timeout_cnt++; pr_dbg("%s:reg_req_flag timeout!!!\n", @@ -6862,6 +7055,8 @@ light_unreg: } else { pr_info("%s error receiver is null.\n", __func__); } + mutex_unlock(&di_event_mutex); + pr_info("DI: reg f\n"); } #ifdef DET3D else if (type == VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE) { @@ -6880,7 +7075,7 @@ light_unreg: return 0; } - +#if 0 static void fast_process(void) { int i; @@ -6937,7 +7132,7 @@ static void fast_process(void) } } } - +#endif static vframe_t *di_vf_peek(void *arg) { vframe_t *vframe_ret = NULL; @@ -6955,7 +7150,7 @@ static vframe_t *di_vf_peek(void *arg) log_buffer_state("pek"); - fast_process(); + /*fast_process();*/ #ifdef SUPPORT_START_FRAME_HOLD if ((disp_frame_count == 0) && (is_bypass(NULL) == 0)) { int ready_count = list_count(QUEUE_POST_READY); @@ -7500,7 +7695,7 @@ static void set_di_flag(void) is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu() || + is_meson_tl1_cpu() || is_meson_tm2_cpu() || is_meson_sm1_cpu()) { mcpre_en = true; mc_mem_alloc = true; @@ -7519,7 +7714,7 @@ static void set_di_flag(void) is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu() || + is_meson_tl1_cpu() || is_meson_tm2_cpu() || is_meson_sm1_cpu()) { full_422_pack = true; } @@ -7532,7 +7727,7 @@ static void set_di_flag(void) } post_hold_line = (is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu() || + || is_meson_tl1_cpu() || is_meson_tm2_cpu() || is_meson_sm1_cpu())?10:17; } else { post_hold_line = 8; /*2019-01-10: from VLSI feijun*/ @@ -7543,6 +7738,8 @@ static void set_di_flag(void) use_2_interlace_buff = 0; di_force_bit_mode = 8; } + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + pulldown_enable = true; if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) intr_mode = 3; if (di_pre_rdma_enable) { @@ -7647,6 +7844,8 @@ static int di_probe(struct platform_device *pdev) "nrds-enable", &(di_devp->nrds_enable)); ret = of_property_read_u32(pdev->dev.of_node, "pps-enable", &(di_devp->pps_enable)); + /*di pre h scaling down :sm1 tm2*/ + di_devp->h_sc_down_en = pre_hsc_down_en; if (di_devp->flag_cma >= 1) { #ifdef CONFIG_CMA @@ -7737,6 +7936,7 @@ static int di_probe(struct platform_device *pdev) device_create_file(di_devp->dev, &dev_attr_secam); pd_device_files_add(di_devp->dev); nr_drv_init(di_devp->dev); + mutex_init(&di_event_mutex); init_flag = 0; reg_flag = 0; diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index 9aa19e26558a..9b9ad1f610ad 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -75,6 +75,16 @@ #endif #endif +#define IS_VDIN_SRC(src) ( \ + (src == VFRAME_SOURCE_TYPE_TUNER) || \ + (src == VFRAME_SOURCE_TYPE_CVBS) || \ + (src == VFRAME_SOURCE_TYPE_COMP) || \ + (src == VFRAME_SOURCE_TYPE_HDMI)) + +#define IS_I_SRC(vftype) (vftype & VIDTYPE_INTERLACE_BOTTOM) + +#define IS_COMP_MODE(vftype) (vftype & VIDTYPE_COMPRESS) + enum process_fun_index_e { PROCESS_FUN_NULL = 0, PROCESS_FUN_DI, @@ -237,6 +247,7 @@ struct di_dev_s { unsigned int post_wr_support; unsigned int nrds_enable; unsigned int pps_enable; + u32 h_sc_down_en;/*sm1, tm2 ...*/ /*struct mutex cma_mutex;*/ unsigned int flag_cma; struct page *total_pages; @@ -289,6 +300,7 @@ struct di_pre_stru_s { int reg_req_flag; int reg_req_flag_irq; int reg_req_flag_cnt; + int reg_irq_busy; int force_unreg_req_flag; int disable_req_flag; /* current source info */ diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c index 63f6102111f2..2a844dcc350a 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c @@ -34,6 +34,7 @@ #include #include "register.h" #include "deinterlace_dbg.h" +#include "deinterlace_hw.h" #include "di_pps.h" #include "nr_downscale.h" #include @@ -254,7 +255,7 @@ void dump_di_reg_g12(void) is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu() || + is_meson_tl1_cpu() || is_meson_tm2_cpu() || is_meson_sm1_cpu()) base_addr = 0xff900000; else @@ -631,7 +632,9 @@ void dump_mif_size_state(struct di_pre_stru_s *pre_stru_p, { pr_info("======pre mif status======\n"); 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("DI_PRE_SIZE H=%d, V=%d\n", + (Rd(DI_PRE_SIZE)>>16)&0xffff, + Rd(DI_PRE_SIZE)&0xffff); pr_info("DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE)); if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { pr_info("CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec)); @@ -1046,6 +1049,27 @@ void dump_buf_addr(struct di_buf_s *di_buf, unsigned int num) } } +void dump_afbcd_reg(void) +{ + u32 i; + u32 afbc_reg; + + pr_info("---- dump afbc eAFBC_DEC0 reg -----\n"); + for (i = 0; i < AFBC_REG_INDEX_NUB; i++) { + afbc_reg = reg_AFBC[eAFBC_DEC0][i]; + pr_info("reg 0x%x val:0x%x\n", afbc_reg, RDMA_RD(afbc_reg)); + } + pr_info("---- dump afbc eAFBC_DEC1 reg -----\n"); + for (i = 0; i < AFBC_REG_INDEX_NUB; i++) { + afbc_reg = reg_AFBC[eAFBC_DEC1][i]; + pr_info("reg 0x%x val:0x%x\n", afbc_reg, RDMA_RD(afbc_reg)); + } + pr_info("reg 0x%x val:0x%x\n", + VD1_AFBCD0_MISC_CTRL, RDMA_RD(VD1_AFBCD0_MISC_CTRL)); + pr_info("reg 0x%x val:0x%x\n", + VD2_AFBCD1_MISC_CTRL, RDMA_RD(VD2_AFBCD1_MISC_CTRL)); +} + /*2018-08-17 add debugfs*/ /*same as dump_state*/ static int seq_file_di_state_show(struct seq_file *seq, void *v) diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h index ab4cbd98f4b1..21e83a9f8291 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h @@ -18,6 +18,8 @@ #define _DI_DBG_H #include "deinterlace.h" +extern const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB]; + void parse_cmd_params(char *buf_orig, char **parm); void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p); void dump_di_post_stru(struct di_post_stru_s *di_post_stru_p); @@ -28,6 +30,7 @@ void dump_di_reg_g12(void); void print_di_buf(struct di_buf_s *di_buf, int format); void dump_pre_mif_state(void); void dump_post_mif_reg(void); +void dump_afbcd_reg(void); void dump_buf_addr(struct di_buf_s *di_buf, unsigned int num); void dump_mif_size_state(struct di_pre_stru_s *pre, struct di_post_stru_s *post); diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index 70fd82712cec..81e613f71df9 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "deinterlace_hw.h" #include "register.h" #include "register_nr4.h" @@ -59,6 +60,7 @@ module_param_named(pq_load_dbg, pq_load_dbg, uint, 0644); static bool pd22_flg_calc_en = true; static unsigned int ctrl_regs[SKIP_CTRE_NUM]; +u32 afbc_disable_flag; #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA extern u32 VSYNC_RD_MPEG_REG(u32 adr); @@ -470,7 +472,8 @@ void di_hw_init(bool pd_enable, bool mc_enable) switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); if (is_meson_txlx_cpu() || is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu() || is_meson_sm1_cpu()) + || is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) di_top_gate_control(true, true); else if (is_meson_gxl_cpu() || is_meson_gxm_cpu() || is_meson_gxlx_cpu()) @@ -484,7 +487,7 @@ void di_hw_init(bool pd_enable, bool mc_enable) is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_sm1_cpu() || - is_meson_tl1_cpu()) { + is_meson_tl1_cpu() || is_meson_tm2_cpu()) { /* vpp fifo max size on txl :128*3=384[0x180] */ /* di fifo max size on txl :96*3=288[0x120] */ fifo_size_vpp = 0x180; @@ -520,7 +523,7 @@ void di_hw_init(bool pd_enable, bool mc_enable) is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_sm1_cpu() || - is_meson_tl1_cpu()) { + is_meson_tl1_cpu() || is_meson_tm2_cpu()) { di_pre_gate_control(true, true); di_post_gate_control(true); } @@ -539,7 +542,7 @@ void di_hw_init(bool pd_enable, bool mc_enable) is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_sm1_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu()) { + is_meson_tl1_cpu() || is_meson_tm2_cpu()) { di_pre_gate_control(false, true); di_post_gate_control(false); di_top_gate_control(false, false); @@ -820,6 +823,96 @@ void enable_di_pre_aml( ); } } + +const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = { + { + AFBC_ENABLE, + AFBC_MODE, + AFBC_SIZE_IN, + AFBC_DEC_DEF_COLOR, + AFBC_CONV_CTRL, + AFBC_LBUF_DEPTH, + AFBC_HEAD_BADDR, + AFBC_BODY_BADDR, + AFBC_SIZE_OUT, + AFBC_OUT_YSCOPE, + AFBC_STAT, + AFBC_VD_CFMT_CTRL, + AFBC_VD_CFMT_W, + AFBC_MIF_HOR_SCOPE, + AFBC_MIF_VER_SCOPE, + AFBC_PIXEL_HOR_SCOPE, + AFBC_PIXEL_VER_SCOPE, + AFBC_VD_CFMT_H, + }, + { + VD2_AFBC_ENABLE, + VD2_AFBC_MODE, + VD2_AFBC_SIZE_IN, + VD2_AFBC_DEC_DEF_COLOR, + VD2_AFBC_CONV_CTRL, + VD2_AFBC_LBUF_DEPTH, + VD2_AFBC_HEAD_BADDR, + VD2_AFBC_BODY_BADDR, + VD2_AFBC_OUT_XSCOPE, + VD2_AFBC_OUT_YSCOPE, + VD2_AFBC_STAT, + VD2_AFBC_VD_CFMT_CTRL, + VD2_AFBC_VD_CFMT_W, + VD2_AFBC_MIF_HOR_SCOPE, + VD2_AFBC_MIF_VER_SCOPE, + VD2_AFBC_PIXEL_HOR_SCOPE, + VD2_AFBC_PIXEL_VER_SCOPE, + VD2_AFBC_VD_CFMT_H, + + }, + +}; + +static enum eAFBC_DEC afbc_get_decnub(void) +{ + enum eAFBC_DEC sel_dec = eAFBC_DEC0; + /* info from vlsi feijun + * gxl:have 1, AFBC_dec0 + * txlx:have 2, di only can use 1 + * g12a:have 2, di can use 2 + * tl1: have 1, AFBC_dec0 + */ + if (is_meson_gxl_cpu()) + sel_dec = eAFBC_DEC0; + else if (is_meson_txlx_cpu()) + sel_dec = eAFBC_DEC1; + else if (is_meson_g12a_cpu()) + sel_dec = eAFBC_DEC1; + else if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + sel_dec = eAFBC_DEC0; + return sel_dec; +} + +static const unsigned int *afbc_get_regbase(void) +{ + return ®_AFBC[afbc_get_decnub()][0]; +} + +bool afbc_is_supported(void) +{ + bool ret = false; + + if (afbc_disable_flag) + return false; + + /*currently support txlx and g12a*/ + if (is_meson_txlx_cpu()) + ret = false; + else if (is_meson_g12a_cpu()) + ret = false; + else if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + ret = true; + + return ret; + +} + /* * after g12a, framereset will not reset simple * wr mif of pre such as mtn&cont&mv&mcinfo wr @@ -904,163 +997,103 @@ void enable_afbc_input(struct vframe_s *vf) } #endif -enum eAFBC_REG { - eAFBC_ENABLE, - eAFBC_MODE, - eAFBC_SIZE_IN, - eAFBC_DEC_DEF_COLOR, - eAFBC_CONV_CTRL, - eAFBC_LBUF_DEPTH, - eAFBC_HEAD_BADDR, - eAFBC_BODY_BADDR, - eAFBC_SIZE_OUT, - eAFBC_OUT_YSCOPE, - eAFBC_STAT, - eAFBC_VD_CFMT_CTRL, - eAFBC_VD_CFMT_W, - eAFBC_MIF_HOR_SCOPE, - eAFBC_MIF_VER_SCOPE, - eAFBC_PIXEL_HOR_SCOPE, - eAFBC_PIXEL_VER_SCOPE, - eAFBC_VD_CFMT_H, -}; -enum eAFBC_DEC { - eAFBC_DEC0, - eAFBC_DEC1, -}; -#define AFBC_REG_INDEX_NUB (18) -#define AFBC_DEC_NUB (2) - -const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = { - { - AFBC_ENABLE, - AFBC_MODE, - AFBC_SIZE_IN, - AFBC_DEC_DEF_COLOR, - AFBC_CONV_CTRL, - AFBC_LBUF_DEPTH, - AFBC_HEAD_BADDR, - AFBC_BODY_BADDR, - AFBC_SIZE_OUT, - AFBC_OUT_YSCOPE, - AFBC_STAT, - AFBC_VD_CFMT_CTRL, - AFBC_VD_CFMT_W, - AFBC_MIF_HOR_SCOPE, - AFBC_MIF_VER_SCOPE, - AFBC_PIXEL_HOR_SCOPE, - AFBC_PIXEL_VER_SCOPE, - AFBC_VD_CFMT_H, - }, - { - VD2_AFBC_ENABLE, - VD2_AFBC_MODE, - VD2_AFBC_SIZE_IN, - VD2_AFBC_DEC_DEF_COLOR, - VD2_AFBC_CONV_CTRL, - VD2_AFBC_LBUF_DEPTH, - VD2_AFBC_HEAD_BADDR, - VD2_AFBC_BODY_BADDR, - VD2_AFBC_OUT_XSCOPE, - VD2_AFBC_OUT_YSCOPE, - VD2_AFBC_STAT, - VD2_AFBC_VD_CFMT_CTRL, - VD2_AFBC_VD_CFMT_W, - VD2_AFBC_MIF_HOR_SCOPE, - VD2_AFBC_MIF_VER_SCOPE, - VD2_AFBC_PIXEL_HOR_SCOPE, - VD2_AFBC_PIXEL_VER_SCOPE, - VD2_AFBC_VD_CFMT_H, - - }, - -}; -#define AFBC_DEC_SEL (eAFBC_DEC1) - - -static enum eAFBC_DEC afbc_get_decnub(void) -{ - enum eAFBC_DEC sel_dec = eAFBC_DEC0; - - if (is_meson_gxl_cpu()) - sel_dec = eAFBC_DEC0; - else if (is_meson_txlx_cpu()) - sel_dec = eAFBC_DEC1; - else if (is_meson_g12a_cpu()) - sel_dec = AFBC_DEC_SEL; - - - return sel_dec; -} - -static const unsigned int *afbc_get_regbase(void) -{ - return ®_AFBC[afbc_get_decnub()][0]; -} - -bool afbc_is_supported(void) -{ - bool ret = false; - - /*currently support txlx and g12a*/ - if (is_meson_txlx_cpu() - || is_meson_g12a_cpu() - /*|| is_meson_tl1_cpu()*/) - ret = false; - return ret; - -} - -#define AFBC_DEC_SEL (eAFBC_DEC1) -void enable_afbc_input(struct vframe_s *vf) - +u32 enable_afbc_input(struct vframe_s *vf) { unsigned int r, u, v, w_aligned, h_aligned; - unsigned int out_height = 0; - unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0; const unsigned int *reg = afbc_get_regbase(); + unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0; + unsigned int out_height = 0; if (!afbc_is_supported()) - return; + return false; - if ((vf->type & VIDTYPE_COMPRESS)) { - // only reg for the first time + if (vf->type & VIDTYPE_COMPRESS) { + /*only reg for the first time*/ afbc_reg_sw(true); - afbc_sw_trig(true); + afbc_sw(true); } else { - afbc_sw_trig(false); - return; + afbc_sw(false); + return false; } - w_aligned = round_up((vf->width-1), 32); - h_aligned = round_up((vf->height-1), 4); + + w_aligned = round_up((vf->width), 32); + /*if (di_pre_stru.cur_inp_type & VIDTYPE_INTERLACE)*/ + if ((vf->type & VIDTYPE_INTERLACE) && + (vf->type & VIDTYPE_VIU_422)) + h_aligned = round_up((vf->height/2), 4);/*from vdin and is i */ + else + h_aligned = round_up((vf->height), 4); + + /*AFBCD working mode config*/ r = (3 << 24) | (10 << 16) | (1 << 14) | /*burst1 1*/ (vf->bitdepth & BITDEPTH_MASK); + if (vf->bitdepth & BITDEPTH_SAVING_MODE) r |= (1<<28); /* mem_saving_mode */ if (vf->type & VIDTYPE_SCATTER) r |= (1<<29); + out_height = h_aligned; - if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) { - r |= 0x40; - vt_ini_phase = 0xc; - out_height = h_aligned>>1; - } else if ((vf->type & VIDTYPE_TYPEMASK) == - VIDTYPE_INTERLACE_BOTTOM) { - r |= 0x80; - vt_ini_phase = 0x4; - vfmt_rpt_first = 0; - out_height = h_aligned>>1; + if (!(vf->type & VIDTYPE_VIU_422)) { + /*from dec, process P as i*/ + if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) { + r |= 0x40; + vt_ini_phase = 0xc; + vfmt_rpt_first = 1; + out_height = h_aligned>>1; + } else if ((vf->type & VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_BOTTOM) { + r |= 0x80; + vt_ini_phase = 0x4; + vfmt_rpt_first = 0; + out_height = h_aligned>>1; + } } RDMA_WR(reg[eAFBC_MODE], r); - RDMA_WR(reg[eAFBC_CONV_CTRL], 0x100); + + r = 0x1600; + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { + /* un compress mode data from vdin bit block order is + * different with from dos + */ + if (!(vf->type & VIDTYPE_VIU_422)) + r |= (1 << 19); /* dos_uncomp */ + + if (vf->type & VIDTYPE_COMB_MODE) + r |= (1 << 20); + } + RDMA_WR(reg[eAFBC_ENABLE], r); + + r = 0x100; + /* TL1 add bit[13:12]: fmt_mode; 0:yuv444; 1:yuv422; 2:yuv420 + * di does not support yuv444, so for fmt yuv444 di will bypass+ + */ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { + if (vf->type & VIDTYPE_VIU_444) + r |= (0 << 12); + else if (vf->type & VIDTYPE_VIU_422) + r |= (1 << 12); + else + r |= (2 << 12); + } + RDMA_WR(reg[eAFBC_CONV_CTRL], r); + u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3; v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3; RDMA_WR(reg[eAFBC_DEC_DEF_COLOR], 0x3FF00000 | /*Y,bit20+*/ 0x80 << (u + 10) | 0x80 << v); + + u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3; + v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3; + RDMA_WR(reg[eAFBC_DEC_DEF_COLOR], + 0x3FF00000 | /*Y,bit20+*/ + 0x80 << (u + 10) | + 0x80 << v); + /* chroma formatter */ RDMA_WR(reg[eAFBC_VD_CFMT_CTRL], (1 << 21) |/* HFORMATTER_YC_RATIO_2_1 */ @@ -1069,25 +1102,46 @@ void enable_afbc_input(struct vframe_s *vf) (vt_ini_phase << 8) | (16 << 1)|/* VFORMATTER_PHASE_BIT */ 0);/* different with inp */ + #if 0 + if (((vf->width-1) != RDMA_RD(reg[eAFBC_PIXEL_HOR_SCOPE])) || + ((vf->height-1) != RDMA_RD(reg[eAFBC_PIXEL_VER_SCOPE]))) { + pr_info("[afbc] in vf type=0x%x\n", vf->type); + /*pr_info("cur_inp_type=0x%x\n", di_pre_stru.cur_inp_type);*/ + pr_info("[afbc] w_aligned=%d, h_aligned=%d\n", + w_aligned, h_aligned); + pr_info("[afbc] vfwidth=%d, vfheight=%d\n", + vf->width, vf->height); + pr_info("[afbc] out_height=%d\n", out_height); + } + #endif + if (vf->type & VIDTYPE_VIU_444) + RDMA_WR(reg[eAFBC_VD_CFMT_W], + (w_aligned << 16) | (w_aligned/2)); + else + RDMA_WR(reg[eAFBC_VD_CFMT_W], + (w_aligned << 16) | (w_aligned)); - RDMA_WR(reg[eAFBC_VD_CFMT_W], - (w_aligned << 16) | (w_aligned/2)); RDMA_WR(reg[eAFBC_MIF_HOR_SCOPE], - (0 << 16) | ((w_aligned>>5) - 1)); + (0 << 16) | ((w_aligned>>5)-1)); RDMA_WR(reg[eAFBC_MIF_VER_SCOPE], - (0 << 16) | ((h_aligned>>2) - 1)); + (0 << 16) | ((h_aligned>>2)-1)); RDMA_WR(reg[eAFBC_PIXEL_HOR_SCOPE], - (0 << 16) | (vf->width - 1)); + (0 << 16) | (vf->width-1)); + RDMA_WR(reg[eAFBC_PIXEL_VER_SCOPE], + 0 << 16 | (vf->height-1)); + RDMA_WR(reg[eAFBC_VD_CFMT_H], out_height); - RDMA_WR(reg[eAFBC_PIXEL_VER_SCOPE], - 0 << 16 | (vf->height-1)); - RDMA_WR(reg[eAFBC_SIZE_IN], h_aligned | w_aligned << 16); + RDMA_WR(reg[eAFBC_SIZE_IN], (vf->height) | w_aligned << 16); RDMA_WR(reg[eAFBC_SIZE_OUT], out_height | w_aligned << 16); + RDMA_WR(reg[eAFBC_HEAD_BADDR], vf->compHeadAddr>>4); RDMA_WR(reg[eAFBC_BODY_BADDR], vf->compBodyAddr>>4); + + return true; } +#if 0 static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on) /*g12a*/ { unsigned int reg_ctrl; @@ -1102,22 +1156,23 @@ static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on) /*g12a*/ RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8); } +#endif static void afbcx_sw(bool on) /*g12a*/ { unsigned int tmp; unsigned int mask; unsigned int reg_ctrl, reg_en; enum eAFBC_DEC dec_sel; + const unsigned int *reg = afbc_get_regbase(); dec_sel = afbc_get_decnub(); if (dec_sel == eAFBC_DEC0) { reg_ctrl = VD1_AFBCD0_MISC_CTRL; - reg_en = AFBC_ENABLE; } else { reg_ctrl = VD2_AFBCD1_MISC_CTRL; - reg_en = VD2_AFBC_ENABLE; } + reg_en = reg[eAFBC_ENABLE]; mask = (3<<20) | (1<<12) | (1<<9); /*clear*/ @@ -1129,36 +1184,30 @@ static void afbcx_sw(bool on) /*g12a*/ | (1<<12) | (1<<9); RDMA_WR(reg_ctrl, tmp); + /*0:vd1 to di 1:vd2 to di */ RDMA_WR_BITS(VD2_AFBCD1_MISC_CTRL, (reg_ctrl == VD1_AFBCD0_MISC_CTRL)?0:1, 8, 1); - RDMA_WR(reg_en, 0x1600); + /*RDMA_WR(reg_en, 0x1600);*/ RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1); + /*TL1 add mem control bit */ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 1, 22, 1); } else { RDMA_WR(reg_ctrl, tmp); RDMA_WR(reg_en, 0x1600); RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 0, 22, 1); } -// printk("%s,on[%d],CTRL[0x%x],en[0x%x]\n", __func__, on, -// RDMA_RD(VD1_AFBCD0_MISC_CTRL), -// RDMA_RD(VD1_AFBCD0_MISC_CTRL)); - - } static void afbc_sw_old(bool on)/*txlx*/ { enum eAFBC_DEC dec_sel; unsigned int reg_en; + const unsigned int *reg = afbc_get_regbase(); dec_sel = afbc_get_decnub(); - - if (dec_sel == eAFBC_DEC0) { - //reg_ctrl = VD1_AFBCD0_MISC_CTRL; - reg_en = AFBC_ENABLE; - } else { - //reg_ctrl = VD2_AFBCD1_MISC_CTRL; - reg_en = VD2_AFBC_ENABLE; - } - + reg_en = reg[eAFBC_ENABLE]; if (on) { /* DI inp(current data) switch to AFBC */ @@ -1179,26 +1228,20 @@ static void afbc_sw_old(bool on)/*txlx*/ } else { RDMA_WR(reg_en, 0); /* afbc to vpp(replace vd1) enable */ - if (RDMA_RD_BITS(VIU_MISC_CTRL1, 0, 1) != 0 || RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) != 0) { RDMA_WR_BITS(VIU_MISC_CTRL1, 0, 0, 1); RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); } - - } } static bool afbc_is_used(void) { bool ret = false; - if (RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) == 1) ret = true; - //di_print("%s:%d\n",__func__,ret); - return ret; } static void afbc_power_sw(bool on) @@ -1206,6 +1249,7 @@ static void afbc_power_sw(bool on) /*afbc*/ enum eAFBC_DEC dec_sel; unsigned int vpu_sel; + unsigned int reg_ctrl; dec_sel = afbc_get_decnub(); if (dec_sel == eAFBC_DEC0) @@ -1216,15 +1260,30 @@ static void afbc_power_sw(bool on) switch_vpu_mem_pd_vmod(vpu_sel, on?VPU_MEM_POWER_ON:VPU_MEM_POWER_DOWN); - - if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) - afbcx_power_sw(dec_sel, on); - + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (dec_sel == eAFBC_DEC0) + reg_ctrl = VD1_AFBCD0_MISC_CTRL; + else + reg_ctrl = VD2_AFBCD1_MISC_CTRL; + if (on) + RDMA_WR_BITS(reg_ctrl, 0, 0, 8); + else + RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8); + } + /*afbcx_power_sw(dec_sel, on);*/ } -static int afbc_reg_unreg_flag; + +int afbc_reg_unreg_flag; +void afbc_sw(bool on) +{ + if (is_meson_gxl_cpu() || is_meson_txlx_cpu()) + afbc_sw_old(on); + else + afbcx_sw(on); +} + void afbc_reg_sw(bool on) { - if (!afbc_is_supported()) return; @@ -1233,25 +1292,18 @@ void afbc_reg_sw(bool on) afbc_reg_unreg_flag = 1; } if ((!on) && afbc_reg_unreg_flag) { - afbc_sw_trig(false); + afbc_sw(false); afbc_power_sw(false); afbc_reg_unreg_flag = 0; } - -} -static void afbc_sw(bool on) -{ - if (is_meson_gxl_cpu() || is_meson_txlx_cpu()) - afbc_sw_old(on); - else - afbcx_sw(on); - } +#if 0 void afbc_sw_trig(bool on) { afbc_sw(on); } -static void afbc_input_sw(bool on) +#endif +void afbc_input_sw(bool on) { const unsigned int *reg = afbc_get_regbase(); unsigned int reg_AFBC_ENABLE; @@ -3603,7 +3655,7 @@ static void di_pre_data_mif_ctrl(bool enable) afbc_input_sw(true); } else { DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1); - afbc_input_sw(false); + /*afbc_input_sw(false);*/ } #endif /* nrwr no clk gate en=0 */ @@ -3622,9 +3674,11 @@ static void di_pre_data_mif_ctrl(bool enable) if (Rd_reg_bits(VIU_MISC_CTRL1, 0, 1) == 1) RDMA_WR_BITS(VD2_AFBC_ENABLE, 0, 8, 1); #else - /* disable AFBC input */ - if (afbc_is_used()) - afbc_input_sw(false); + /* + * disable AFBC input at unreg + */ + //if (afbc_is_used()) + // afbc_input_sw(false); #endif } diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index eb303531e46c..d85c8b3202ab 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -27,6 +27,34 @@ #define SKIP_CTRE_NUM 13 +enum eAFBC_REG { + eAFBC_ENABLE, /*0x1ae0*/ + eAFBC_MODE, /*0x1ae1*/ + eAFBC_SIZE_IN, /*0x1ae2*/ + eAFBC_DEC_DEF_COLOR, /*0x1ae3*/ + eAFBC_CONV_CTRL, /*0x1ae4*/ + eAFBC_LBUF_DEPTH, /*0x1ae5*/ + eAFBC_HEAD_BADDR, /*0x1ae6*/ + eAFBC_BODY_BADDR, /*0x1ae7*/ + eAFBC_SIZE_OUT, /*0x1ae8*/ + eAFBC_OUT_YSCOPE, /*0x1ae9*/ + eAFBC_STAT, /*0x1aea*/ + eAFBC_VD_CFMT_CTRL, /*0x1aeb*/ + eAFBC_VD_CFMT_W, /*0x1aec*/ + eAFBC_MIF_HOR_SCOPE, /*0x1aed*/ + eAFBC_MIF_VER_SCOPE, /*0x1aee*/ + eAFBC_PIXEL_HOR_SCOPE, /*0x1aef*/ + eAFBC_PIXEL_VER_SCOPE, /*0x1af0*/ + eAFBC_VD_CFMT_H, /*0x1af1*/ +}; + +enum eAFBC_DEC { + eAFBC_DEC0, + eAFBC_DEC1, +}; +#define AFBC_REG_INDEX_NUB (18) +#define AFBC_DEC_NUB (2) + struct DI_MIF_s { unsigned short luma_x_start0; unsigned short luma_x_end0; @@ -91,6 +119,7 @@ struct di_pq_parm_s { struct list_head list; }; +extern u32 afbc_disable_flag; 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); @@ -109,7 +138,7 @@ void enable_di_pre_aml( struct DI_SIM_MIF_s *di_contwr_mif, unsigned char madi_en, unsigned char pre_field_num, unsigned char pre_vdin_link); -void enable_afbc_input(struct vframe_s *vf); +u32 enable_afbc_input(struct vframe_s *vf); void mc_pre_mv_irq(void); void enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif, @@ -179,8 +208,11 @@ void di_txl_patch_prog(int prog_flg, unsigned int cnt, bool mc_en); bool afbc_is_supported(void); //extern void afbc_power_sw(bool on); extern void afbc_reg_sw(bool on); -extern void afbc_sw_trig(bool on); +/*extern void afbc_sw_trig(bool on);*/ +extern void afbc_sw(bool on); +extern void afbc_input_sw(bool on); extern void dump_vd2_afbc(void); +extern int afbc_reg_unreg_flag; extern u8 *di_vmap(ulong addr, u32 size, bool *bflg); extern void di_unmap_phyaddr(u8 *vaddr); diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c index 7a912edfebdb..81e003664204 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c @@ -297,7 +297,7 @@ struct combing_status_s *adpative_combing_config(unsigned int width, } void mtn_int_combing_glbmot(void) { - if (is_meson_tl1_cpu()) {/*from VLSI yanling.liu*/ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {/*from VLSI yanling.liu*/ combing_glbmot_radprat[0] = 30; } } @@ -629,6 +629,24 @@ static int di_debug_readreg; module_param(di_debug_readreg, int, 0644); MODULE_PARM_DESC(di_debug_readreg, "di_debug_readreg"); +/*from VLSI yanling.liu, the patch fix TL1 1080I in some dark */ +/*scenes and roller coasters have small sawtooth, when turn off*/ +/*combing_fix_en, set the registers*/ +void fix_tl1_1080i_sawtooth_patch(void) +{ + DI_Wr(0x1741, 0x0A0A1A22); + DI_Wr(0x1742, 0x0a100101); + DI_Wr(0x1743, 0x01020420); + DI_Wr(0x1744, 0x32210404); + DI_Wr(0x17a9, 0x0a100505); + DI_Wr(0x17aa, 0x04040101); + DI_Wr(0x17ab, 0x0a0a0a0a); + DI_Wr(0x17ac, 0x0f100101); + DI_Wr(0x17ad, 0x04040606); + DI_Wr(0x17ae, 0x02030202); + DI_Wr(0x17af, 0x60020a60); +} + static int combing_cnt; int combing_diff_min = 2000; int combing_diff_max = 2000; diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.h b/drivers/amlogic/media/deinterlace/deinterlace_mtn.h index 206d1c307543..13cc468c7e07 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_mtn.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.h @@ -39,6 +39,7 @@ struct combing_status_s *adpative_combing_config(unsigned int width, unsigned int height, enum vframe_source_type_e src_type, bool prog, enum tvin_sig_fmt_e fmt); +extern void fix_tl1_1080i_sawtooth_patch(void); int adaptive_combing_fixing( struct combing_status_s *cmb_status, unsigned int field_diff, unsigned int frame_diff, diff --git a/drivers/amlogic/media/deinterlace/di_pps.c b/drivers/amlogic/media/deinterlace/di_pps.c index 750be0179d03..302555429af8 100644 --- a/drivers/amlogic/media/deinterlace/di_pps.c +++ b/drivers/amlogic/media/deinterlace/di_pps.c @@ -388,10 +388,12 @@ static void f2v_get_vertical_phase(unsigned int zoom_ratio, vphase->phase = (offset_out - offset_in) >> 2; } } + /* * patch 1: inp scaler 0: di wr scaler + * support: TM2 + * not support: SM1 */ - void di_pps_config(unsigned char path, int src_w, int src_h, int dst_w, int dst_h) { @@ -1325,3 +1327,61 @@ RESTART: } #endif +/* + * di pre h scaling down function + * only have h scaling down + * support: sm1 tm2 ... + * 0x37b0 ~ 0x37b5 + */ +void di_inp_hsc_setting(uint32_t src_w, uint32_t dst_w) +{ + uint32_t i; + uint32_t hsc_en; + uint32_t horz_phase_step; + int *filt_coef0 = di_filt_coef0; + /*int *filt_coef1 = di_filt_coef1;*/ + /*int *filt_coef2 = di_filt_coef2;*/ + + if (src_w == dst_w) { + hsc_en = 0; + } else { + hsc_en = 1; + /*write horz filter coefs*/ + RDMA_WR(DI_VIU_HSC_COEF_IDX, 0x0100); + for (i = 0; i < 33; i++) + RDMA_WR(DI_VIU_HSC_COEF, filt_coef0[i]); /*bicubic*/ + + horz_phase_step = (src_w << 20) / dst_w; + horz_phase_step = (horz_phase_step << 4); + RDMA_WR(DI_VIU_HSC_WIDTHM1, (src_w-1)<<16 | (dst_w-1)); + RDMA_WR(DI_VIU_HSC_PHASE_STEP, horz_phase_step); + RDMA_WR(DI_VIU_HSC_PHASE_CTRL, 0); + } + RDMA_WR(DI_VIU_HSC_CTRL, + (4 << 20) | /* initial receive number*/ + (0 << 12) | /* initial pixel ptr*/ + (1 << 10) | /* repeat first pixel number*/ + (0 << 8) | /* sp422 mode*/ + (4 << 4) | /* horz scaler bank length*/ + (0 << 2) | /* phase0 always en*/ + (0 << 1) | /* nearest_en*/ + (hsc_en<<0)); /* hsc_en*/ +} + +/* + * 0x37b0 ~ 0x37b5 + */ +void dump_hdownscler_reg(unsigned int base_addr) +{ + unsigned int i = 0x374e; + + pr_info("-----dump hdownscler start-----\n"); + for (i = 0x37b0; i < 0x37b5; i++) { + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, RDMA_RD(i)); + } + pr_info("-----dump hdownscler end-----\n"); +} + + diff --git a/drivers/amlogic/media/deinterlace/di_pps.h b/drivers/amlogic/media/deinterlace/di_pps.h index 9ec789eb3b8e..a607364651f3 100644 --- a/drivers/amlogic/media/deinterlace/di_pps.h +++ b/drivers/amlogic/media/deinterlace/di_pps.h @@ -54,6 +54,12 @@ enum f2v_vphase_type_e { F2V_TYPE_MAX }; /* frame to video conversion type */ #endif + +enum hdr2_scaler_e { + hdr2_scaler_postdi = 0, + hdr2_scaler_predi = 1, +}; + struct pps_f2v_vphase_s { unsigned char rcv_num; unsigned char rpt_num; @@ -99,4 +105,7 @@ struct pps_frame_par_s { void di_pps_config(unsigned char path, int src_w, int src_h, int dst_w, int dst_h); void dump_pps_reg(unsigned int base_addr); +void di_inp_hsc_setting(uint32_t src_w, uint32_t dst_w); +void dump_hdownscler_reg(unsigned int base_addr); + #endif diff --git a/drivers/amlogic/media/deinterlace/nr_drv.c b/drivers/amlogic/media/deinterlace/nr_drv.c index 509117bbbb6b..b25113768d3c 100644 --- a/drivers/amlogic/media/deinterlace/nr_drv.c +++ b/drivers/amlogic/media/deinterlace/nr_drv.c @@ -280,7 +280,10 @@ static void dnr_config(struct DNR_PARM_s *dnr_parm_p, DI_Wr(DNR_DM_CTRL, Rd(DNR_DM_CTRL)|(1 << 11)); DI_Wr_reg_bits(DNR_CTRL, dnr_en?1:0, 16, 1); /* dm for sd, hd will slower */ - DI_Wr(DNR_CTRL, 0x1df00); + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + DI_Wr(DNR_CTRL, 0x1df00 | (0x03 << 18)); //5 line + else + DI_Wr(DNR_CTRL, 0x1df00); if (is_meson_gxlx_cpu()) { /* disable chroma dm according to baozheng */ DI_Wr_reg_bits(DNR_DM_CTRL, 0, 8, 1); @@ -354,7 +357,7 @@ static void nr2_config(unsigned short width, unsigned short height) { if (is_meson_txlx_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_tl1_cpu() || - is_meson_sm1_cpu()) { + is_meson_sm1_cpu() || is_meson_tm2_cpu()) { DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 2, 1); DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 15, 1); DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 17, 1); @@ -404,7 +407,7 @@ void nr_all_config(unsigned short width, unsigned short height, cue_config(nr_param.pcue_parm, field_type); if (is_meson_txlx_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_tl1_cpu() || - is_meson_sm1_cpu()) { + is_meson_sm1_cpu() || is_meson_tm2_cpu()) { linebuffer_config(width); nr4_config(nr_param.pnr4_parm, width, height); } @@ -596,7 +599,7 @@ static void dnr_process(struct DNR_PARM_s *pDnrPrm) #endif int ll, lr; - if (is_meson_tl1_cpu()) { + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { ll = Rd(DNR_RO_GBS_STAT_LR); lr = Rd(DNR_RO_GBS_STAT_LL); } else { @@ -742,6 +745,16 @@ module_param_named(glb_fieldck_en, glb_fieldck_en, bool, 0644); void adaptive_cue_adjust(unsigned int frame_diff, unsigned int field_diff) { struct CUE_PARM_s *pcue_parm = nr_param.pcue_parm; + unsigned int mask1, mask2; + + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { + /*value from VLSI(yanling.liu) 2018-12-07: */ + mask1 = 0x50332; + mask2 = 0x00054357; + } else { /*ori value*/ + mask1 = 0x50323; + mask2 = 0x00054375; + } if (frame_diff > pcue_parm->glb_mot_framethr) { pcue_parm->frame_count = pcue_parm->frame_count > 0 ? @@ -827,7 +840,7 @@ void nr_process_in_irq(void) dnr_process(&dnr_param); if (is_meson_txlx_cpu() || is_meson_g12a_cpu() || is_meson_g12a_cpu() || is_meson_tl1_cpu() || - is_meson_sm1_cpu()) { + is_meson_sm1_cpu() || is_meson_tm2_cpu()) { noise_meter_process(nr_param.pnr4_parm, nr_param.frame_count); luma_enhancement_process(nr_param.pnr4_parm, nr_param.frame_count); @@ -1064,19 +1077,11 @@ static void nr4_param_init(struct NR4_PARM_s *nr4_parm_p) nr4_parm_p->sw_nr4_sad2gain_lut[14] = 14; nr4_parm_p->sw_nr4_sad2gain_lut[15] = 9; - if (is_meson_tl1_cpu()) { - nr4_parm_p->sw_nr4_noise_thd = 32; - nr4_parm_p->sw_nr4_noise_sel = 0; - nr4_parm_p->sw_nr4_noise_ctrl_dm_en = 0; - nr4_parm_p->sw_nr4_scene_change_thd2 = 80; - nr4_parm_p->sw_dm_scene_change_en = 0; - } else { - nr4_parm_p->sw_nr4_noise_thd = 32; - nr4_parm_p->sw_nr4_noise_sel = 0; - nr4_parm_p->sw_nr4_noise_ctrl_dm_en = 0; - nr4_parm_p->sw_nr4_scene_change_thd2 = 80; - nr4_parm_p->sw_dm_scene_change_en = 0; - } + nr4_parm_p->sw_nr4_noise_thd = 32; + nr4_parm_p->sw_nr4_noise_sel = 0; + nr4_parm_p->sw_nr4_noise_ctrl_dm_en = 0; + nr4_parm_p->sw_nr4_scene_change_thd2 = 80; + nr4_parm_p->sw_dm_scene_change_en = 0; } static void cue_param_init(struct CUE_PARM_s *cue_parm_p) @@ -1187,7 +1192,10 @@ void nr_hw_init(void) { nr_gate_control(true); - DI_Wr(DNR_CTRL, 0x1df00); + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + DI_Wr(DNR_CTRL, 0x1df00|(0x03<<18));//5 line + else + DI_Wr(DNR_CTRL, 0x1df00); DI_Wr(NR3_MODE, 0x3); DI_Wr(NR3_COOP_PARA, 0x28ff00); DI_Wr(NR3_CNOOP_GAIN, 0x881900); @@ -1201,7 +1209,7 @@ void nr_gate_control(bool gate) { if (!is_meson_txlx_cpu() && !is_meson_g12a_cpu() && !is_meson_g12b_cpu() && !is_meson_sm1_cpu() - && !is_meson_tl1_cpu()) + && !is_meson_tl1_cpu() && !is_meson_tm2_cpu()) return; if (gate) { /* enable nr auto gate */ diff --git a/drivers/amlogic/media/deinterlace/register.h b/drivers/amlogic/media/deinterlace/register.h index 5ce602d7f00c..5d8a36acb1de 100644 --- a/drivers/amlogic/media/deinterlace/register.h +++ b/drivers/amlogic/media/deinterlace/register.h @@ -212,6 +212,15 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, #define DI_HSC_INI_PAT_CTRL 0x376b #define DI_SC_GCLK_CTRL 0x376c #define DI_SC_HOLD_LINE 0x376d + +/* DI H DOWN SCALER */ +#define DI_VIU_HSC_WIDTHM1 0x37b0 +#define DI_VIU_HSC_PHASE_STEP 0x37b1 +#define DI_VIU_HSC_CTRL 0x37b2 +#define DI_VIU_HSC_PHASE_CTRL 0x37b3 +#define DI_VIU_HSC_COEF 0x37b4 +#define DI_VIU_HSC_COEF_IDX 0x37b5 + /* NR DOWNSAMPLE */ #define NRDSWR_X 0x37f9 #define NRDSWR_Y 0x37fa diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 6492f44dfe9a..558d5ca1eb3e 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -529,6 +529,7 @@ const char video_dev_id2[] = "amvideo-dev2"; int onwaitendframe; static u32 vpp_hold_line = 8; +static u32 stop_update; struct video_dev_s video_dev[2] = { {0x1d00 - 0x1d00, 0x1a50 - 0x1a50}, @@ -4038,6 +4039,8 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) #endif } } + if (stop_update) + frame_par_ready_to_set = 0; ATRACE_COUNTER(__func__, 0); } @@ -7179,7 +7182,15 @@ SET_FILTER: u32 zoom_start_y, zoom_end_y; correct_vd1_mif_size_for_DV(cur_frame_par); if (cur_dispbuf->type & VIDTYPE_INTERLACE) { - if (cur_dispbuf->type & VIDTYPE_VIU_FIELD) { + if (cur_dispbuf->type + & VIDTYPE_COMPRESS) { + /* for vdin afbc and interlace case */ + zoom_start_y = + cur_frame_par->VPP_vd_start_lines_; + zoom_end_y = + cur_frame_par->VPP_vd_end_lines_; + } else if (cur_dispbuf->type + & VIDTYPE_VIU_FIELD) { zoom_start_y = cur_frame_par->VPP_vd_start_lines_ >> 1; @@ -13027,6 +13038,9 @@ module_param(toggle_count, uint, 0664); MODULE_PARM_DESC(vpp_hold_line, "\n vpp_hold_line\n"); module_param(vpp_hold_line, uint, 0664); +MODULE_PARM_DESC(stop_update, "\n stop_update\n"); +module_param(stop_update, uint, 0664); + MODULE_PARM_DESC(reference_zorder, "\n reference_zorder\n"); module_param(reference_zorder, uint, 0664); diff --git a/drivers/amlogic/media/video_sink/vpp.c b/drivers/amlogic/media/video_sink/vpp.c index 2195cceed121..4b92e7167d62 100644 --- a/drivers/amlogic/media/video_sink/vpp.c +++ b/drivers/amlogic/media/video_sink/vpp.c @@ -2974,7 +2974,10 @@ int vpp_set_filters( aspect_ratio = (vf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK) >> DISP_RATIO_ASPECT_RATIO_BIT; - if (vf->type & VIDTYPE_INTERLACE) + /* the height from vdin afbc will be half */ + /* so need no interlace in */ + if ((vf->type & VIDTYPE_INTERLACE) + && !(vf->type & VIDTYPE_COMPRESS)) vpp_flags = VPP_FLAG_INTERLACE_IN; if (vf->ratio_control & DISP_RATIO_PORTRAIT_MODE)