| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * drivers/amlogic/media/di_multi/dd_s4dw.c |
| * |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/err.h> |
| #include <linux/seq_file.h> |
| |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include "register.h" |
| #include "register_nr4.h" |
| #include "deinterlace.h" |
| #include "deinterlace_dbg.h" |
| |
| #include "di_data_l.h" |
| #include "deinterlace_hw.h" |
| #include "di_hw_v3.h" |
| #include "di_afbc_v3.h" |
| |
| #include "di_dbg.h" |
| #include "di_pps.h" |
| #include "di_pre.h" |
| #include "di_prc.h" |
| #include "di_task.h" |
| #include "di_vframe.h" |
| #include "di_que.h" |
| #include "di_api.h" |
| #include "di_sys.h" |
| #include "di_reg_v3.h" |
| #include "dolby_sys.h" |
| /*2018-07-18 add debugfs*/ |
| #include <linux/seq_file.h> |
| #include <linux/debugfs.h> |
| /*2018-07-18 -----------*/ |
| |
| static unsigned int dim_afbc_skip_en; |
| module_param_named(dim_afbc_skip_en, dim_afbc_skip_en, uint, 0664); |
| |
| #ifdef DBG_BUFFER_FLOW |
| static unsigned int afbc_skip_pps_w, afbc_skip_pps_h; |
| module_param_named(afbc_skip_pps_w, afbc_skip_pps_w, uint, 0664); |
| module_param_named(afbc_skip_pps_h, afbc_skip_pps_h, uint, 0664); |
| #endif |
| bool dip_cfg_afbc_skip(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT0) ? true : false; |
| } |
| |
| bool dip_cfg_afbc_pps(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT1) ? true : false; |
| } |
| |
| static bool dbg_change_each_vs(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT3) ? true : false; |
| } |
| |
| #ifdef DBG_BUFFER_FLOW |
| static bool dbg_flow(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT4) ? true : false; |
| } |
| #endif |
| |
| static bool dbg_buffer_ext(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT5) ? true : false; |
| } |
| |
| static bool dbg_vfm_cvs(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT6) ? true : false; |
| } |
| |
| bool s4dw_test_ins(void) |
| { |
| /* use internal buffer to test create instance */ |
| return (dim_afbc_skip_en & DI_BIT8) ? true : false; |
| } |
| |
| static bool dip_cfg_afbc_dbg_display_buffer(void) |
| { |
| return (dim_afbc_skip_en & DI_BIT9) ? true : false; |
| } |
| |
| void dim_dbg_buffer_flow(struct di_ch_s *pch, |
| unsigned long addr, |
| unsigned long addr2, |
| unsigned int pos) |
| { |
| #ifdef DBG_BUFFER_FLOW |
| unsigned int ch = 99; |
| |
| if (dbg_flow()) { |
| if (pch) |
| ch = pch->ch_id; |
| PR_INF("dbg buffer:ch[%d],0x%lx,0x%lx,%d\n", ch, addr, addr2, pos); |
| } |
| #endif /*DBG_BUFFER_FLOW*/ |
| } |
| |
| void dim_dbg_buffer_ext(struct di_ch_s *pch, |
| struct di_buffer *buffer, |
| unsigned int pos) |
| { |
| #ifdef DBG_BUFFER_EXT |
| unsigned int ch = 99; |
| |
| if (!dbg_buffer_ext()) |
| return; |
| if (pch) |
| ch = pch->ch_id; |
| if (!buffer->vf) { |
| PR_INF("dbg_buffer_ex:ch[%d],%d,0x%px,no vf\n", |
| ch, pos, buffer); |
| return; |
| } |
| PR_INF("dbg_buffer_ex:ch[%d],%d,0x%px,0x%x,[0x%px,0x%px]\n", |
| ch, pos, buffer, buffer->flag, |
| buffer->private_data, buffer->vf->private_data); |
| PR_INF("\t0x%lx,0x%lx,0x%lx<%d %d>:0x%x:0x%x\n", |
| buffer->phy_addr, |
| buffer->vf->canvas0_config[0].phy_addr, |
| buffer->vf->canvas0_config[1].phy_addr, |
| buffer->vf->canvas0_config[0].width, |
| buffer->vf->canvas0_config[0].height, |
| buffer->vf->canvas0Addr, |
| buffer->vf->type); |
| |
| #endif |
| } |
| |
| void dim_dbg_vf_cvs(struct di_ch_s *pch, |
| struct vframe_s *vfm, |
| unsigned int pos) |
| { |
| #ifdef DBG_VFM_CVS |
| struct canvas_config_s *cvs; |
| unsigned int ch = 99; |
| |
| if (!dbg_vfm_cvs() || !vfm) |
| return; |
| if (pch) |
| ch = pch->ch_id; |
| cvs = &vfm->canvas0_config[0]; |
| |
| PR_INF("dbg_vf:ch[%d],%d,[%d],0x%px[0x%px]\n", |
| ch, pos, vfm->plane_num, vfm, vfm->private_data); |
| PR_INF("\t0x%lx,<%d %d>,0x%x", |
| cvs->phy_addr, |
| cvs->width, |
| cvs->height, |
| vfm->canvas0Addr); |
| if (vfm->plane_num > 1) { |
| cvs = &vfm->canvas0_config[1]; |
| PR_INF("dbg_vf:\t0x%lx,<%d %d>\n", |
| cvs->phy_addr, |
| cvs->width, |
| cvs->height); |
| } |
| |
| #endif |
| } |
| |
| static int s4dw_init_buf_simple(struct di_ch_s *pch) |
| { |
| int i, j; |
| |
| struct vframe_s **pvframe_in; |
| struct vframe_s *pvframe_in_dup; |
| struct vframe_s *pvframe_local; |
| struct vframe_s *pvframe_post; |
| struct di_buf_s *pbuf_local; |
| struct di_buf_s *pbuf_in; |
| struct di_buf_s *pbuf_post; |
| struct di_buf_s *di_buf; |
| |
| struct div2_mm_s *mm; /*mm-0705*/ |
| unsigned int cnt; |
| |
| unsigned int ch; |
| unsigned int length; |
| |
| /**********************************************/ |
| /* count buf info */ |
| /**********************************************/ |
| ch = pch->ch_id; |
| pvframe_in = get_vframe_in(ch); |
| pvframe_in_dup = get_vframe_in_dup(ch); |
| pvframe_local = get_vframe_local(ch); |
| pvframe_post = get_vframe_post(ch); |
| pbuf_local = get_buf_local(ch); |
| pbuf_in = get_buf_in(ch); |
| pbuf_post = get_buf_post(ch); |
| mm = dim_mm_get(ch); |
| |
| /* decoder'buffer had been release no need put */ |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) |
| pvframe_in[i] = NULL; |
| |
| /**********************************************/ |
| /* que init */ |
| /**********************************************/ |
| |
| queue_init(ch, MAX_LOCAL_BUF_NUM * 2); |
| di_que_init(ch); /*new que*/ |
| |
| /**********************************************/ |
| /* local buf init */ |
| /**********************************************/ |
| for (i = 0; i < (MAX_LOCAL_BUF_NUM * 2); i++) { |
| di_buf = &pbuf_local[i]; |
| |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| di_buf->type = VFRAME_TYPE_LOCAL; |
| di_buf->pre_ref_count = 0; |
| di_buf->post_ref_count = 0; |
| for (j = 0; j < 3; j++) |
| di_buf->canvas_width[j] = mm->cfg.canvas_width[j]; |
| |
| di_buf->index = i; |
| di_buf->flg_null = 1; |
| di_buf->vframe = &pvframe_local[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = ch; |
| di_buf->canvas_config_flag = 2; |
| |
| di_que_in(ch, QUE_PRE_NO_BUF, di_buf); |
| dbg_init("buf[%d], addr=0x%lx\n", di_buf->index, |
| di_buf->nr_adr); |
| } |
| |
| /**********************************************/ |
| /* input buf init */ |
| /**********************************************/ |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) { |
| di_buf = &pbuf_in[i]; |
| |
| if (di_buf) { |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| di_buf->type = VFRAME_TYPE_IN; |
| di_buf->pre_ref_count = 0; |
| di_buf->post_ref_count = 0; |
| di_buf->vframe = &pvframe_in_dup[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->index = i; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = ch; |
| di_que_in(ch, QUE_IN_FREE, di_buf); |
| } |
| } |
| /**********************************************/ |
| /* post buf init */ |
| /**********************************************/ |
| cnt = 0; |
| for (i = 0; i < MAX_POST_BUF_NUM; i++) { |
| di_buf = &pbuf_post[i]; |
| |
| if (di_buf) { |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| |
| di_buf->type = VFRAME_TYPE_POST; |
| di_buf->index = i; |
| di_buf->vframe = &pvframe_post[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = ch; |
| di_buf->flg_null = 1; |
| |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| di_buf->canvas_width[NR_CANVAS] = |
| mm->cfg.pst_cvs_w; |
| //di_buf->canvas_rot_w = rot_width; |
| di_buf->canvas_height = mm->cfg.pst_cvs_h; |
| di_buf->canvas_config_flag = 1; |
| |
| dbg_init("[%d]post buf:%d: addr=0x%lx\n", i, |
| di_buf->index, di_buf->nr_adr); |
| } |
| cnt++; |
| //di_que_in(channel, QUE_POST_FREE, di_buf); |
| di_que_in(ch, QUE_PST_NO_BUF, di_buf); |
| |
| } else { |
| PR_ERR("%s:%d:post buf is null\n", __func__, i); |
| } |
| } |
| /* check */ |
| length = di_que_list_count(ch, QUE_PST_NO_BUF); |
| |
| di_buf = di_que_out_to_di_buf(ch, QUE_PST_NO_BUF); |
| dbg_mem2("%s:ch[%d]:pst_no_buf:%d, index[%d]\n", __func__, |
| ch, length, di_buf->index); |
| return 0; |
| } |
| |
| static int s4dw_cnt_post_buf(struct di_ch_s *pch) |
| { |
| unsigned int ch; |
| struct div2_mm_s *mm; |
| unsigned int nr_width, /*nr_canvas_width,*/canvas_align_width = 32; |
| unsigned int height, width; |
| unsigned int tmpa, tmpb; |
| unsigned int canvas_height; |
| enum EDPST_MODE mode; |
| |
| ch = pch->ch_id; |
| mm = dim_mm_get(ch); |
| |
| height = mm->cfg.di_h; |
| canvas_height = roundup(height, 32); |
| width = mm->cfg.di_w; |
| |
| mm->cfg.pbuf_hsize = width; |
| nr_width = width; |
| dbg_mem2("%s w[%d]h[%d]\n", __func__, width, height); |
| |
| /**********************************************/ |
| /* count buf info */ |
| /**********************************************/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| canvas_align_width = 64; |
| |
| /***********************/ |
| mode = pch->mode; //EDPST_MODE_NV21_8BIT |
| |
| dbg_mem2("%s:mode:%d\n", __func__, mode); |
| |
| /* p */ |
| //tmp nr_width = roundup(nr_width, canvas_align_width); |
| mm->cfg.pst_mode = EDPST_MODE_NV21_8BIT; |
| if (mode == EDPST_MODE_NV21_8BIT) { |
| nr_width = roundup(nr_width, canvas_align_width); |
| tmpa = (nr_width * canvas_height) >> 1;/*uv*/ |
| tmpb = tmpa; |
| tmpa = nr_width * canvas_height; |
| |
| mm->cfg.pst_buf_uv_size = roundup(tmpb, PAGE_SIZE); |
| mm->cfg.pst_buf_y_size = roundup(tmpa, PAGE_SIZE); |
| mm->cfg.pst_buf_size = mm->cfg.pst_buf_y_size + |
| mm->cfg.pst_buf_uv_size;//tmpa + tmpb; |
| mm->cfg.size_post = mm->cfg.pst_buf_size; |
| mm->cfg.pst_cvs_w = nr_width; |
| mm->cfg.pst_cvs_h = canvas_height; |
| mm->cfg.pst_afbci_size = 0; |
| mm->cfg.pst_afbct_size = 0; |
| } else { |
| PR_ERR("%s:temp:not nv21\n", __func__); |
| return -1; |
| } |
| |
| mm->cfg.size_buf_hf = 0; |
| |
| mm->cfg.dw_size = 0; |
| |
| mm->cfg.size_post = roundup(mm->cfg.size_post, PAGE_SIZE); |
| mm->cfg.size_post_page = mm->cfg.size_post >> PAGE_SHIFT; |
| |
| /* p */ |
| mm->cfg.pbuf_flg.b.page = mm->cfg.size_post_page; |
| mm->cfg.pbuf_flg.b.is_i = 0; |
| if (mm->cfg.pst_afbct_size) |
| mm->cfg.pbuf_flg.b.afbc = 1; |
| else |
| mm->cfg.pbuf_flg.b.afbc = 0; |
| if (mm->cfg.dw_size) |
| mm->cfg.pbuf_flg.b.dw = 1; |
| else |
| mm->cfg.pbuf_flg.b.dw = 0; |
| |
| mm->cfg.pbuf_flg.b.typ = EDIM_BLK_TYP_OLDP; |
| |
| if (dip_itf_is_ins_exbuf(pch)) { |
| mm->cfg.pbuf_flg.b.typ |= EDIM_BLK_TYP_POUT; |
| mm->cfg.size_buf_hf = 0; |
| } |
| dbg_mem2("hf:size:%d\n", mm->cfg.size_buf_hf); |
| |
| dbg_mem2("%s:3 pst_cvs_w[%d]\n", __func__, mm->cfg.pst_cvs_w); |
| #ifdef PRINT_BASIC |
| dbg_mem2("%s:size:\n", __func__); |
| dbg_mem2("\t%-15s:0x%x\n", "total_size", mm->cfg.size_post); |
| dbg_mem2("\t%-15s:0x%x\n", "total_page", mm->cfg.size_post_page); |
| dbg_mem2("\t%-15s:0x%x\n", "buf_size", mm->cfg.pst_buf_size); |
| dbg_mem2("\t%-15s:0x%x\n", "y_size", mm->cfg.pst_buf_y_size); |
| dbg_mem2("\t%-15s:0x%x\n", "uv_size", mm->cfg.pst_buf_uv_size); |
| dbg_mem2("\t%-15s:0x%x\n", "afbci_size", mm->cfg.pst_afbci_size); |
| dbg_mem2("\t%-15s:0x%x\n", "afbct_size", mm->cfg.pst_afbct_size); |
| dbg_mem2("\t%-15s:0x%x\n", "flg", mm->cfg.pbuf_flg.d32); |
| dbg_mem2("\t%-15s:0x%x\n", "dw_size", mm->cfg.dw_size); |
| dbg_mem2("\t%-15s:0x%x\n", "size_hf", mm->cfg.size_buf_hf); |
| PR_INF("\t%-15s:0x%x\n", "pst_cvs_h", mm->cfg.pst_cvs_h); |
| #endif |
| return 0; |
| } |
| |
| static int s4dw_buf_init(struct di_ch_s *pch) |
| { |
| struct mtsk_cmd_s blk_cmd; |
| //struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct div2_mm_s *mm; |
| unsigned int ch; |
| // unsigned int tmp_nub; |
| |
| ch = pch->ch_id; |
| mm = dim_mm_get(ch); |
| |
| check_tvp_state(pch); |
| //di_cnt_i_buf(pch, 1920, 1088); |
| //di_cnt_i_buf(pch, 1920, 2160); |
| //di_cnt_pst_afbct(pch); |
| mm->cfg.size_pafbct_all = 0; |
| mm->cfg.size_pafbct_one = 0; |
| mm->cfg.nub_pafbct = 0; |
| mm->cfg.dat_pafbct_flg.d32 = 0; |
| |
| s4dw_cnt_post_buf(pch); |
| s4dw_init_buf_simple(pch); |
| |
| //di_que_list_count(ch, QUE_POST_KEEP); |
| PR_INF("%s:\n", __func__); |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_CMA) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_A) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_B)) { /*trig cma alloc*/ |
| dbg_timer(ch, EDBG_TIMER_ALLOC); |
| |
| if ((mm->cfg.pbuf_flg.b.typ & 0x8) == |
| EDIM_BLK_TYP_POUT) { |
| //move all to wait: |
| di_buf_no2wait(pch, mm->cfg.num_post); |
| } else if (mm->cfg.pbuf_flg.b.page) {//@ary_note: ?? |
| /* post */ |
| blk_cmd.cmd = ECMD_BLK_ALLOC; |
| |
| blk_cmd.nub = mm->cfg.num_post; |
| blk_cmd.flg.d32 = mm->cfg.pbuf_flg.d32; |
| if (mm->cfg.size_buf_hf) |
| blk_cmd.hf_need = 1; |
| else |
| blk_cmd.hf_need = 0; |
| |
| mtask_send_cmd(ch, &blk_cmd); |
| } |
| |
| mm->sts.flg_alloced = true; |
| mm->cfg.num_rebuild_keep = 0; |
| } |
| return 0; |
| } |
| |
| #ifdef DBG_BUFFER_FLOW |
| static unsigned int s4dw_buf_h; |
| module_param_named(s4dw_buf_h, s4dw_buf_h, uint, 0664); |
| #endif /* DBG_BUFFER_FLOW */ |
| |
| const struct di_mm_cfg_s c_mm_cfg_s4_cp = { |
| .di_h = 544, //540, |
| .di_w = 960,//960, |
| .num_local = 0, |
| .num_post = 9, |
| .num_step1_post = 0, |
| }; |
| |
| static void s4dw_reg_variable(struct di_ch_s *pch, struct vframe_s *vframe) |
| { |
| unsigned int ch; |
| struct di_pre_stru_s *ppre; |
| struct di_post_stru_s *ppost; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct div2_mm_s *mm; |
| |
| if (!pch) |
| return; |
| ch = pch->ch_id; |
| |
| PR_INF("%s:=%d\n", __func__, ch); |
| //tmp dim_slt_init(); |
| |
| ppre = get_pre_stru(ch); |
| |
| dim_print("%s:0x%p\n", __func__, vframe); |
| mm = dim_mm_get(ch); |
| /**/ |
| if (vframe) { |
| /* ext dip_init_value_reg(channel, vframe);*/ |
| /* struct di_post_stru_s */ |
| ppost = get_post_stru(ch); |
| ppost = get_post_stru(ch); |
| memset(ppost, 0, sizeof(struct di_post_stru_s)); |
| ppost->next_canvas_id = 1; //?? |
| /*pre: struct di_pre_stru_s */ |
| memset(ppre, 0, sizeof(struct di_pre_stru_s)); |
| |
| dim_bypass_st_clear(pch); |
| if (pch->itf.op_cfg_ch_set) |
| pch->itf.op_cfg_ch_set(pch); |
| |
| pch->en_hf = false; |
| pch->en_hf_buf = false; |
| |
| pch->en_dw_mem = false; |
| pch->en_dw = false; |
| /* normal */ |
| dimp_set(edi_mp_prog_proc_config, 0x23); |
| dimp_set(edi_mp_use_2_interlace_buff, 0);//1? 0? |
| pch->src_type = vframe->source_type; //?? no used |
| pch->ponly = false; |
| //?? di_set_default(ch); |
| memcpy(&mm->cfg, &c_mm_cfg_s4_cp, sizeof(mm->cfg)); |
| #ifdef DBG_BUFFER_FLOW |
| if (s4dw_buf_h) |
| mm->cfg.di_h = s4dw_buf_h; |
| #endif |
| PR_INF("%s:di_h:%d\n", __func__, mm->cfg.di_h); |
| mm->cfg.dis_afbce = 0; |
| mm->cfg.fix_buf = 1; |
| mm->cfg.num_local = 0; |
| mm->cfg.num_post = 5; //tmp; |
| pch->mode = EDPST_MODE_NV21_8BIT; |
| /* dip_init_value_reg end*/ |
| /*******************************************/ |
| dim_ddbg_mod_save(EDI_DBG_MOD_RVB, ch, 0); |
| |
| ppre->bypass_flag = false; |
| |
| //de_devp->nrds_enable = 0; //?? |
| //de_devp->pps_enable = dimp_get(edi_mp_pps_en); // ?? |
| /*di pre h scaling down: sm1 tm2*/ |
| de_devp->h_sc_down_en = 0; //?? |
| |
| if (dimp_get(edi_mp_di_printk_flag) & 2) //?? |
| dimp_set(edi_mp_di_printk_flag, 1); |
| |
| // dim_print("%s: vframe come => di_init_buf\n", __func__); |
| |
| //no use if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) && !de_devp->mem_flg) |
| //no use dim_rev_mem_check(); |
| |
| /*need before set buffer*/ |
| if (dim_afds()) |
| dim_afds()->reg_val(pch); |
| |
| s4dw_buf_init(pch); |
| |
| //no use pre_sec_alloc(pch, mm->cfg.dat_idat_flg.d32); |
| //no use pst_sec_alloc(pch, mm->cfg.dat_pafbct_flg.d32); |
| ppre->mtn_status = //?? need check |
| get_ops_mtn()->adpative_combing_config |
| (vframe->width, |
| (vframe->height >> 1), |
| (vframe->source_type), |
| VFMT_IS_P(vframe->type),/*is_progressive(vframe)*/ |
| vframe->sig_fmt); |
| |
| dimh_patch_post_update_mc_sw(DI_MC_SW_REG, true); |
| di_sum_reg_init(ch); //check |
| |
| //?? dcntr_reg(1); |
| |
| set_init_flag(ch, true);/*init_flag = 1;*/ |
| |
| dim_ddbg_mod_save(EDI_DBG_MOD_RVE, ch, 0); |
| } |
| } |
| |
| enum ES4DW_BYPASS_ID { |
| ES4DW_BYPASS_ALL_BYPASS = 1, |
| ES4DW_BYPASS_CH, |
| ES4DW_BYPASS_NOT_AFBCD, |
| ES4DW_BYPASS_I, |
| ES4DW_BYPASS_TYP, |
| ES4DW_BYPASS_SRC_PPMGR, |
| ES4DW_BYPASS_SIZE_UP_4K, |
| ES4DW_BYPASS_SIZE_DOWN, |
| ES4DW_BYPASS_EOS, |
| }; |
| |
| static unsigned int s4dw_bypasse_checkvf(struct vframe_s *vf) |
| { |
| unsigned int x, y; |
| |
| if (!vf) |
| return 0; |
| if (!IS_COMP_MODE(vf->type)) |
| return ES4DW_BYPASS_NOT_AFBCD; |
| if (VFMT_IS_I(vf->type)) |
| return ES4DW_BYPASS_I; |
| if (vf->type & DIM_BYPASS_VF_TYPE) |
| return ES4DW_BYPASS_TYP; |
| if (vf->type & VIDTYPE_V4L_EOS) |
| return ES4DW_BYPASS_EOS; |
| if (vf->source_type == VFRAME_SOURCE_TYPE_PPMGR) |
| return ES4DW_BYPASS_SRC_PPMGR; |
| |
| dim_vf_x_y(vf, &x, &y); |
| if (x > 3840 || y > 2160) |
| return ES4DW_BYPASS_SIZE_UP_4K; |
| |
| if (x < 128 || y < 16) |
| return ES4DW_BYPASS_SIZE_DOWN; |
| |
| return 0; |
| } |
| |
| static u32 s4dw_bypass_checkother(struct di_ch_s *pch) |
| { |
| if (dimp_get(edi_mp_di_debug_flag) & 0x100000) |
| return ES4DW_BYPASS_ALL_BYPASS; |
| /* EDI_CFGX_BYPASS_ALL */ |
| di_cfgx_set(pch->ch_id, |
| EDI_CFGX_BYPASS_ALL, |
| pch->itf.bypass_ext, DI_BIT4); |
| if (di_cfgx_get(pch->ch_id, EDI_CFGX_BYPASS_ALL)) |
| return ES4DW_BYPASS_CH; |
| //other |
| return 0; |
| } |
| |
| static u32 s4dw_is_bypass(struct di_ch_s *pch, struct vframe_s *vf) |
| { |
| u32 ret = 0; |
| //static u32 last_ret;//dbg only |
| |
| ret = s4dw_bypass_checkother(pch); |
| if (!ret && vf) |
| ret = s4dw_bypasse_checkvf(vf); |
| //debug only |
| if (pch->last_bypass != ret) { |
| PR_INF("%s:ch[%d]:%d->%d\n", __func__, |
| pch->ch_id, pch->last_bypass, ret); |
| pch->last_bypass = ret; |
| } |
| return ret; |
| } |
| |
| /**/ |
| static bool s4dw_bypass_2_ready_bynins(struct di_ch_s *pch, |
| struct dim_nins_s *nins) |
| { |
| void *in_ori; |
| // struct dim_nins_s *nins =NULL; |
| struct di_buffer *buffer = NULL, *buffer_o; |
| struct di_buf_s *buf_pst; |
| |
| if (!nins) { |
| PR_ERR("%s:no in ori ?\n", __func__); |
| return true; |
| } |
| in_ori = nins->c.ori; |
| |
| /* recycle */ |
| nins->c.ori = NULL; |
| nins_used_some_to_recycle(pch, nins); |
| |
| /* to ready buffer */ |
| if (dip_itf_is_ins(pch)) { |
| /* need mark bypass flg*/ |
| buffer = (struct di_buffer *)in_ori; |
| buffer->flag |= DI_FLAG_BUF_BY_PASS; |
| } |
| if (dip_itf_is_ins_exbuf(pch)) { |
| /* get out buffer */ |
| buf_pst = di_que_out_to_di_buf(pch->ch_id, QUE_POST_FREE); |
| if (!buf_pst || !buffer) { |
| PR_ERR("%s:no post free\n", __func__); |
| return true; |
| } |
| |
| buffer_o = buf_pst->c.buffer; |
| if (!buffer_o) { |
| PR_ERR("%s:no buffer_o\n", __func__); |
| return true; |
| } |
| di_buf_clear(pch, buf_pst); |
| di_que_in(pch->ch_id, QUE_PST_NO_BUF_WAIT, buf_pst); |
| if (buffer->flag & DI_FLAG_EOS || |
| (buffer->vf && buffer->vf->type & VIDTYPE_V4L_EOS)) |
| buffer_o->flag |= DI_FLAG_EOS; |
| if (buffer_o->vf) |
| buffer_o->vf->vf_ext = buffer->vf; |
| buffer_o->flag |= DI_FLAG_BUF_BY_PASS; |
| ndrd_qin(pch, buffer_o); |
| } else { |
| ndrd_qin(pch, in_ori); |
| } |
| |
| return true; |
| } |
| |
| const struct dim_s4dw_data_s dim_s4dw_def = { |
| .reg_variable = s4dw_reg_variable, |
| .is_bypass = s4dw_is_bypass, |
| .is_bypass_sys = s4dw_bypass_checkother, |
| .fill_2_ready_bynins = s4dw_bypass_2_ready_bynins, |
| }; |
| |
| static enum DI_ERRORTYPE s4dw_empty_input_l(struct di_ch_s *pch, |
| struct di_buffer *buffer) |
| { |
| // struct dim_itf_s *pintf; |
| unsigned int ch; |
| // struct di_ch_s *pch; |
| unsigned int index; |
| unsigned int free_nub; |
| struct buf_que_s *pbufq; |
| struct dim_nins_s *pins; |
| bool flg_q; |
| |
| ch = pch->ch_id; |
| pbufq = &pch->nin_qb; |
| free_nub = qbufp_count(pbufq, QBF_NINS_Q_IDLE); |
| if (!free_nub) { |
| PR_WARN("%s:no nins idle\n", __func__); |
| return DI_ERR_IN_NO_SPACE; |
| } |
| |
| /* get ins */ |
| flg_q = qbuf_out(pbufq, QBF_NINS_Q_IDLE, &index); |
| if (!flg_q) { |
| PR_ERR("%s:qout\n", __func__); |
| return DI_ERR_IN_NO_SPACE; |
| } |
| pins = (struct dim_nins_s *)pbufq->pbuf[index].qbc; |
| pins->c.ori = buffer; |
| dim_dbg_buffer_ext(pch, buffer, 2); |
| |
| pins->c.cnt = pch->in_cnt; |
| pch->in_cnt++; |
| |
| /* @ary_note: eos may be no vf */ |
| //move to parser memcpy(&pins->c.vfm_cp, buffer->vf, sizeof(pins->c.vfm_cp)); |
| |
| flg_q = qbuf_in(pbufq, QBF_NINS_Q_DCT, index); |
| dbg_copy("%s:%d\n", __func__, pins->c.cnt); |
| sum_g_inc(ch); |
| if (!flg_q) { |
| PR_ERR("%s:qin check\n", __func__); |
| qbuf_in(pbufq, QBF_NINS_Q_IDLE, index); |
| } |
| //dbg_itf_tmode(pch,1); |
| if (pch->in_cnt < 4) { |
| if (pch->in_cnt == 1) |
| dbg_timer(ch, EDBG_TIMER_1_GET); |
| else if (pch->in_cnt == 2) |
| dbg_timer(ch, EDBG_TIMER_2_GET); |
| else if (pch->in_cnt == 3) |
| dbg_timer(ch, EDBG_TIMER_3_GET); |
| } |
| return DI_ERR_NONE; |
| } |
| |
| enum DI_ERRORTYPE s4dw_empty_input(struct di_ch_s *pch, |
| struct di_buffer *buffer) |
| { |
| enum DI_ERRORTYPE ret; |
| |
| mutex_lock(&pch->itf.lock_in); |
| ret = s4dw_empty_input_l(pch, buffer); |
| mutex_unlock(&pch->itf.lock_in); |
| |
| if (ret == DI_ERR_NONE) |
| task_send_ready(20); |
| return ret; |
| } |
| |
| /* in -> check */ |
| void s4dw_parser_infor(struct di_ch_s *pch) |
| { |
| unsigned int index; |
| unsigned int in_nub; |
| struct buf_que_s *pbufq; |
| struct dim_nins_s *pins; |
| bool flg_q; |
| int i; |
| struct vframe_s *vfm = NULL; |
| struct di_buffer *buffer = NULL; |
| u32 bypass_ret; |
| |
| if (!pch || !pch->itf.flg_s4dw) |
| return; |
| pbufq = &pch->nin_qb; |
| in_nub = qbufp_count(pbufq, QBF_NINS_Q_DCT); |
| if (!in_nub) { |
| //PR_WARN("%s:no nins in\n", __func__); |
| return; |
| } |
| for (i = 0; i < in_nub; i++) { |
| /* get ins */ |
| flg_q = qbuf_out(pbufq, QBF_NINS_Q_DCT, &index); |
| if (!flg_q) { |
| PR_ERR("%s:qout\n", __func__); |
| return; |
| } |
| pins = (struct dim_nins_s *)pbufq->pbuf[index].qbc; |
| buffer = (struct di_buffer *)pins->c.ori; |
| if (!buffer->vf) { |
| pins->c.wmode.is_bypass = 1; |
| dbg_copy("set1:b:%d\n", pins->c.cnt); |
| } else { |
| vfm = buffer->vf; |
| bypass_ret = s4dw_is_bypass(pch, vfm); |
| if (bypass_ret) { |
| pins->c.wmode.is_bypass = 1; |
| dbg_copy("set2:b:%d\n", pins->c.cnt); |
| } else { |
| dbg_copy("set3:no bypass:%d\n", pins->c.cnt); |
| memcpy(&pins->c.vfm_cp, vfm, sizeof(pins->c.vfm_cp)); |
| } |
| } |
| |
| flg_q = qbuf_in(pbufq, QBF_NINS_Q_CHECK, index); |
| if (!flg_q) { |
| PR_ERR("%s:qin check:%d:%d\n", __func__, in_nub, i); |
| return; |
| } |
| } |
| } |
| |
| static bool s4dw_pre_sw2bypass(struct di_ch_s *pch, unsigned int bypassid) |
| { |
| struct di_pre_stru_s *ppre; |
| unsigned int ch; |
| bool ret = false; |
| |
| ch = pch->ch_id; |
| ppre = get_pre_stru(ch); |
| |
| dim_bypass_set(pch, 1, bypassid); |
| if (di_bypass_state_get(ch) == 0) { |
| //cnt_rebuild = 0; /*from no bypass to bypass*/ |
| ppre->is_bypass_all = true; |
| bset(&pch->self_trig_mask, 29); |
| /*********************************/ |
| di_bypass_state_set(ch, true);/*bypass_state:1;*/ |
| pch->sumx.need_local = false; |
| PR_INF("%s:to bypass\n", __func__); |
| ret = true; |
| } |
| return ret; |
| } |
| |
| /************************************************* |
| * return |
| * < 0: do not need do next; |
| * > 0: need di process; |
| * -1: no input; |
| * -2: have done; |
| * 1 : not in bypass mode; |
| * 2 : have input but not bypass. |
| **************************************************/ |
| int s4dw_pre_bypass(struct di_ch_s *pch) |
| { |
| struct dim_nins_s *nins = NULL; |
| unsigned int ch, nub, bypass_nub; |
| int i, flg = -1, err = 0; |
| |
| ch = pch->ch_id; |
| // check state |
| if (di_bypass_state_get(ch) == 0) { |
| nins = nins_peek_pre(pch); |
| if (!nins) { |
| dbg_copy("%s:no:input\n", __func__); |
| return -1; // no input |
| } |
| if (nins->c.wmode.is_bypass) { |
| //switch state: |
| dbg_copy("%s:in:bypass\n", __func__); |
| s4dw_pre_sw2bypass(pch, nins->c.wmode.bypass_reason); |
| } else { |
| dbg_copy("%s:not bypass:%d\n", __func__, nins->c.cnt); |
| } |
| } |
| // |
| if (di_bypass_state_get(ch) == 0) |
| return 1; |
| |
| nub = nins_cnt(pch, QBF_NINS_Q_CHECK); |
| |
| if (nub <= 0) |
| return -1; |
| bypass_nub = 0; |
| for (i = 0; i < nub; i++) { |
| nins = nins_peek_pre(pch); |
| if (!nins) { |
| err = 2; |
| break; |
| } |
| if (!nins->c.wmode.is_bypass) { |
| flg = 2; //have input but not bypass. |
| break; |
| } |
| //bypass: |
| nins = nins_get(pch); |
| if (!nins) { |
| err = 1; |
| PR_ERR("%s:peek but can't get\n", __func__); |
| break; |
| } |
| |
| if (pch->rsc_bypass.b.ponly_fst_cnt) { |
| pch->rsc_bypass.b.ponly_fst_cnt--; |
| //PR_INF("%s:%d\n", __func__, pch->rsc_bypass.b.ponly_fst_cnt); |
| } |
| dim_s4dw_def.fill_2_ready_bynins(pch, nins); |
| bypass_nub++; |
| } |
| if (err) { |
| PR_INF("%s:err:%d;%d:%d\n", __func__, err, nub, i); |
| return -1;//no input; |
| } |
| if (nub) |
| dbg_copy("%s:%d,%d\n", __func__, nub, bypass_nub); |
| return flg; |
| } |
| |
| /******************************************** |
| * s4dw_pre_cfg_bypass |
| * part of pre config; |
| * when return > 0 date to ready, and state to bypass |
| * when return 0, state to normal. |
| ********************************************/ |
| unsigned char s4dw_pre_cfg_bypass(struct di_ch_s *pch, struct dim_nins_s *nins) |
| { |
| unsigned int ch, bypassr; |
| struct di_pre_stru_s *ppre; |
| |
| ch = pch->ch_id; |
| ppre = get_pre_stru(ch); |
| |
| bypassr = dim_s4dw_def.is_bypass_sys(pch); |
| if (!bypassr) { |
| if (nins->c.wmode.is_bypass || nins->c.wmode.need_bypass) { |
| bypassr = nins->c.wmode.bypass_reason; |
| } else { |
| //not bypass: |
| return 0; |
| } |
| } |
| /* from normal to bypass ?*/ |
| //dim_bypass_set(pch, 1, bypassr); |
| |
| s4dw_pre_sw2bypass(pch, bypassr); |
| |
| if (pch->rsc_bypass.b.ponly_fst_cnt) { |
| pch->rsc_bypass.b.ponly_fst_cnt--; |
| //PR_INF("%s:%d\n", __func__, pch->rsc_bypass.b.ponly_fst_cnt); |
| } |
| dim_s4dw_def.fill_2_ready_bynins(pch, nins); |
| |
| return (unsigned char)bypassr; |
| } |
| |
| /*copy from dimpst_fill_outvf */ |
| static void s4dw_fill_pstvf_cvs(struct di_ch_s *pch, |
| struct di_buf_s *di_buf, |
| enum EDPST_OUT_MODE mode) |
| { |
| struct canvas_config_s *cvsp, *cvsf; |
| struct vframe_s *vfm; |
| struct di_buffer *buffer; //for ext buff |
| struct div2_mm_s *mm; |
| |
| if (!di_buf || !di_buf->vframe) |
| return; |
| |
| vfm = di_buf->vframe; |
| |
| if (dip_itf_is_ins_exbuf(pch)) { |
| if (!di_buf->c.buffer) { |
| PR_ERR("%s:ext_buf,no buffer\n", __func__); |
| return; |
| } |
| buffer = (struct di_buffer *)di_buf->c.buffer; |
| if (!buffer->vf) { |
| PR_ERR("%s:ext_buf,no vf\n", __func__); |
| return; |
| } |
| dim_print("%s:buffer %px\n", __func__, buffer); |
| cvsf = &buffer->vf->canvas0_config[0]; |
| cvsp = &vfm->canvas0_config[0]; |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->width = cvsf->width; |
| cvsp->height = cvsf->height; |
| //if (buffer->vf->plane_num == 1) |
| // return; |
| cvsf = &buffer->vf->canvas0_config[1]; |
| cvsp = &vfm->canvas0_config[1]; |
| |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->width = cvsf->width; |
| cvsp->height = cvsf->height; |
| #ifdef DBG_EXTBUFFER_ONLY_ADDR |
| cvsp = &vfm->canvas0_config[0]; |
| if (cvsp->width) |
| return; |
| vfm->plane_num = 2; |
| mm = dim_mm_get(pch->ch_id); |
| |
| cvsp->width = mm->cfg.pst_cvs_w; |
| cvsp->height = mm->cfg.pst_cvs_h; |
| |
| cvsp = &vfm->canvas0_config[1]; |
| cvsp->width = mm->cfg.pst_cvs_w; |
| cvsp->height = mm->cfg.pst_cvs_h; |
| #endif |
| return; |
| } |
| /*local*/ |
| vfm->canvas0Addr = (u32)-1; |
| vfm->canvas1Addr = (u32)-1; |
| mm = dim_mm_get(pch->ch_id); |
| if (mode == EDPST_OUT_MODE_DEF) { |
| vfm->plane_num = 1; |
| cvsp = &vfm->canvas0_config[0]; |
| cvsp->phy_addr = di_buf->nr_adr; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| //di_buf->canvas_width[NR_CANVAS]; |
| //di_buf->canvas_height; |
| cvsp->width = mm->cfg.pst_cvs_w; |
| cvsp->height = mm->cfg.pst_cvs_h; |
| } else { |
| vfm->plane_num = 2; |
| cvsp = &vfm->canvas0_config[0]; |
| cvsp->phy_addr = di_buf->nr_adr; |
| cvsp->width = mm->cfg.pst_cvs_w; |
| cvsp->height = mm->cfg.pst_cvs_h; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| |
| cvsp = &vfm->canvas0_config[1]; |
| cvsp->phy_addr = di_buf->nr_adr + mm->cfg.pst_buf_y_size; |
| cvsp->width = mm->cfg.pst_cvs_w; |
| cvsp->height = mm->cfg.pst_cvs_h; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| } |
| } |
| |
| static void s4_dw_dimpst_fill_outvf(struct vframe_s *vfm, |
| struct di_buf_s *di_buf, |
| enum EDPST_OUT_MODE mode) |
| { |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| unsigned int ch; |
| struct di_ch_s *pch; |
| //bool ext_buf = false; |
| |
| //check ext buffer: |
| ch = di_buf->channel; |
| pch = get_chdata(ch); |
| |
| /* canvas */ |
| s4dw_fill_pstvf_cvs(pch, di_buf, mode); |
| |
| dim_print("%s:addr0[0x%lx], 1[0x%lx],w[%d,%d]\n", |
| __func__, |
| (unsigned long)vfm->canvas0_config[0].phy_addr, |
| (unsigned long)vfm->canvas0_config[1].phy_addr, |
| vfm->canvas0_config[0].width, |
| vfm->canvas0_config[0].height); |
| |
| /* type */ |
| if (mode == EDPST_OUT_MODE_NV21 || |
| mode == EDPST_OUT_MODE_NV12) { |
| /*clear*/ |
| vfm->type &= ~(VIDTYPE_VIU_NV12 | |
| VIDTYPE_VIU_444 | |
| VIDTYPE_VIU_NV21 | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_COMPRESS | |
| VIDTYPE_PRE_INTERLACE); |
| vfm->type |= VIDTYPE_VIU_FIELD; |
| vfm->type |= VIDTYPE_DI_PW; |
| if (mode == EDPST_OUT_MODE_NV21) |
| vfm->type |= VIDTYPE_VIU_NV21; |
| else |
| vfm->type |= VIDTYPE_VIU_NV12; |
| |
| /* bit */ |
| vfm->bitdepth &= ~(BITDEPTH_MASK); |
| vfm->bitdepth &= ~(FULL_PACK_422_MODE); |
| vfm->bitdepth |= (BITDEPTH_Y8 | |
| BITDEPTH_U8 | |
| BITDEPTH_V8); |
| } |
| |
| if (de_devp->pps_enable && |
| dimp_get(edi_mp_pps_position) == 0) { |
| if (dimp_get(edi_mp_pps_dstw)) |
| vfm->width = dimp_get(edi_mp_pps_dstw); |
| |
| if (dimp_get(edi_mp_pps_dsth)) |
| vfm->height = dimp_get(edi_mp_pps_dsth); |
| } |
| |
| if (di_buf->afbc_info & DI_BIT0) |
| vfm->height = vfm->height / 2; |
| |
| //dim_print("%s:h[%d]\n", __func__, vfm->height); |
| #ifdef NV21_DBG |
| if (cfg_vf) |
| vfm->type = cfg_vf; |
| #endif |
| } |
| |
| /* copy from mem_resize_buf*/ |
| static void s4dw_mem_resize_buf(struct di_ch_s *pch, struct di_buf_s *di_buf) |
| { |
| struct div2_mm_s *mm; |
| struct di_buffer *buf; |
| struct canvas_config_s *cvs; |
| |
| //struct vframe_s *vfm; |
| mm = dim_mm_get(pch->ch_id); |
| |
| if (dip_itf_is_ins_exbuf(pch)) { |
| buf = (struct di_buffer *)di_buf->c.buffer; |
| if (buf && buf->vf) { |
| di_buf->canvas_width[NR_CANVAS] = buf->vf->canvas0_config[0].width; |
| return; |
| } |
| PR_ERR("%s:\n", __func__); |
| } else { |
| //for local buffer: |
| cvs = &di_buf->vframe->canvas0_config[0]; |
| cvs->width = mm->cfg.pst_cvs_w; |
| cvs->height = mm->cfg.pst_cvs_h; |
| cvs = &di_buf->vframe->canvas0_config[1]; |
| cvs->width = mm->cfg.pst_cvs_w; |
| cvs->height = mm->cfg.pst_cvs_h; |
| } |
| |
| di_buf->canvas_width[NR_CANVAS] = mm->cfg.pst_cvs_w; |
| } |
| |
| static unsigned char s4dw_pre_buf_config(struct di_ch_s *pch) |
| { |
| unsigned int channel; |
| struct di_buf_s *di_buf = NULL; |
| struct vframe_s *vframe; |
| unsigned char change_type = 0; |
| unsigned char change_type2 = 0; |
| bool bit10_pack_patch = false; |
| unsigned int width_roundup = 2; |
| struct di_pre_stru_s *ppre; |
| |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| int cfg_prog_proc = dimp_get(edi_mp_prog_proc_config); |
| unsigned int nv21_flg = 0; |
| enum EDI_SGN sgn; |
| struct div2_mm_s *mm; |
| u32 cur_dw_width = 0xffff; |
| u32 cur_dw_height = 0xffff; |
| struct dim_nins_s *nins = NULL; |
| enum EDPST_OUT_MODE tmpmode; |
| unsigned int pps_w, pps_h; |
| u32 typetmp; |
| unsigned char chg_hdr = 0; |
| |
| if (!pch) { |
| PR_ERR("%s:no pch\n", __func__); |
| return 100; |
| } |
| channel = pch->ch_id; |
| ppre = get_pre_stru(channel); |
| |
| //tmp if (di_blocking) /* pause */ |
| // return 1; |
| |
| if (di_que_list_count(channel, QUE_IN_FREE) < 1) |
| return 2; |
| |
| if (di_que_is_empty(channel, QUE_POST_FREE)) |
| return 5; |
| |
| /* check post buffer */ |
| di_buf = di_que_peek(channel, QUE_POST_FREE); |
| mm = dim_mm_get(channel); |
| if (!dip_itf_is_ins_exbuf(pch) && |
| (!di_buf->blk_buf || |
| di_buf->blk_buf->flg.d32 != mm->cfg.pbuf_flg.d32)) { |
| if (!di_buf->blk_buf) |
| PR_ERR("%s:pst no blk:idx[%d]\n", |
| __func__, |
| di_buf->index); |
| else |
| PR_ERR("%s:pst flgis err:buf:idx[%d] 0x%x->0x%x\n", |
| __func__, |
| di_buf->index, |
| mm->cfg.pbuf_flg.d32, |
| di_buf->blk_buf->flg.d32); |
| |
| return 6; |
| } |
| |
| /* input get */ |
| nins = nins_peek_pre(pch); |
| if (!nins) |
| return 10; |
| nins = nins_get(pch); |
| if (!nins) { |
| PR_ERR("%s:peek but can't get\n", __func__); |
| return 14; |
| } |
| /* bypass control */ |
| if (s4dw_pre_cfg_bypass(pch, nins)) |
| return 101; |
| /**************************************************/ |
| vframe = &nins->c.vfm_cp; |
| |
| /*mem check*/ |
| memcpy(&ppre->vfm_cpy, vframe, sizeof(ppre->vfm_cpy)); |
| |
| sgn = di_vframe_2_sgn(vframe); |
| |
| if (nins->c.cnt < 3) { |
| if (nins->c.cnt == 0) |
| dbg_timer(channel, EDBG_TIMER_1_PRE_CFG); |
| else if (nins->c.cnt == 1) |
| dbg_timer(channel, EDBG_TIMER_2_PRE_CFG); |
| else if (nins->c.cnt == 2) |
| dbg_timer(channel, EDBG_TIMER_3_PRE_CFG); |
| } |
| |
| if (vframe->type & VIDTYPE_COMPRESS) { |
| /* backup the original vf->width/height for bypass case */ |
| cur_dw_width = vframe->width; |
| cur_dw_height = vframe->height; |
| vframe->width = vframe->compWidth; |
| vframe->height = vframe->compHeight; |
| } |
| dim_tr_ops.pre_get(vframe->index_disp); |
| if (dip_itf_is_vfm(pch)) |
| didbg_vframe_in_copy(channel, nins->c.ori); |
| else |
| didbg_vframe_in_copy(channel, vframe); |
| |
| dim_print("DI:ch[%d]get %dth vf[0x%p][%d] from front %u ms\n", |
| channel, |
| ppre->in_seq, vframe, |
| vframe->index_disp, |
| jiffies_to_msecs(jiffies_64 - |
| vframe->ready_jiffies64)); |
| vframe->prog_proc_config = (cfg_prog_proc & 0x20) >> 5; |
| |
| bit10_pack_patch = (is_meson_gxtvbb_cpu() || |
| is_meson_gxl_cpu() || |
| is_meson_gxm_cpu()); |
| width_roundup = bit10_pack_patch ? 16 : width_roundup; |
| |
| dimp_set(edi_mp_force_width, 0); |
| |
| ppre->source_trans_fmt = vframe->trans_fmt; |
| |
| ppre->invert_flag = false; |
| vframe->type &= ~TB_DETECT_MASK; |
| |
| ppre->width_bk = vframe->width; |
| if (dimp_get(edi_mp_force_width)) |
| vframe->width = dimp_get(edi_mp_force_width); |
| if (dimp_get(edi_mp_force_height)) |
| vframe->height = dimp_get(edi_mp_force_height); |
| vframe->width = roundup(vframe->width, width_roundup); |
| |
| /* backup frame motion info */ |
| vframe->combing_cur_lev = dimp_get(edi_mp_cur_lev);/*cur_lev;*/ |
| |
| dim_print("%s: vf_get => 0x%p\n", __func__, nins->c.ori); |
| |
| di_buf = di_que_out_to_di_buf(channel, QUE_IN_FREE); |
| di_buf->dec_vf_state = 0; /*dec vf keep*/ |
| di_buf->is_eos = 0; |
| if (dim_check_di_buf(di_buf, 10, channel)) |
| return 16; |
| |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_VFRAME) |
| dim_dump_vframe(vframe); |
| |
| memcpy(di_buf->vframe, vframe, sizeof(vframe_t)); |
| dim_dbg_pre_cnt(channel, "cf1"); |
| di_buf->width_bk = ppre->width_bk; /*ary.sui 2019-04-23*/ |
| di_buf->dw_width_bk = cur_dw_width; |
| di_buf->dw_height_bk = cur_dw_height; |
| di_buf->vframe->private_data = di_buf; |
| //10-09 di_buf->vframe->vf_ext = NULL; /*09-25*/ |
| |
| di_buf->c.in = nins; |
| //dbg_nins_log_buf(di_buf, 1); |
| |
| di_buf->seq = ppre->in_seq; |
| ppre->in_seq++; |
| |
| /* source change*/ |
| pre_vinfo_set(channel, vframe); |
| change_type = is_source_change(vframe, channel); |
| |
| if (change_type) { |
| sgn = di_vframe_2_sgn(vframe); |
| ppre->sgn_lv = sgn; |
| PR_INF("%s:ch[%d]:%ums %dth source change:\n", |
| "pre cfg", |
| channel, |
| jiffies_to_msecs(jiffies_64), |
| ppre->in_seq); |
| PR_INF("source change:cp:0x%x/%d/%d/%d=>0x%x/%d/%d/%d:%d\n", |
| ppre->cur_inp_type, |
| ppre->cur_width, |
| ppre->cur_height, |
| ppre->cur_source_type, |
| di_buf->vframe->type, |
| di_buf->vframe->width, |
| di_buf->vframe->height, |
| di_buf->vframe->source_type, ppre->sgn_lv); |
| if (di_buf->vframe->type & VIDTYPE_COMPRESS) { |
| ppre->cur_width = |
| di_buf->vframe->compWidth; |
| ppre->cur_height = |
| di_buf->vframe->compHeight; |
| } else { |
| ppre->cur_width = di_buf->vframe->width; |
| ppre->cur_height = di_buf->vframe->height; |
| } |
| ppre->pps_width = ppre->cur_width; |
| ppre->pps_height = ppre->cur_height; |
| |
| if (IS_COMP_MODE(vframe->type)) { |
| PR_INF("enable afbc skip\n"); |
| pps_w = ppre->cur_width >> 1; |
| pps_h = ppre->cur_height >> 1; |
| //dip_cfg_afbcskip_s(pps_w, pps_h); |
| ppre->afbc_skip_w = pps_w; |
| ppre->afbc_skip_h = pps_h; |
| //dip_cfg_afbcskip_ori_s(ppre->cur_width, ppre->cur_height); |
| ppre->pps_width = pps_w; |
| ppre->pps_height = pps_h; |
| |
| PR_INF("en pps\n"); |
| //de_devp->pps_enable = true; |
| pps_w = pps_w >> 1; |
| pps_h = pps_h >> 1; |
| //dip_cfg_afbcskip_pps_s(pps_w, pps_h); |
| ppre->pps_dstw = pps_w; |
| ppre->pps_dsth = pps_h; |
| #ifdef DBG_BUFFER_FLOW |
| /* by hand */ |
| if (afbc_skip_pps_w) |
| ppre->pps_dstw = afbc_skip_pps_w; |
| if (afbc_skip_pps_h) |
| ppre->pps_dsth = afbc_skip_pps_h; |
| |
| #endif |
| } |
| /* dw */ |
| memset(&ppre->shrk_cfg, 0, |
| sizeof(ppre->shrk_cfg)); |
| |
| ppre->cur_prog_flag = VFMT_IS_P(di_buf->vframe->type); |
| // is_progressive(di_buf->vframe); |
| if (ppre->cur_prog_flag) { |
| ppre->prog_proc_type = 0x10; |
| pch->sumx.need_local = 0; |
| } else { |
| ppre->prog_proc_type = 0; |
| pch->sumx.need_local = true; |
| } |
| ppre->cur_inp_type = di_buf->vframe->type; |
| ppre->cur_source_type = |
| di_buf->vframe->source_type; |
| ppre->cur_sig_fmt = di_buf->vframe->sig_fmt; |
| ppre->orientation = di_buf->vframe->video_angle; |
| ppre->source_change_flag = 1; |
| ppre->input_size_change_flag = true; |
| ppre->is_bypass_mem = 0; |
| |
| ppre->field_count_for_cont = 0; |
| ppre->used_pps = true; |
| chg_hdr++; |
| } else { /* not change */ |
| ppre->cur_inp_type = di_buf->vframe->type; |
| } |
| dimp_set(edi_mp_pps_position, 1); |
| dimp_set(edi_mp_pps_dstw, ppre->pps_dstw); |
| dimp_set(edi_mp_pps_dsth, ppre->pps_dsth); |
| /*--------------------------*/ |
| if (!change_type) { |
| change_type2 = is_vinfo_change(channel); |
| if (change_type2) { |
| /*ppre->source_change_flag = 1;*/ |
| ppre->input_size_change_flag = true; |
| } |
| } |
| /*--------------------------*/ |
| if (VFMT_IS_P(di_buf->vframe->type)) { |
| if (ppre->is_bypass_all) { /* ??need check: from bypass to normal*/ |
| ppre->input_size_change_flag = true; |
| ppre->source_change_flag = 1; |
| bclr(&pch->self_trig_mask, 29); |
| //ppre->field_count_for_cont = 0; |
| } |
| ppre->is_bypass_all = false; |
| di_buf->post_proc_flag = 0; |
| ppre->di_inp_buf = di_buf; |
| |
| if (!ppre->di_mem_buf_dup_p) { |
| /* use n */ |
| ppre->di_mem_buf_dup_p = di_buf; |
| } |
| } else { |
| PR_ERR("%s:i?\n", __func__); |
| } |
| |
| /* peek input end */ |
| /******************************************/ |
| /*dim_dbg_pre_cnt(channel, "cfg");*/ |
| /* di_wr_buf */ |
| |
| if (ppre->prog_proc_type == 0x10) { |
| /********************************************************/ |
| /* di_buf is local buf */ |
| //di_que_out_to_di_buf(channel, QUE_POST_FREE); |
| //di_buf = pp_pst_2_local(pch); |
| di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE); |
| if (dim_check_di_buf(di_buf, 17, channel)) { |
| //di_unlock_irqfiq_restore(irq_flag2); |
| return 22; |
| } |
| //move to below s4dw_mem_resize_buf(pch, di_buf);//need check |
| /* hdr */ |
| di_buf->c.en_hdr = false; |
| |
| di_buf->post_proc_flag = 0; |
| di_buf->canvas_config_flag = 1; |
| di_buf->di_wr_linked_buf = NULL; |
| di_buf->c.src_is_i = false; |
| |
| di_buf->en_hf = 0; |
| |
| di_buf->hf_done = 0; |
| |
| //if (dim_cfg_pre_nv21(0)) { |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) { |
| nv21_flg = 0; |
| di_buf->flg_nv21 = 0; |
| } else if ((cfggch(pch, POUT_FMT) == 1) || (cfggch(pch, POUT_FMT) == 2)) { |
| nv21_flg = 1; /*nv21*/ |
| di_buf->flg_nv21 = cfggch(pch, POUT_FMT); |
| } else if ((cfggch(pch, POUT_FMT) == 5) && |
| (ppre->sgn_lv == EDI_SGN_4K)) { |
| nv21_flg = 1; /*nv21*/ |
| di_buf->flg_nv21 = 1; |
| } |
| /*keep dec vf*/ |
| //di_buf->dec_vf_state = DI_BIT0; |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) |
| ppre->di_inp_buf->dec_vf_state = DI_BIT0; |
| else if (cfggch(pch, KEEP_DEC_VF) == 1) |
| ppre->di_inp_buf->dec_vf_state = DI_BIT0; |
| else if ((cfggch(pch, KEEP_DEC_VF) == 2) && |
| (ppre->sgn_lv == EDI_SGN_4K)) |
| ppre->di_inp_buf->dec_vf_state = DI_BIT0; |
| |
| if ((dip_is_support_nv2110(channel)) && |
| ppre->sgn_lv == EDI_SGN_4K) |
| di_buf->afbce_out_yuv420_10 = 1; |
| else |
| di_buf->afbce_out_yuv420_10 = 0; |
| |
| if (ppre->shrk_cfg.shrk_en) { |
| dw_pre_sync_addr(&ppre->dw_wr_dvfm, di_buf); |
| di_buf->dw_have = true; |
| ppre->dw_wr_dvfm.is_dw = true; |
| } else { |
| di_buf->dw_have = false; |
| ppre->dw_wr_dvfm.is_dw = false; |
| } |
| |
| if (ppre->input_size_change_flag) |
| di_buf->trig_post_update = 1; |
| else |
| di_buf->trig_post_update = 0; |
| |
| } else { |
| PR_ERR("%s:3 check\n", __func__); |
| } |
| |
| di_buf->afbc_sgn_cfg = 0; |
| di_buf->sgn_lv = ppre->sgn_lv; |
| ppre->di_wr_buf = di_buf; |
| ppre->di_wr_buf->pre_ref_count = 1; |
| |
| if (ppre->cur_inp_type & VIDTYPE_COMPRESS) { |
| ppre->di_inp_buf->vframe->width = |
| ppre->di_inp_buf->vframe->compWidth; |
| ppre->di_inp_buf->vframe->height = |
| ppre->di_inp_buf->vframe->compHeight; |
| } |
| |
| memcpy(di_buf->vframe, |
| ppre->di_inp_buf->vframe, sizeof(vframe_t)); |
| di_buf->dw_width_bk = cur_dw_width; |
| di_buf->dw_height_bk = cur_dw_height; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; |
| s4dw_mem_resize_buf(pch, di_buf); //move from before |
| //if (di_buf->vframe->width == 3840 && di_buf->vframe->height == 2160) |
| if (ppre->sgn_lv == EDI_SGN_4K) |
| di_buf->is_4k = 1; |
| else |
| di_buf->is_4k = 0; |
| |
| ppre->is_bypass_mem = 1; //for copy mode |
| /* set vframe bit info */ |
| di_buf->vframe->bitdepth &= ~(BITDEPTH_YMASK); |
| di_buf->vframe->bitdepth &= ~(FULL_PACK_422_MODE); |
| /* no need pps auto */ |
| if (ppre->used_pps) { |
| di_buf->vframe->width = ppre->afbc_skip_w; |
| di_buf->vframe->height = ppre->afbc_skip_h; |
| ppre->width_bk = ppre->afbc_skip_w; |
| { |
| di_buf->vframe->width = ppre->pps_dstw; |
| di_buf->vframe->height = ppre->pps_dsth; |
| ppre->width_bk = ppre->pps_dstw; |
| } |
| } else if (de_devp->pps_enable && dimp_get(edi_mp_pps_position)) { |
| if (dimp_get(edi_mp_pps_dstw) != di_buf->vframe->width) { |
| di_buf->vframe->width = dimp_get(edi_mp_pps_dstw); |
| ppre->width_bk = dimp_get(edi_mp_pps_dstw); |
| } |
| if (dimp_get(edi_mp_pps_dsth) != di_buf->vframe->height) |
| di_buf->vframe->height = dimp_get(edi_mp_pps_dsth); |
| } else if (de_devp->h_sc_down_en) { |
| if (di_mp_uit_get(edi_mp_pre_hsc_down_width) |
| != di_buf->vframe->width) { |
| pr_info("di: hscd %d to %d\n", di_buf->vframe->width, |
| di_mp_uit_get(edi_mp_pre_hsc_down_width)); |
| di_buf->vframe->width = |
| di_mp_uit_get(edi_mp_pre_hsc_down_width); |
| /*di_pre_stru.width_bk = pre_hsc_down_width;*/ |
| ppre->width_bk = |
| di_mp_uit_get(edi_mp_pre_hsc_down_width); |
| } |
| } |
| if (dimp_get(edi_mp_di_force_bit_mode) == 10) { |
| di_buf->vframe->bitdepth |= (BITDEPTH_Y10); |
| if (dimp_get(edi_mp_full_422_pack)) |
| di_buf->vframe->bitdepth |= (FULL_PACK_422_MODE); |
| } else { |
| di_buf->vframe->bitdepth |= (BITDEPTH_Y8); |
| } |
| di_buf->width_bk = ppre->width_bk; /*ary:2019-04-23*/ |
| di_buf->field_count = ppre->field_count_for_cont; |
| if (ppre->prog_proc_type) { |
| if (ppre->prog_proc_type != 0x10 || |
| (ppre->prog_proc_type == 0x10 && !nv21_flg)) |
| di_buf->vframe->type = VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD; |
| if (ppre->cur_inp_type & VIDTYPE_PRE_INTERLACE) |
| di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; |
| |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) { |
| if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| if (IS_COMP_MODE(ppre->di_inp_buf->vframe->type)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_P_H265); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_P); |
| } |
| } |
| } else if (ppre->prog_proc_type == 0x10 && |
| (nv21_flg || |
| (cfggch(pch, POUT_FMT) == 0) || |
| (((cfggch(pch, POUT_FMT) == 4) || |
| (cfggch(pch, POUT_FMT) == 5) || |
| (cfggch(pch, POUT_FMT) == 6) || |
| (cfggch(pch, POUT_FMT) == 7)) && |
| (ppre->sgn_lv <= EDI_SGN_HD)))) { |
| if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| typetmp = ppre->di_inp_buf->vframe->type; |
| if (IS_COMP_MODE(typetmp)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_P_H265_AS_P); |
| //for copy not need afbcd mem |
| //di_buf->afbc_sgn_cfg = |
| // dim_afds()->cnt_sgn_mode |
| // (AFBC_SGN_H265_SINP); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_BYPSS); |
| } |
| } |
| } else { |
| if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| typetmp = ppre->di_inp_buf->vframe->type; |
| if (IS_COMP_MODE(typetmp)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_P_H265); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_P); |
| } |
| } |
| } |
| if (nv21_flg && ppre->prog_proc_type == 0x10) { |
| dim_print("cfg wr buf as nv21\n"); |
| if (cfggch(pch, POUT_FMT) == 1) |
| tmpmode = EDPST_OUT_MODE_NV21; |
| else |
| tmpmode = EDPST_OUT_MODE_NV12; |
| s4_dw_dimpst_fill_outvf(di_buf->vframe, |
| di_buf, tmpmode); |
| } |
| } else { |
| //for interlace |
| } |
| |
| //need check: dimp_set(edi_mp_bypass_post_state, 0); |
| |
| ppre->madi_enable = 0; |
| ppre->mcdi_enable = 0; |
| di_buf->post_proc_flag = 0; |
| dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); |
| |
| if (ppre->di_mem_buf_dup_p == ppre->di_wr_buf || |
| ppre->di_chan2_buf_dup_p == ppre->di_wr_buf) { |
| PR_ERR("+++++++++++++++++++++++\n"); |
| |
| return 24; |
| } |
| dim_dbg_vf_cvs(pch, ppre->di_wr_buf->vframe, 1); |
| |
| //need check di_load_pq_table(); |
| //need check: |
| ppre->combing_fix_en = false;//di_mpr(combing_fix_en); |
| |
| return 0; /*ok*/ |
| } |
| |
| void s4dw_hpre_check_pps(void) |
| { |
| struct di_hpre_s *pre = get_hw_pre(); |
| struct di_pre_stru_s *ppre; |
| |
| ppre = pre->pres; |
| if (pre->used_pps && !ppre->used_pps) { |
| dim_pps_disable(); |
| dim_print("pps->no pps\n"); |
| pre->used_pps = false; |
| } else if (!pre->used_pps && ppre->used_pps) { |
| ppre->input_size_change_flag = true; |
| pre->used_pps = true; |
| dim_print("no pps->pps\n"); |
| } |
| } |
| |
| static void s4dw_pre_set(unsigned int channel) |
| { |
| //ulong irq_flag2 = 0; |
| unsigned short pre_width = 0, pre_height = 0, t5d_cnt; |
| unsigned char chan2_field_num = 1; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| int canvases_idex = ppre->field_count_for_cont % 2; |
| unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK; |
| struct di_cvs_s *cvss; |
| struct vframe_s *vf_i, *vf_mem, *vf_chan2; |
| union hw_sc2_ctr_pre_s *sc2_pre_cfg; |
| struct di_ch_s *pch; |
| u32 cvs_nv21[2]; |
| bool mc_en = false;//dimp_get(edi_mp_mcpre_en) |
| |
| vf_i = NULL; |
| vf_mem = NULL; |
| vf_chan2 = NULL; |
| #ifdef TMP_S4DW_MC_EN |
| mc_en = dimp_get(edi_mp_mcpre_en) ? true : false; |
| #endif |
| pch = get_chdata(channel); |
| ppre->pre_de_process_flag = 1; |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_SETB, channel, ppre->in_seq);/*dbg*/ |
| cvss = &get_datal()->cvs; |
| |
| if (IS_ERR_OR_NULL(ppre->di_inp_buf)) |
| return; |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| pre_inp_canvas_config(ppre->di_inp_buf->vframe); |
| #endif |
| |
| pre_inp_mif_w(&ppre->di_inp_mif, ppre->di_inp_buf->vframe); |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_inp_mif, |
| DI_MIF0_ID_INP, |
| ppre->di_inp_buf, |
| channel); |
| else |
| config_di_mif(&ppre->di_inp_mif, ppre->di_inp_buf, channel); |
| /* pr_dbg("set_separate_en=%d vframe->type %d\n", |
| * di_pre_stru.di_inp_mif.set_separate_en, |
| * di_pre_stru.di_inp_buf->vframe->type); |
| */ |
| |
| if (IS_ERR_OR_NULL(ppre->di_mem_buf_dup_p)) |
| return; |
| |
| dim_secure_sw_pre(channel); |
| #ifdef S4D_OLD_SETTING_KEEP |
| if (ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p != ppre->di_inp_buf) { |
| if (ppre->di_mem_buf_dup_p->flg_nv21) { |
| cvs_nv21[0] = cvss->post_idx[1][3]; |
| cvs_nv21[1] = cvss->post_idx[1][4]; |
| ppre->di_mem_buf_dup_p->vframe->canvas0Addr = ((u32)-1); |
| dim_canvas_set2(ppre->di_mem_buf_dup_p->vframe, |
| &cvs_nv21[0]); |
| dim_print("mem:vfm:pnub[%d]\n", |
| ppre->di_mem_buf_dup_p->vframe->plane_num); |
| //dim_print("mem:vfm:w[%d]\n", |
| //ppre->di_mem_buf_dup_p->vframe-> |
| //canvas0_config[0].width); |
| //ppre->di_mem_mif.canvas_num = |
| //re->di_mem_buf_dup_p->vframe->canvas0Addr; |
| } else { |
| config_canvas_idx(ppre->di_mem_buf_dup_p, |
| cvss->pre_idx[canvases_idex][0], -1); |
| } |
| dim_print("mem:flg_nv21[%d]:flg_[%d] %px\n", |
| ppre->di_mem_buf_dup_p->flg_nv21, |
| ppre->di_mem_buf_dup_p->flg_nr, |
| ppre->di_mem_buf_dup_p); |
| config_cnt_canvas_idx(ppre->di_mem_buf_dup_p, |
| cvss->pre_idx[canvases_idex][1]); |
| if (DIM_IS_IC_EF(T7)) { |
| ppre->di_contp2rd_mif.addr = |
| ppre->di_mem_buf_dup_p->cnt_adr; |
| dbg_ic("contp2rd:0x%lx\n", ppre->di_contp2rd_mif.addr); |
| } |
| } else { |
| config_cnt_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][1]); |
| config_di_cnt_mif(&ppre->di_contp2rd_mif, |
| ppre->di_wr_buf); |
| } |
| if (ppre->di_chan2_buf_dup_p) { |
| config_canvas_idx(ppre->di_chan2_buf_dup_p, |
| cvss->pre_idx[canvases_idex][2], -1); |
| config_cnt_canvas_idx(ppre->di_chan2_buf_dup_p, |
| cvss->pre_idx[canvases_idex][3]); |
| } else { |
| config_cnt_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][3]); |
| } |
| #endif /* S4D_OLD_SETTING_KEEP */ |
| ppre->di_nrwr_mif.is_dw = 0; |
| if (ppre->di_wr_buf->flg_nv21) { |
| //cvss = &get_datal()->cvs; |
| //0925 cvs_nv21[0] = cvss->post_idx[1][1]; |
| cvs_nv21[0] = cvss->pre_idx[canvases_idex][4];//0925 |
| cvs_nv21[1] = cvss->post_idx[1][2]; |
| ppre->di_wr_buf->vframe->canvas0Addr = ((u32)-1); |
| dim_dbg_vf_cvs(pch, ppre->di_wr_buf->vframe, 5); |
| dim_canvas_set2(ppre->di_wr_buf->vframe, &cvs_nv21[0]); |
| #ifdef S4D_OLD_SETTING_KEEP |
| config_canvas_idx_mtn(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][5]); |
| #endif /* S4D_OLD_SETTING_KEEP */ |
| //ppost->di_diwr_mif.canvas_num = pst->vf_post.canvas0Addr; |
| ppre->di_nrwr_mif.canvas_num = |
| ppre->di_wr_buf->vframe->canvas0Addr; |
| ppre->di_wr_buf->nr_canvas_idx = |
| ppre->di_wr_buf->vframe->canvas0Addr; |
| if (ppre->di_wr_buf->flg_nv21 == 1) |
| ppre->di_nrwr_mif.cbcr_swap = 0; |
| else |
| ppre->di_nrwr_mif.cbcr_swap = 1; |
| if (dip_itf_is_o_linear(pch)) { |
| ppre->di_nrwr_mif.reg_swap = 0; |
| ppre->di_nrwr_mif.l_endian = 1; |
| |
| } else { |
| ppre->di_nrwr_mif.reg_swap = 1; |
| ppre->di_nrwr_mif.l_endian = 0; |
| } |
| if (cfgg(LINEAR)) { |
| ppre->di_nrwr_mif.linear = 1; |
| ppre->di_nrwr_mif.addr = |
| ppre->di_wr_buf->vframe->canvas0_config[0].phy_addr; |
| ppre->di_nrwr_mif.addr1 = |
| ppre->di_wr_buf->vframe->canvas0_config[1].phy_addr; |
| } |
| } else if (ppre->shrk_cfg.shrk_en) { |
| ppre->di_nrwr_mif.reg_swap = 1; |
| ppre->di_nrwr_mif.cbcr_swap = 0; |
| ppre->di_nrwr_mif.l_endian = 0; |
| ppre->di_nrwr_mif.is_dw = 1; |
| if (cfgg(LINEAR)) { |
| ppre->di_nrwr_mif.linear = 1; |
| ppre->di_nrwr_mif.addr = |
| ppre->dw_wr_dvfm.vfs.canvas0_config[0].phy_addr; |
| ppre->di_nrwr_mif.addr1 = |
| ppre->dw_wr_dvfm.vfs.canvas0_config[1].phy_addr; |
| } |
| |
| dim_dvf_config_canvas(&ppre->dw_wr_dvfm); |
| //ppre->di_wr_buf->vframe->canvas0Addr = cvs_nv21[0]; |
| //ppre->di_wr_buf->vframe->canvas1Addr = cvs_nv21[0]; /*?*/ |
| //dim_print("wr:%px\n", ppre->di_wr_buf); |
| } else { |
| ppre->di_nrwr_mif.reg_swap = 1; |
| ppre->di_nrwr_mif.cbcr_swap = 0; |
| ppre->di_nrwr_mif.l_endian = 0; |
| if (cfgg(LINEAR)) { |
| ppre->di_nrwr_mif.linear = 1; |
| ppre->di_nrwr_mif.addr = ppre->di_wr_buf->nr_adr; |
| } |
| config_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][4], |
| cvss->pre_idx[canvases_idex][5]); |
| } |
| #ifdef S4D_OLD_SETTING_KEEP |
| config_cnt_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][6]); |
| #endif /* S4D_OLD_SETTING_KEEP */ |
| #ifdef TMP_S4DW_MC_EN |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (ppre->di_chan2_buf_dup_p) |
| config_mcinfo_canvas_idx |
| (ppre->di_chan2_buf_dup_p, |
| cvss->pre_idx[canvases_idex][7]); |
| else |
| config_mcinfo_canvas_idx |
| (ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][7]); |
| |
| config_mcinfo_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][8]); |
| config_mcvec_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][9]); |
| } |
| #endif /* TMP_S4DW_MC_EN */ |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_mem_mif, |
| DI_MIF0_ID_MEM, |
| ppre->di_mem_buf_dup_p, |
| channel); |
| else |
| config_di_mif(&ppre->di_mem_mif, |
| ppre->di_mem_buf_dup_p, channel); |
| /* patch */ |
| if (ppre->di_wr_buf->flg_nv21 && |
| ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p != ppre->di_inp_buf) { |
| ppre->di_mem_mif.l_endian = ppre->di_nrwr_mif.l_endian; |
| ppre->di_mem_mif.cbcr_swap = ppre->di_nrwr_mif.cbcr_swap; |
| ppre->di_mem_mif.reg_swap = ppre->di_nrwr_mif.reg_swap; |
| } |
| if (!ppre->di_chan2_buf_dup_p) { |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_chan2_mif, |
| DI_MIF0_ID_CHAN2, |
| ppre->di_inp_buf, |
| channel); |
| else |
| config_di_mif(&ppre->di_chan2_mif, |
| ppre->di_inp_buf, channel); |
| |
| } else { |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_chan2_mif, |
| DI_MIF0_ID_CHAN2, |
| ppre->di_chan2_buf_dup_p, |
| channel); |
| else |
| config_di_mif(&ppre->di_chan2_mif, |
| ppre->di_chan2_buf_dup_p, channel); |
| } |
| if (ppre->prog_proc_type == 0) { |
| ppre->di_nrwr_mif.src_i = 1; |
| ppre->di_mtnwr_mif.src_i = 1; |
| } else { |
| ppre->di_nrwr_mif.src_i = 0; |
| ppre->di_mtnwr_mif.src_i = 0; |
| } |
| if (DIM_IS_IC_EF(SC2)) { |
| if (ppre->shrk_cfg.shrk_en) { |
| //dw_fill_outvf_pre(&ppre->vf_copy, ppre->di_wr_buf); |
| //ppre->vfm_cpy.private_data = ppre->di_wr_buf; |
| opl1()->wr_cfg_mif_dvfm(&ppre->di_nrwr_mif, |
| EDI_MIFSM_NR, |
| &ppre->dw_wr_dvfm, NULL); |
| } else { |
| opl1()->wr_cfg_mif(&ppre->di_nrwr_mif, |
| EDI_MIFSM_NR, |
| ppre->di_wr_buf, NULL); |
| } |
| } else { |
| config_di_wr_mif(&ppre->di_nrwr_mif, &ppre->di_mtnwr_mif, |
| ppre->di_wr_buf, channel); |
| } |
| |
| if (DIM_IS_IC_EF(SC2)) |
| config_di_mtnwr_mif(&ppre->di_mtnwr_mif, ppre->di_wr_buf); |
| |
| if (ppre->di_chan2_buf_dup_p) |
| config_di_cnt_mif(&ppre->di_contprd_mif, |
| ppre->di_chan2_buf_dup_p); |
| else |
| config_di_cnt_mif(&ppre->di_contprd_mif, |
| ppre->di_wr_buf); |
| |
| config_di_cnt_mif(&ppre->di_contwr_mif, ppre->di_wr_buf); |
| |
| #ifdef TMP_S4DW_MC_EN |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (ppre->di_chan2_buf_dup_p) |
| config_di_mcinford_mif(&ppre->di_mcinford_mif, |
| ppre->di_chan2_buf_dup_p); |
| else |
| config_di_mcinford_mif(&ppre->di_mcinford_mif, |
| ppre->di_wr_buf); |
| |
| config_di_pre_mc_mif(&ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, ppre->di_wr_buf); |
| } |
| #endif |
| if (ppre->di_chan2_buf_dup_p && |
| ((ppre->di_chan2_buf_dup_p->vframe->type & VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP)) |
| chan2_field_num = 0; |
| |
| if (ppre->shrk_cfg.shrk_en) { |
| pre_width = ppre->di_wr_buf->vframe->width; |
| pre_height = ppre->di_wr_buf->vframe->height; |
| } else { |
| pre_width = ppre->di_nrwr_mif.end_x + 1; |
| pre_height = ppre->di_nrwr_mif.end_y + 1; |
| } |
| if (IS_ERR_OR_NULL(ppre->di_inp_buf)) |
| return; |
| s4dw_hpre_check_pps(); // for add s4cp |
| |
| if (/*ppre->di_inp_buf && */ppre->di_inp_buf->vframe) |
| vf_i = ppre->di_inp_buf->vframe; |
| |
| if (dim_afds() && dim_afds()->pre_check) |
| dim_afds()->pre_check(ppre->di_wr_buf->vframe, pch); |
| if (ppre->di_wr_buf->is_4k) { |
| ppre->pre_top_cfg.b.is_inp_4k = 1; |
| ppre->pre_top_cfg.b.is_mem_4k = 0; |
| } |
| if (ppre->input_size_change_flag || dbg_change_each_vs()) { |
| if (dim_afds() && dim_afds()->rest_val) |
| dim_afds()->rest_val(); |
| cur_inp_field_type = |
| (ppre->di_inp_buf->vframe->type & VIDTYPE_TYPEMASK); |
| cur_inp_field_type = |
| ppre->cur_prog_flag ? VIDTYPE_PROGRESSIVE : cur_inp_field_type; |
| /*di_async_reset2();*/ |
| di_pre_size_change(pre_width, pre_height, |
| cur_inp_field_type, channel); |
| ppre->input_size_change_flag = false; |
| } |
| |
| if (DIM_IS_IC_EF(SC2)) { |
| sc2_pre_cfg = &get_hw_pre()->pre_top_cfg; |
| if (sc2_pre_cfg->d32 != ppre->pre_top_cfg.d32) { |
| sc2_pre_cfg->d32 = ppre->pre_top_cfg.d32; |
| dim_sc2_contr_pre(sc2_pre_cfg, NULL); |
| dim_sc2_4k_set(sc2_pre_cfg->b.mode_4k, NULL); |
| } |
| } |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| dim_nr_ds_hw_ctrl(false); |
| |
| #ifndef TMP_MASK_FOR_T7 |
| /*patch for SECAM signal format from vlsi-feijun for all IC*/ |
| get_ops_nr()->secam_cfr_adjust(ppre->di_inp_buf->vframe->sig_fmt, |
| ppre->di_inp_buf->vframe->type); |
| #endif |
| /* set interrupt mask for pre module. |
| * we need to only leave one mask open |
| * to prevent multiple entry for dim_irq |
| */ |
| |
| if (ppre->is_bypass_mem) |
| ppre->di_wr_buf->is_bypass_mem = 1; |
| else |
| ppre->di_wr_buf->is_bypass_mem = 0; |
| |
| /* for t5d vb netflix change afbc input timeout */ |
| if (DIM_IS_IC(T5DB)) { |
| t5d_cnt = cfgg(T5DB_P_NOTNR_THD); |
| if (t5d_cnt < 2) |
| t5d_cnt = 2; |
| if (ppre->field_count_for_cont < t5d_cnt && |
| ppre->cur_prog_flag) |
| ppre->is_bypass_mem |= 0x02; |
| else |
| ppre->is_bypass_mem &= ~0x02; |
| |
| if (ppre->is_bypass_mem) |
| ppre->di_wr_buf->is_bypass_mem = 1; |
| else |
| ppre->di_wr_buf->is_bypass_mem = 0; |
| dim_print("%s:is_bypass_mem[%d]\n", __func__, |
| ppre->di_wr_buf->is_bypass_mem); |
| if (ppre->field_count_for_cont < 1 && |
| IS_FIELD_I_SRC(ppre->cur_inp_type)) |
| ppre->is_disable_chan2 = 1; |
| else |
| ppre->is_disable_chan2 = 0; |
| //when p mode/first frame ,set 0 to reset the mc vec wr, |
| //second frame write back to 1,from vlsi feijun.fan for DMC bug |
| |
| if (ppre->field_count_for_cont < 1 && |
| IS_PROG(ppre->cur_inp_type)) { |
| dimh_set_slv_mcvec(0); |
| } else { |
| if (!dimh_get_slv_mcvec()) |
| dimh_set_slv_mcvec(1); |
| } |
| } |
| if (dim_config_crc_ic()) //add for crc @2k22-0102 |
| dimh_set_crc_init(ppre->field_count_for_cont); |
| |
| if (IS_ERR_OR_NULL(ppre->di_wr_buf)) |
| return; |
| if (dim_hdr_ops() && ppre->di_wr_buf->c.en_hdr) |
| dim_hdr_ops()->set(1); |
| //dbg: |
| if (cfgg(LINEAR)) |
| dim_dbg_buffer_flow(pch, |
| ppre->di_nrwr_mif.addr, |
| ppre->di_nrwr_mif.addr1, 10); |
| dim_dbg_vf_cvs(pch, ppre->di_wr_buf->vframe, 6); |
| |
| di_lock_irq();//di_lock_irqfiq_save(irq_flag2); |
| if (IS_IC_SUPPORT(DW)) { /* dw */ |
| opl1()->shrk_set(&ppre->shrk_cfg, &di_pre_regset); |
| } |
| dimh_enable_di_pre_aml(&ppre->di_inp_mif, |
| &ppre->di_mem_mif, |
| &ppre->di_chan2_mif, |
| &ppre->di_nrwr_mif, |
| &ppre->di_mtnwr_mif, |
| &ppre->di_contp2rd_mif, |
| &ppre->di_contprd_mif, |
| &ppre->di_contwr_mif, |
| ppre->madi_enable, |
| chan2_field_num, |
| ppre->vdin2nr | |
| (ppre->is_bypass_mem << 4), |
| ppre, channel); |
| |
| //no need for s4dw dcntr_set(); |
| |
| if (dim_afds()) { |
| if (ppre->di_mem_buf_dup_p && ppre->di_mem_buf_dup_p->vframe) |
| vf_mem = ppre->di_mem_buf_dup_p->vframe; |
| if (ppre->di_chan2_buf_dup_p && |
| ppre->di_chan2_buf_dup_p->vframe) |
| vf_chan2 = ppre->di_chan2_buf_dup_p->vframe; |
| //use di_pulldown transfer s4cp infor |
| vf_i->di_pulldown = 1; |
| dbg_copy("set:0x%px, pd %d\n", vf_i, vf_i->di_pulldown); |
| if (vf_mem && vf_mem != vf_i) |
| vf_mem->di_pulldown = 0; |
| if (vf_chan2 && vf_chan2 != vf_i) |
| vf_chan2->di_pulldown = 0; |
| |
| if (/*ppre->di_wr_buf && */ppre->di_wr_buf->vframe) |
| dim_afds()->en_pre_set(vf_i, |
| vf_mem, |
| vf_chan2, |
| ppre->di_wr_buf->vframe); |
| vf_i->di_pulldown = 0; |
| } |
| #ifdef TMP_S4DW_MC_EN |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (DIM_IS_IC_EF(T7)) |
| opl1()->pre_enable_mc(&ppre->di_mcinford_mif, |
| &ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, |
| ppre->mcdi_enable); |
| else if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| dimh_enable_mc_di_pre_g12(&ppre->di_mcinford_mif, |
| &ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, |
| ppre->mcdi_enable); |
| else |
| dimh_enable_mc_di_pre(&ppre->di_mcinford_mif, |
| &ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, |
| ppre->mcdi_enable); |
| } |
| #endif |
| |
| if (dim_config_crc_icl()) //add for crc @2k23-0403 |
| dimh_set_crc_init_update(ppre->field_count_for_cont); |
| dimh_nr_disable_set(true); |
| ppre->field_count_for_cont++; |
| |
| if (ppre->field_count_for_cont >= 5) |
| DIM_DI_WR_REG_BITS(DI_MTN_CTRL, 0, 30, 1); |
| |
| dimh_txl_patch_prog(ppre->cur_prog_flag, |
| ppre->field_count_for_cont, |
| /*dimp_get(edi_mp_mcpre_en)*/mc_en); |
| |
| /* must make sure follow part issue without interrupts, |
| * otherwise may cause watch dog reboot |
| */ |
| //di_lock_irqfiq_save(irq_flag2); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { |
| /* enable mc pre mif*/ |
| dimh_enable_di_pre_mif(true, /*dimp_get(edi_mp_mcpre_en)*/mc_en); |
| dim_pre_frame_reset_g12(ppre->madi_enable, |
| ppre->mcdi_enable); |
| } else { |
| dim_pre_frame_reset(); |
| /* enable mc pre mif*/ |
| dimh_enable_di_pre_mif(true, /*dimp_get(edi_mp_mcpre_en)*/mc_en); |
| } |
| /*dbg_set_DI_PRE_CTRL();*/ |
| atomic_set(&get_hw_pre()->flg_wait_int, 1); |
| ppre->pre_de_busy = 1; |
| ppre->irq_time[0] = cur_to_usecs(); |
| ppre->irq_time[1] = ppre->irq_time[0]; |
| di_unlock_irq();//di_unlock_irqfiq_restore(irq_flag2); |
| /*reinit pre busy flag*/ |
| pch->sum_pre++; |
| dim_dbg_pre_cnt(channel, "s3"); |
| // ppre->irq_time[0] = cur_to_msecs(); |
| // ppre->irq_time[1] = cur_to_msecs(); |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_SETE, channel, ppre->in_seq);/*dbg*/ |
| dim_tr_ops.pre_set(ppre->di_wr_buf->vframe->index_disp); |
| |
| ppre->pre_de_process_flag = 0; |
| } |
| |
| static void dbg_display_buffersize(struct di_ch_s *pch, struct vframe_s *vfm) |
| { |
| struct div2_mm_s *mm; |
| |
| if (!dip_cfg_afbc_dbg_display_buffer()) |
| return; |
| mm = dim_mm_get(pch->ch_id); |
| vfm->width = mm->cfg.di_w; |
| vfm->height = mm->cfg.di_h; |
| } |
| |
| static void s4dw_done_config(unsigned int channel, bool flg_timeout) |
| { |
| struct di_buf_s *post_wr_buf = NULL; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_ch_s *pch; |
| struct vframe_s *vfmt; |
| |
| dim_dbg_pre_cnt(channel, "d1"); |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_DONEB, channel, ppre->in_seq);/*dbg*/ |
| pch = get_chdata(channel); |
| dimh_nr_disable_set(false); |
| if (!ppre->di_wr_buf || !ppre->di_inp_buf) { |
| PR_ERR("%s:no key buffer? 0x%px,0x%px\n", |
| __func__, ppre->di_wr_buf, ppre->di_inp_buf); |
| return; |
| } |
| |
| if (flg_timeout) { |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_gl_sw(false); |
| else |
| hpre_gl_sw(false); |
| //for cp disable ppre->timeout_check = true; |
| } |
| if (ppre->di_wr_buf->field_count < 3) { |
| if (!ppre->di_wr_buf->field_count) |
| dbg_timer(channel, EDBG_TIMER_1_PREADY); |
| else if (ppre->di_wr_buf->field_count == 1) |
| dbg_timer(channel, EDBG_TIMER_2_PREADY); |
| else if (ppre->di_wr_buf->field_count == 2) |
| dbg_timer(channel, EDBG_TIMER_3_PREADY); |
| } |
| |
| dim_tr_ops.pre_ready(ppre->di_wr_buf->vframe->index_disp); |
| ppre->di_wr_buf->flg_nr = 1; |
| if (ppre->pre_throw_flag > 0) { |
| ppre->di_wr_buf->throw_flag = 1; |
| ppre->pre_throw_flag--; |
| } else { |
| ppre->di_wr_buf->throw_flag = 0; |
| } |
| |
| if (ppre->di_wr_buf->flg_afbce_set) { |
| ppre->di_wr_buf->flg_afbce_set = 0; |
| PR_ERR("%s:afbce?\n", __func__); |
| } |
| |
| /*dec vf keep*/ |
| if (ppre->di_inp_buf && |
| ppre->di_inp_buf->dec_vf_state & DI_BIT0) { |
| ppre->di_wr_buf->in_buf = ppre->di_inp_buf; |
| dim_print("dim:dec vf:l[%d]\n", |
| ppre->di_wr_buf->in_buf->vframe->index_disp); |
| } |
| //ppre->di_post_wr_buf not use |
| |
| post_wr_buf = ppre->di_wr_buf; |
| |
| post_wr_buf->vframe->di_pulldown = 0; |
| post_wr_buf->vframe->di_gmv = 0; |
| post_wr_buf->vframe->di_cm_cnt = 0; |
| |
| if (ppre->prog_proc_type == 0x10) { |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| /*recycle the progress throw buffer*/ |
| ppre->di_wr_buf->seq = ppre->pre_ready_seq++; |
| ppre->di_wr_buf->post_ref_count = 0; |
| |
| if (ppre->di_wr_buf->throw_flag) { |
| ppre->di_wr_buf->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| ppre->di_post_wr_buf = NULL; |
| ppre->di_wr_buf = NULL; |
| |
| } else if (ppre->di_wr_buf->is_bypass_mem) { |
| //di_que_in(channel, QUE_PRE_READY, |
| // ppre->di_wr_buf); |
| /* set flag */ |
| vfmt = ppre->di_wr_buf->vframe; |
| /* flag clear */ |
| vfmt->flag &= (~VFMT_FLG_CHG_MASK); |
| |
| if (!dip_itf_is_o_linear(pch)) |
| vfmt->flag &= (~VFRAME_FLAG_VIDEO_LINEAR); |
| vfmt->canvas0Addr = (u32)-1; |
| vfmt->canvas1Addr = (u32)-1; |
| #ifdef TMP_FOR_S4DW /*temp*/ |
| if (s4dw_test_ins()) { |
| vfmt->early_process_fun = dim_do_post_wr_fun; |
| vfmt->process_fun = NULL; |
| vfmt->mem_handle = NULL; |
| vfmt->type |= VIDTYPE_DI_PW; |
| |
| if (dip_itf_is_vfm(pch)) |
| vfmt->flag |= VFRAME_FLAG_DI_PW_VFM; |
| else if (dip_itf_is_ins_lbuf(pch)) |
| vfmt->flag |= VFRAME_FLAG_DI_PW_N_LOCAL; |
| else |
| vfmt->flag |= VFRAME_FLAG_DI_PW_N_EXT; |
| } |
| #endif |
| dbg_display_buffersize(pch, vfmt); |
| pch->itf.op_fill_ready(pch, ppre->di_wr_buf); |
| ppre->di_mem_buf_dup_p = NULL; |
| ppre->di_post_wr_buf = NULL; |
| ppre->di_wr_buf = NULL; |
| dim_print("mem bypass\n"); |
| } else { |
| /* clear mem ref */ |
| PR_ERR("not bypass mem?\n"); |
| } |
| |
| /******************************************/ |
| /* need check */ |
| if (ppre->source_change_flag) { |
| //ppre->di_wr_buf->new_format_flag = 1; |
| ppre->source_change_flag = 0; |
| } else { |
| //ppre->di_wr_buf->new_format_flag = 0; |
| } |
| } else { |
| PR_INF("%s: err2\n", __func__); |
| } |
| |
| if (!(ppre->di_inp_buf->dec_vf_state & DI_BIT0)) { |
| /*dec vf keep*/ |
| queue_in(channel, ppre->di_inp_buf, |
| QUEUE_RECYCLE); |
| ppre->di_inp_buf = NULL; |
| } |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_DONEE, channel, ppre->in_seq);/*dbg*/ |
| dim_dbg_pre_cnt(channel, "d2"); |
| } |
| |
| /**************************************************************/ |
| //s4dw pre setting table : |
| /* use do_table: */ |
| /* bypass or setting */ |
| static unsigned int s4dw_t_check(void *data) |
| { |
| struct di_hpre_s *pre = get_hw_pre(); |
| unsigned int ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); |
| struct di_ch_s *pch; |
| int ret_bypass; |
| |
| pch = get_chdata(pre->curr_ch); |
| /* @ary bypass flow*/ |
| ret_bypass = s4dw_pre_bypass(pch); |
| dbg_copy("%s:1:%d\n", "s4dw check", ret_bypass); |
| if (ret_bypass < 0) { /**/ |
| /* @ary no nin, to start */ |
| ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); |
| } else { |
| /* @ary pre config */ |
| ret_bypass = s4dw_pre_buf_config(pch); |
| dbg_copy("%s:2:%d\n", "s4dw check", ret_bypass); |
| if (!ret_bypass) { |
| /* pre set */ |
| s4dw_pre_set(pre->curr_ch); |
| pre->irq_nr = false; |
| di_tout_contr(EDI_TOUT_CONTR_EN, &pre->tout); |
| ret = K_DO_R_FINISH; |
| } else { |
| /* @ary bypass to start */ |
| ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); |
| } |
| } |
| |
| return ret; |
| } |
| |
| /************************************* |
| * return: |
| * false: don't wait. finish seting and go to start; |
| * true: wait |
| *************************************/ |
| static bool s4dw_wait_int_process(void) |
| { |
| struct di_hpre_s *pre = get_hw_pre(); |
| //tmp ulong flags = 0; |
| struct di_pre_stru_s *ppre; |
| bool ret = true; //wait |
| |
| if (pre->flg_int_done) { |
| /*have INT done flg*/ |
| |
| /*di_pre_wait_irq_set(false);*/ |
| /*finish to count timer*/ |
| di_tout_contr(EDI_TOUT_CONTR_FINISH, &pre->tout); |
| //tmp spin_lock_irqsave(&plist_lock, flags); |
| |
| s4dw_done_config(pre->curr_ch, false); |
| |
| pre->flg_int_done = 0; |
| |
| dpre_recyc(pre->curr_ch); |
| dpre_vdoing(pre->curr_ch); |
| |
| //tmp spin_unlock_irqrestore(&plist_lock, flags); |
| |
| ppre = get_pre_stru(pre->curr_ch); |
| |
| ret = false; |
| |
| } else { |
| /*check if timeout:*/ |
| if (di_tout_contr(EDI_TOUT_CONTR_CHECK, &pre->tout)) { |
| /* @ary timeout */ |
| if (!atomic_dec_and_test(&get_hw_pre()->flg_wait_int)) { |
| PR_WARN("%s:ch[%d]timeout\n", __func__, |
| pre->curr_ch); |
| di_tout_contr(EDI_TOUT_CONTR_EN, &pre->tout); |
| ret = true; |
| } else { |
| /*return K_DO_R_FINISH;*/ |
| /* real timeout */ |
| hpre_timeout_read(); |
| |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_gl_sw(false); |
| #ifdef TMP_S4DW_MC_EN |
| dimh_enable_di_pre_mif(false, dimp_get(edi_mp_mcpre_en)); |
| #else |
| dimh_enable_di_pre_mif(false, false); |
| #endif |
| pre->pres->pre_de_irq_timeout_count++; |
| |
| pre->pres->pre_de_busy = 0; |
| pre->pres->pre_de_clear_flag = 2; |
| |
| PR_WARN("ch[%d]cp %d timeout 0x%x(%d ms)%d\n", |
| pre->curr_ch, |
| pre->pres->field_count_for_cont, |
| RD(DI_INTR_CTRL), |
| (unsigned int)((cur_to_usecs() - |
| pre->pres->irq_time[0]) >> 10), |
| pre->irq_nr); |
| |
| /*******************************/ |
| s4dw_done_config(pre->curr_ch, true); |
| |
| dpre_recyc(pre->curr_ch); |
| dpre_vdoing(pre->curr_ch); |
| |
| ret = false; |
| } |
| } else { //wait |
| ret = true; |
| } |
| } |
| return ret; |
| } |
| |
| /* wait int or done or reset ? */ |
| static unsigned int s4dw_t_wait_int(void *data) |
| { |
| bool wait; |
| unsigned int ret = K_DO_R_NOT_FINISH; |
| |
| wait = s4dw_wait_int_process(); |
| if (wait) |
| ret = K_DO_R_NOT_FINISH; |
| else |
| ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); |
| |
| return ret; |
| } |
| |
| enum EDI_S4DW_MT { |
| EDI_S4DW_MT_CHECK = K_DO_TABLE_ID_START, |
| //EDI_DCT_MT_SET, |
| EDI_S4DW_MT_WAIT_INT, |
| }; |
| |
| //static |
| const struct do_table_ops_s s4dw_hw_process[4] = { |
| /*fix*/ |
| [K_DO_TABLE_ID_PAUSE] = { |
| .id = K_DO_TABLE_ID_PAUSE, |
| .mark = 0, |
| .con = NULL, |
| .do_op = NULL, |
| .do_stop_op = NULL, |
| .name = "pause", |
| }, |
| [K_DO_TABLE_ID_STOP] = { |
| .id = K_DO_TABLE_ID_STOP, |
| .mark = 0, |
| .con = NULL, |
| .do_op = NULL, |
| .do_stop_op = NULL, |
| .name = "stop", |
| }, |
| /******************/ |
| [K_DO_TABLE_ID_START] = { /*EDI_PRE_MT_CHECK*/ |
| .id = K_DO_TABLE_ID_START, |
| .mark = 0, |
| .con = NULL, |
| .do_op = s4dw_t_check, |
| .do_stop_op = NULL, |
| .name = "s4dw_check", |
| }, |
| [EDI_S4DW_MT_WAIT_INT] = { |
| .id = EDI_S4DW_MT_WAIT_INT, |
| .mark = 0, |
| .con = NULL, |
| .do_op = s4dw_t_wait_int, |
| .do_stop_op = NULL, |
| .name = "s4dw_wait_int", |
| } |
| }; |
| |
| /*s4dw pre setting table end*/ |
| /**************************************************************/ |
| |