| /* |
| * drivers/amlogic/media/di_multi_v3/di_prc.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/of_fdt.h> |
| |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include "deinterlace.h" |
| |
| #include "di_data_l.h" |
| #include "di_data.h" |
| #include "di_dbg.h" |
| #include "di_sys.h" |
| #include "di_vframe.h" |
| #include "di_que.h" |
| #include "di_task.h" |
| |
| #include "di_prc.h" |
| #include "di_pre.h" |
| #include "di_pre_hw.h" |
| #include "di_post.h" |
| #include "di_api.h" |
| |
| /************************************** |
| * |
| * cfg ctr top |
| * bool |
| **************************************/ |
| |
| const struct di_cfg_ctr_s div3_cfg_top_ctr[K_DI_CFG_NUB] = { |
| /*same order with enum eDI_DBG_CFG*/ |
| /* cfg for top */ |
| [EDI_CFG_BEGIN] = {"cfg top begin ", EDI_CFG_BEGIN, 0, |
| K_DI_CFG_T_FLG_NONE}, |
| [EDI_CFG_CH_NUB] = {"ch_nub", EDI_CFG_CH_NUB, 1, |
| K_DI_CFG_T_FLG_DTS}, |
| [EDI_CFG_mem_flg] = {"flag_cma", EDI_CFG_mem_flg, |
| eDI_MEM_M_cma, |
| K_DI_CFG_T_FLG_DTS}, |
| [EDI_CFG_first_bypass] = {"first_bypass", |
| EDI_CFG_first_bypass, |
| 0, |
| K_DI_CFG_T_FLG_DTS}, |
| [EDI_CFG_ref_2] = {"ref_2", |
| EDI_CFG_ref_2, 0, K_DI_CFG_T_FLG_NOTHING}, |
| [EDI_CFG_PMODE] = {"pmode:0:as p;1:as i;2:use 2 i buf", |
| EDI_CFG_PMODE, |
| 1, |
| K_DI_CFG_T_FLG_NOTHING}, |
| [EDI_CFG_KEEP_CLEAR_AUTO] = {"keep_buf clear auto", |
| EDI_CFG_KEEP_CLEAR_AUTO, |
| 1, |
| K_DI_CFG_T_FLG_NOTHING}, |
| [EDI_CFG_PRE_RST_OLD_FLOW] = {"pre_rst_old_flow", |
| EDI_CFG_PRE_RST_OLD_FLOW, |
| 0, |
| K_DI_CFG_T_FLG_NOTHING}, |
| |
| [EDI_CFG_TMODE_1] = {"tmode1", |
| EDI_CFG_TMODE_1, |
| 1, |
| K_DI_CFG_T_FLG_DTS}, |
| [EDI_CFG_TMODE_2] = {"tmode2", |
| EDI_CFG_TMODE_2, |
| 1, |
| K_DI_CFG_T_FLG_DTS}, |
| [EDI_CFG_TMODE_3] = {"tmode3", |
| EDI_CFG_TMODE_3, |
| 0, |
| K_DI_CFG_T_FLG_DTS}, |
| [EDI_CFG_DBG] = {"dbg only", |
| EDI_CFG_DBG, 0x00, K_DI_CFG_T_FLG_NOTHING}, |
| [EDI_CFG_END] = {"cfg top end ", EDI_CFG_END, 0, |
| K_DI_CFG_T_FLG_NONE}, |
| |
| }; |
| |
| char *div3_cfg_top_get_name(enum eDI_CFG_TOP_IDX idx) |
| { |
| return div3_cfg_top_ctr[idx].dts_name; |
| } |
| |
| void div3_cfg_top_get_info(unsigned int idx, char **name) |
| { |
| if (div3_cfg_top_ctr[idx].id != idx) |
| PR_ERR("%s:err:idx not map [%d->%d]\n", __func__, |
| idx, div3_cfg_top_ctr[idx].id); |
| |
| *name = div3_cfg_top_ctr[idx].dts_name; |
| } |
| |
| bool div3_cfg_top_check(unsigned int idx) |
| { |
| unsigned int tsize; |
| |
| tsize = ARRAY_SIZE(div3_cfg_top_ctr); |
| if (idx >= tsize) { |
| PR_ERR("%s:err:overflow:%d->%d\n", |
| __func__, idx, tsize); |
| return false; |
| } |
| if (div3_cfg_top_ctr[idx].flg & K_DI_CFG_T_FLG_NONE) |
| return false; |
| if (idx != div3_cfg_top_ctr[idx].id) { |
| PR_ERR("%s:%s:err:not map:%d->%d\n", |
| __func__, |
| div3_cfg_top_ctr[idx].dts_name, |
| idx, |
| div3_cfg_top_ctr[idx].id); |
| return false; |
| } |
| #if 0 |
| pr_info("\t%-15s=%d\n", div3_cfg_top_ctr[idx].name, |
| div3_cfg_top_ctr[idx].default_val); |
| #endif |
| return true; |
| } |
| |
| void div3_cfg_top_init_val(void) |
| { |
| int i; |
| union di_cfg_tdata_u *pd; |
| const struct di_cfg_ctr_s *pt; |
| |
| PR_INF("%s:\n", __func__); |
| for (i = EDI_CFG_BEGIN; i < EDI_CFG_END; i++) { |
| if (!div3_cfg_top_check(i)) |
| continue; |
| pd = &get_datal()->cfg_en[i]; |
| pt = &div3_cfg_top_ctr[i]; |
| |
| /*di_cfg_top_set(i, di_cfg_top_ctr[i].default_val);*/ |
| pd->d32 = 0;/*clear*/ |
| pd->b.val_df = pt->default_val; |
| pd->b.val_c = pd->b.val_df; |
| } |
| PR_INF("%s:finish\n", __func__); |
| } |
| |
| /*after init*/ |
| void div3_cfg_top_dts(void) |
| { |
| struct platform_device *pdev = getv3_dim_de_devp()->pdev; |
| int i; |
| union di_cfg_tdata_u *pd; |
| const struct di_cfg_ctr_s *pt; |
| int ret; |
| unsigned int uval; |
| |
| if (!pdev) { |
| PR_ERR("%s:no pdev\n", __func__); |
| return; |
| } |
| PR_INF("%s\n", __func__); |
| |
| for (i = EDI_CFG_BEGIN; i < EDI_CFG_END; i++) { |
| if (!div3_cfg_top_check(i)) |
| continue; |
| if (!(div3_cfg_top_ctr[i].flg & K_DI_CFG_T_FLG_DTS)) |
| continue; |
| |
| pd = &get_datal()->cfg_en[i]; |
| pt = &div3_cfg_top_ctr[i]; |
| pd->b.dts_en = 1; |
| |
| ret = of_property_read_u32(pdev->dev.of_node, |
| pt->dts_name, |
| &uval); |
| if (ret) |
| continue; |
| PR_INF("\t%s:%d\n", pt->dts_name, uval); |
| |
| pd->b.dts_have = 1; |
| pd->b.val_dts = uval; |
| pd->b.val_c = pd->b.val_dts; |
| } |
| PR_INF("%s end\n", __func__); |
| } |
| |
| /*item: one /all; include table/val*/ |
| /*val: one /all; only val*/ |
| static void di_cfgt_show_item_one(struct seq_file *s, unsigned int index) |
| { |
| union di_cfg_tdata_u *pd; |
| const struct di_cfg_ctr_s *pt; |
| |
| if (!div3_cfg_top_check(index)) |
| return; |
| |
| pd = &get_datal()->cfg_en[index]; |
| pt = &div3_cfg_top_ctr[index]; |
| |
| seq_printf(s, "id:%2d:%-10s\n", index, pt->dts_name); |
| /*tab*/ |
| seq_printf(s, "\t%-5s:0x%2x[%d]\n", |
| "tdf", pt->default_val, pt->default_val); |
| seq_printf(s, "\t%-5s:%d\n", |
| "tdts", pt->flg & K_DI_CFG_T_FLG_DTS); |
| /*val*/ |
| seq_printf(s, "\t%-5s:0x%-4x\n", "d32", pd->d32); |
| seq_printf(s, "\t%-5s:0x%2x[%d]\n", |
| "vdf", pd->b.val_df, pd->b.val_df); |
| seq_printf(s, "\t%-5s:0x%2x[%d]\n", |
| "vdts", pd->b.val_dts, pd->b.val_dts); |
| seq_printf(s, "\t%-5s:0x%2x[%d]\n", |
| "vdbg", pd->b.val_dbg, pd->b.val_dbg); |
| seq_printf(s, "\t%-5s:0x%2x[%d]\n", "vc", pd->b.val_c, pd->b.val_c); |
| seq_printf(s, "\t%-5s:%d\n", "endts", pd->b.dts_en); |
| seq_printf(s, "\t%-5s:%d\n", "hdts", pd->b.dts_have); |
| seq_printf(s, "\t%-5s:%d\n", "hdbg", pd->b.dbg_have); |
| } |
| |
| void div3_cfgt_show_item_sel(struct seq_file *s) |
| { |
| int i = get_datal()->cfg_sel; |
| |
| di_cfgt_show_item_one(s, i); |
| } |
| |
| void div3_cfgt_set_sel(unsigned int dbg_mode, unsigned int id) |
| { |
| if (!div3_cfg_top_check(id)) { |
| PR_ERR("%s:%d is overflow\n", __func__, id); |
| return; |
| } |
| |
| get_datal()->cfg_sel = id; |
| get_datal()->cfg_dbg_mode = dbg_mode; |
| } |
| |
| void div3_cfgt_show_item_all(struct seq_file *s) |
| { |
| int i; |
| |
| for (i = EDI_CFG_BEGIN; i < EDI_CFG_END; i++) |
| di_cfgt_show_item_one(s, i); |
| } |
| |
| static void di_cfgt_show_val_one(struct seq_file *s, unsigned int index) |
| { |
| union di_cfg_tdata_u *pd; |
| const struct di_cfg_ctr_s *pt; |
| |
| if (!div3_cfg_top_check(index)) |
| return; |
| |
| pd = &get_datal()->cfg_en[index]; |
| pt = &div3_cfg_top_ctr[index]; |
| |
| seq_printf(s, "id:%2d:%-10s\n", index, pt->dts_name); |
| |
| seq_printf(s, "\t%-5s:0x%-4x\n", "d32", pd->d32); |
| seq_printf(s, "\t%-5s:0x%2x[%d]\n", "vc", pd->b.val_c, pd->b.val_c); |
| } |
| |
| void div3_cfgt_show_val_sel(struct seq_file *s) |
| { |
| unsigned int i = get_datal()->cfg_sel; |
| |
| di_cfgt_show_val_one(s, i); |
| } |
| |
| void div3_cfgt_show_val_all(struct seq_file *s) |
| { |
| int i; |
| |
| for (i = EDI_CFG_BEGIN; i < EDI_CFG_END; i++) |
| di_cfgt_show_val_one(s, i); |
| } |
| |
| unsigned int div3_cfg_top_get(enum eDI_CFG_TOP_IDX id) |
| { |
| union di_cfg_tdata_u *pd; |
| |
| pd = &get_datal()->cfg_en[id]; |
| return pd->b.val_c; |
| } |
| |
| void div3_cfg_top_set(enum eDI_CFG_TOP_IDX id, unsigned int val) |
| { |
| union di_cfg_tdata_u *pd; |
| |
| pd = &get_datal()->cfg_en[id]; |
| pd->b.val_dbg = val; |
| pd->b.dbg_have = 1; |
| pd->b.val_c = val; |
| } |
| |
| /************************************** |
| * |
| * cfg ctr x |
| * bool |
| **************************************/ |
| |
| const struct di_cfgx_ctr_s div3_cfgx_ctr[K_DI_CFGX_NUB] = { |
| /*same order with enum eDI_DBG_CFG*/ |
| |
| /* cfg channel x*/ |
| [eDI_CFGX_BEGIN] = {"cfg x begin ", eDI_CFGX_BEGIN, 0}, |
| /* bypass_all */ |
| [eDI_CFGX_BYPASS_ALL] = {"bypass_all", eDI_CFGX_BYPASS_ALL, 0}, |
| [EDI_CFGX_HOLD_VIDEO] = {"hold_video", EDI_CFGX_HOLD_VIDEO, 0}, |
| [eDI_CFGX_END] = {"cfg x end ", eDI_CFGX_END, 0}, |
| |
| /* debug cfg x */ |
| [eDI_DBG_CFGX_BEGIN] = {"cfg dbg begin ", eDI_DBG_CFGX_BEGIN, 0}, |
| [eDI_DBG_CFGX_IDX_VFM_IN] = {"vfm_in", eDI_DBG_CFGX_IDX_VFM_IN, 0}, |
| [eDI_DBG_CFGX_IDX_VFM_OT] = {"vfm_out", eDI_DBG_CFGX_IDX_VFM_OT, 1}, |
| [eDI_DBG_CFGX_END] = {"cfg dbg end", eDI_DBG_CFGX_END, 0}, |
| }; |
| |
| char *div3_cfgx_get_name(enum eDI_CFGX_IDX idx) |
| { |
| return div3_cfgx_ctr[idx].name; |
| } |
| |
| void div3_cfgx_get_info(enum eDI_CFGX_IDX idx, char **name) |
| { |
| if (div3_cfgx_ctr[idx].id != idx) |
| PR_ERR("%s:err:idx not map [%d->%d]\n", __func__, |
| idx, div3_cfgx_ctr[idx].id); |
| |
| *name = div3_cfgx_ctr[idx].name; |
| } |
| |
| bool div3_cfgx_check(unsigned int idx) |
| { |
| unsigned int tsize; |
| |
| tsize = ARRAY_SIZE(div3_cfgx_ctr); |
| if (idx >= tsize) { |
| PR_ERR("%s:err:overflow:%d->%d\n", |
| __func__, idx, tsize); |
| return false; |
| } |
| if (idx != div3_cfgx_ctr[idx].id) { |
| PR_ERR("%s:err:not map:%d->%d\n", |
| __func__, idx, div3_cfgx_ctr[idx].id); |
| return false; |
| } |
| PR_INF("\t%-15s=%d\n", div3_cfgx_ctr[idx].name, |
| div3_cfgx_ctr[idx].default_val); |
| return true; |
| } |
| |
| void div3_cfgx_init_val(void) |
| { |
| int i, ch; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| for (i = eDI_CFGX_BEGIN; i < eDI_DBG_CFGX_END; i++) |
| div3_cfgx_set(ch, i, div3_cfgx_ctr[i].default_val); |
| } |
| } |
| |
| bool div3_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx) |
| { |
| return get_datal()->ch_data[ch].cfgx_en[idx]; |
| } |
| |
| void div3_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en) |
| { |
| get_datal()->ch_data[ch].cfgx_en[idx] = en; |
| } |
| |
| /************************************** |
| * |
| * module para top |
| * int |
| **************************************/ |
| |
| const struct di_mp_uit_s div3_mp_ui_top[] = { |
| /*same order with enum eDI_MP_UI*/ |
| /* for top */ |
| [eDI_MP_UI_T_BEGIN] = {"module para top begin ", |
| eDI_MP_UI_T_BEGIN, 0}, |
| /**************************************/ |
| [eDI_MP_SUB_DI_B] = {"di begin ", |
| eDI_MP_SUB_DI_B, 0}, |
| [eDI_MP_force_prog] = {"bool:force_prog:1", |
| eDI_MP_force_prog, 1}, |
| [edi_mp_combing_fix_en] = {"bool:combing_fix_en,def:1", |
| edi_mp_combing_fix_en, 1}, |
| [eDI_MP_cur_lev] = {"int cur_lev,def:2", |
| eDI_MP_cur_lev, 2}, |
| [eDI_MP_pps_dstw] = {"pps_dstw:int", |
| eDI_MP_pps_dstw, 0}, |
| [eDI_MP_pps_dsth] = {"pps_dsth:int", |
| eDI_MP_pps_dsth, 0}, |
| [eDI_MP_pps_en] = {"pps_en:bool", |
| eDI_MP_pps_en, 0}, |
| [eDI_MP_pps_position] = {"pps_position:uint:def:1", |
| eDI_MP_pps_position, 1}, |
| [eDI_MP_pre_enable_mask] = {"pre_enable_mask:bit0:ma;bit1:mc:def:3", |
| eDI_MP_pre_enable_mask, 3}, |
| [eDI_MP_post_refresh] = {"post_refresh:bool", |
| eDI_MP_post_refresh, 0}, |
| [eDI_MP_nrds_en] = {"nrds_en:bool", |
| eDI_MP_nrds_en, 0}, |
| [eDI_MP_bypass_3d] = {"bypass_3d:int:def:1", |
| eDI_MP_bypass_3d, 1}, |
| [eDI_MP_bypass_trick_mode] = {"bypass_trick_mode:int:def:1", |
| eDI_MP_bypass_trick_mode, 1}, |
| [eDI_MP_invert_top_bot] = {"invert_top_bot:int", |
| eDI_MP_invert_top_bot, 0}, |
| [eDI_MP_skip_top_bot] = {"skip_top_bot:int:", |
| /*1or2: may affect atv when bypass di*/ |
| eDI_MP_skip_top_bot, 0}, |
| [eDI_MP_force_width] = {"force_width:int", |
| eDI_MP_force_width, 0}, |
| [eDI_MP_force_height] = {"force_height:int", |
| eDI_MP_force_height, 0}, |
| [eDI_MP_prog_proc_config] = {"prog_proc_config:int:def:0x23", |
| /* prog_proc_config, |
| * bit[2:1]: when two field buffers are used, |
| * 0 use vpp for blending , |
| * 1 use post_di module for blending |
| * 2 debug mode, bob with top field |
| * 3 debug mode, bot with bot field |
| * bit[0]: |
| * 0 "prog vdin" use two field buffers, |
| * 1 "prog vdin" use single frame buffer |
| * bit[4]: |
| * 0 "prog frame from decoder/vdin" use two field buffers, |
| * 1 use single frame buffer |
| * bit[5]: |
| * when two field buffers are used for decoder (bit[4] is 0): |
| * 1,handle prog frame as two interlace frames |
| * bit[6]:(bit[4] is 0,bit[5] is 0,use_2_interlace_buff is 0): 0, |
| * process progress frame as field,blend by post; |
| * 1, process progress frame as field,process by normal di |
| */ |
| eDI_MP_prog_proc_config, ((1 << 5) | (1 << 1) | 1)}, |
| [eDI_MP_start_frame_drop_count] = {"start_frame_drop_count:int:2", |
| eDI_MP_start_frame_drop_count, 0}, /*from 2 to 0*/ |
| [eDI_MP_same_field_top_count] = {"same_field_top_count:long?", |
| eDI_MP_same_field_top_count, 0}, |
| [eDI_MP_same_field_bot_count] = {"same_field_bot_count:long?", |
| eDI_MP_same_field_bot_count, 0}, |
| [eDI_MP_vpp_3d_mode] = {"vpp_3d_mode:int", |
| eDI_MP_vpp_3d_mode, 0}, |
| [eDI_MP_force_recovery_count] = {"force_recovery_count:uint", |
| eDI_MP_force_recovery_count, 0}, |
| [eDI_MP_pre_process_time] = {"pre_process_time:int", |
| eDI_MP_pre_process_time, 0}, |
| [eDI_MP_bypass_post] = {"bypass_post:int", |
| eDI_MP_bypass_post, 0}, |
| [eDI_MP_post_wr_en] = {"post_wr_en:bool:1", |
| eDI_MP_post_wr_en, 1}, |
| [eDI_MP_post_wr_support] = {"post_wr_support:uint", |
| eDI_MP_post_wr_support, 0}, |
| [eDI_MP_bypass_post_state] = {"bypass_post_state:int", |
| /* 0, use di_wr_buf still; |
| * 1, call dim_pre_de_done_buf_clear to clear di_wr_buf; |
| * 2, do nothing |
| */ |
| eDI_MP_bypass_post_state, 0}, |
| [eDI_MP_use_2_interlace_buff] = {"use_2_interlace_buff:int", |
| eDI_MP_use_2_interlace_buff, 0}, |
| [eDI_MP_debug_blend_mode] = {"debug_blend_mode:int:-1", |
| eDI_MP_debug_blend_mode, -1}, |
| [eDI_MP_nr10bit_support] = {"nr10bit_support:uint", |
| /* 0: not support nr10bit, 1: support nr10bit */ |
| eDI_MP_nr10bit_support, 0}, |
| [eDI_MP_di_stop_reg_flag] = {"di_stop_reg_flag:uint", |
| eDI_MP_di_stop_reg_flag, 0}, |
| [eDI_MP_mcpre_en] = {"mcpre_en:bool:true", |
| eDI_MP_mcpre_en, 1}, |
| [eDI_MP_check_start_drop_prog] = {"check_start_drop_prog:bool", |
| eDI_MP_check_start_drop_prog, 0}, |
| [eDI_MP_overturn] = {"overturn:bool:?", |
| eDI_MP_overturn, 0}, |
| [eDI_MP_full_422_pack] = {"full_422_pack:bool", |
| eDI_MP_full_422_pack, 0}, |
| [eDI_MP_cma_print] = {"cma_print:bool:1", |
| eDI_MP_cma_print, 0}, |
| [eDI_MP_pulldown_enable] = {"pulldown_enable:bool:1", |
| eDI_MP_pulldown_enable, 1}, |
| [eDI_MP_di_force_bit_mode] = {"di_force_bit_mode:uint:10", |
| eDI_MP_di_force_bit_mode, 10}, |
| [eDI_MP_calc_mcinfo_en] = {"calc_mcinfo_en:bool:1", |
| eDI_MP_calc_mcinfo_en, 1}, |
| [eDI_MP_colcfd_thr] = {"colcfd_thr:uint:128", |
| eDI_MP_colcfd_thr, 128}, |
| [eDI_MP_post_blend] = {"post_blend:uint", |
| eDI_MP_post_blend, 0}, |
| [eDI_MP_post_ei] = {"post_ei:uint", |
| eDI_MP_post_ei, 0}, |
| [eDI_MP_post_cnt] = {"post_cnt:uint", |
| eDI_MP_post_cnt, 0}, |
| [eDI_MP_di_log_flag] = {"di_log_flag:uint", |
| eDI_MP_di_log_flag, 0}, |
| [eDI_MP_di_debug_flag] = {"di_debug_flag:uint", |
| eDI_MP_di_debug_flag, 0}, |
| [eDI_MP_buf_state_log_threshold] = {"buf_state_log_threshold:unit:16", |
| eDI_MP_buf_state_log_threshold, 16}, |
| [eDI_MP_di_vscale_skip_enable] = {"di_vscale_skip_enable:int", |
| /* |
| * bit[2]: enable bypass all when skip |
| * bit[1:0]: enable bypass post when skip |
| */ |
| eDI_MP_di_vscale_skip_enable, 0}, |
| [eDI_MP_di_vscale_skip_count] = {"di_vscale_skip_count:int", |
| eDI_MP_di_vscale_skip_count, 0}, |
| [eDI_MP_di_vscale_skip_count_real] = {"di_vscale_skip_count_real:int", |
| eDI_MP_di_vscale_skip_count_real, 0}, |
| [eDI_MP_det3d_en] = {"det3d_en:bool", |
| eDI_MP_det3d_en, 0}, |
| [eDI_MP_post_hold_line] = {"post_hold_line:int:8", |
| eDI_MP_post_hold_line, 8}, |
| [eDI_MP_post_urgent] = {"post_urgent:int:1", |
| eDI_MP_post_urgent, 1}, |
| [eDI_MP_di_printk_flag] = {"di_printk_flag:uint", |
| eDI_MP_di_printk_flag, 0}, |
| [eDI_MP_force_recovery] = {"force_recovery:uint:1", |
| eDI_MP_force_recovery, 1}, |
| #if 0 |
| [eDI_MP_debug_blend_mode] = {"debug_blend_mode:int:-1", |
| eDI_MP_debug_blend_mode, -1}, |
| #endif |
| [eDI_MP_di_dbg_mask] = {"di_dbg_mask:uint:0x02", |
| eDI_MP_di_dbg_mask, 2}, |
| [eDI_MP_nr_done_check_cnt] = {"nr_done_check_cnt:uint:5", |
| eDI_MP_nr_done_check_cnt, 5}, |
| [eDI_MP_pre_hsc_down_en] = {"pre_hsc_down_en:bool:0", |
| eDI_MP_pre_hsc_down_en, 0}, |
| [eDI_MP_pre_hsc_down_width] = {"pre_hsc_down_width:int:480", |
| eDI_MP_pre_hsc_down_width, 480}, |
| [eDI_MP_show_nrwr] = {"show_nrwr:bool:0", |
| eDI_MP_show_nrwr, 0}, |
| |
| /******deinterlace_hw.c**********/ |
| [eDI_MP_pq_load_dbg] = {"pq_load_dbg:uint", |
| eDI_MP_pq_load_dbg, 0}, |
| [eDI_MP_lmv_lock_win_en] = {"lmv_lock_win_en:bool", |
| eDI_MP_lmv_lock_win_en, 0}, |
| [eDI_MP_lmv_dist] = {"lmv_dist:short:5", |
| eDI_MP_lmv_dist, 5}, |
| [eDI_MP_pr_mcinfo_cnt] = {"pr_mcinfo_cnt:ushort", |
| eDI_MP_pr_mcinfo_cnt, 0}, |
| [eDI_MP_offset_lmv] = {"offset_lmv:short:100", |
| eDI_MP_offset_lmv, 100}, |
| [eDI_MP_post_ctrl] = {"post_ctrl:uint", |
| eDI_MP_post_ctrl, 0}, |
| [eDI_MP_if2_disable] = {"if2_disable:bool", |
| eDI_MP_if2_disable, 0}, |
| [eDI_MP_pre_flag] = {"pre_flag:ushort:2", |
| eDI_MP_pre_flag, 2}, |
| [eDI_MP_pre_mif_gate] = {"pre_mif_gate:bool", |
| eDI_MP_pre_mif_gate, 0}, |
| [eDI_MP_pre_urgent] = {"pre_urgent:ushort", |
| eDI_MP_pre_urgent, 0}, |
| [eDI_MP_pre_hold_line] = {"pre_hold_line:ushort:10", |
| eDI_MP_pre_hold_line, 10}, |
| [eDI_MP_pre_ctrl] = {"pre_ctrl:uint", |
| eDI_MP_pre_ctrl, 0}, |
| [eDI_MP_line_num_post_frst] = {"line_num_post_frst:ushort:5", |
| eDI_MP_line_num_post_frst, 5}, |
| [eDI_MP_line_num_pre_frst] = {"line_num_pre_frst:ushort:5", |
| eDI_MP_line_num_pre_frst, 5}, |
| [eDI_MP_pd22_flg_calc_en] = {"pd22_flg_calc_en:bool:true", |
| eDI_MP_pd22_flg_calc_en, 1}, |
| [eDI_MP_mcen_mode] = {"mcen_mode:ushort:1", |
| eDI_MP_mcen_mode, 1}, |
| [eDI_MP_mcuv_en] = {"mcuv_en:ushort:1", |
| eDI_MP_mcuv_en, 1}, |
| [eDI_MP_mcdebug_mode] = {"mcdebug_mode:ushort", |
| eDI_MP_mcdebug_mode, 0}, |
| [eDI_MP_pldn_ctrl_rflsh] = {"pldn_ctrl_rflsh:uint:1", |
| eDI_MP_pldn_ctrl_rflsh, 1}, |
| [eDI_MP_4k_test] = {"4_k_input:uint:1", |
| eDI_MP_4k_test, 0}, |
| |
| [eDI_MP_SUB_DI_E] = {"di end-------", |
| eDI_MP_SUB_DI_E, 0}, |
| /**************************************/ |
| [eDI_MP_SUB_NR_B] = {"nr begin", |
| eDI_MP_SUB_NR_B, 0}, |
| [EDI_MP_SUB_DELAY] = {"delay:bool:true", |
| EDI_MP_SUB_DELAY, 0}, |
| [EDI_MP_SUB_DBG_MODE] = {"delay_mode:uint:0", |
| EDI_MP_SUB_DBG_MODE, 0}, |
| [eDI_MP_cue_en] = {"cue_en:bool:true", |
| eDI_MP_cue_en, 1}, |
| [eDI_MP_invert_cue_phase] = {"invert_cue_phase:bool", |
| eDI_MP_invert_cue_phase, 0}, |
| [eDI_MP_cue_pr_cnt] = {"cue_pr_cnt:uint", |
| eDI_MP_cue_pr_cnt, 0}, |
| [eDI_MP_cue_glb_mot_check_en] = {"cue_glb_mot_check_en:bool:true", |
| eDI_MP_cue_glb_mot_check_en, 1}, |
| [eDI_MP_glb_fieldck_en] = {"glb_fieldck_en:bool:true", |
| eDI_MP_glb_fieldck_en, 1}, |
| [eDI_MP_dnr_pr] = {"dnr_pr:bool", |
| eDI_MP_dnr_pr, 0}, |
| [eDI_MP_dnr_dm_en] = {"dnr_dm_en:bool", |
| eDI_MP_dnr_dm_en, 0}, |
| [eDI_MP_SUB_NR_E] = {"nr end-------", |
| eDI_MP_SUB_NR_E, 0}, |
| /**************************************/ |
| [eDI_MP_SUB_PD_B] = {"pd begin", |
| eDI_MP_SUB_PD_B, 0}, |
| [eDI_MP_flm22_ratio] = {"flm22_ratio:uint:200", |
| eDI_MP_flm22_ratio, 200}, |
| [eDI_MP_pldn_cmb0] = {"pldn_cmb0:uint:1", |
| eDI_MP_pldn_cmb0, 1}, |
| [eDI_MP_pldn_cmb1] = {"pldn_cmb1:uint", |
| eDI_MP_pldn_cmb1, 0}, |
| [eDI_MP_flm22_sure_num] = {"flm22_sure_num:uint:100", |
| eDI_MP_flm22_sure_num, 100}, |
| [eDI_MP_flm22_glbpxlnum_rat] = {"flm22_glbpxlnum_rat:uint:4", |
| eDI_MP_flm22_glbpxlnum_rat, 4}, |
| [eDI_MP_flag_di_weave] = {"flag_di_weave:int:1", |
| eDI_MP_flag_di_weave, 1}, |
| [eDI_MP_flm22_glbpxl_maxrow] = {"flm22_glbpxl_maxrow:uint:16", |
| eDI_MP_flm22_glbpxl_maxrow, 16}, |
| [eDI_MP_flm22_glbpxl_minrow] = {"flm22_glbpxl_minrow:uint:3", |
| eDI_MP_flm22_glbpxl_minrow, 3}, |
| [eDI_MP_cmb_3point_rnum] = {"cmb_3point_rnum:uint", |
| eDI_MP_cmb_3point_rnum, 0}, |
| [eDI_MP_cmb_3point_rrat] = {"cmb_3point_rrat:unit:32", |
| eDI_MP_cmb_3point_rrat, 32}, |
| /********************************/ |
| [eDI_MP_pr_pd] = {"pr_pd:uint", |
| eDI_MP_pr_pd, 0}, |
| [eDI_MP_prt_flg] = {"prt_flg:bool", |
| eDI_MP_prt_flg, 0}, |
| [eDI_MP_flmxx_maybe_num] = {"flmxx_maybe_num:uint:15", |
| /* if flmxx level > flmxx_maybe_num */ |
| /* mabye flmxx: when 2-2 3-2 not detected */ |
| eDI_MP_flmxx_maybe_num, 15}, |
| [eDI_MP_flm32_mim_frms] = {"flm32_mim_frms:int:6", |
| eDI_MP_flm32_mim_frms, 6}, |
| [eDI_MP_flm22_dif01a_flag] = {"flm22_dif01a_flag:int:1", |
| eDI_MP_flm22_dif01a_flag, 1}, |
| [eDI_MP_flm22_mim_frms] = {"flm22_mim_frms:int:60", |
| eDI_MP_flm22_mim_frms, 60}, |
| [eDI_MP_flm22_mim_smfrms] = {"flm22_mim_smfrms:int:40", |
| eDI_MP_flm22_mim_smfrms, 40}, |
| [eDI_MP_flm32_f2fdif_min0] = {"flm32_f2fdif_min0:int:11", |
| eDI_MP_flm32_f2fdif_min0, 11}, |
| [eDI_MP_flm32_f2fdif_min1] = {"flm32_f2fdif_min1:int:11", |
| eDI_MP_flm32_f2fdif_min1, 11}, |
| [eDI_MP_flm32_chk1_rtn] = {"flm32_chk1_rtn:int:25", |
| eDI_MP_flm32_chk1_rtn, 25}, |
| [eDI_MP_flm32_ck13_rtn] = {"flm32_ck13_rtn:int:8", |
| eDI_MP_flm32_ck13_rtn, 8}, |
| [eDI_MP_flm32_chk2_rtn] = {"flm32_chk2_rtn:int:16", |
| eDI_MP_flm32_chk2_rtn, 16}, |
| [eDI_MP_flm32_chk3_rtn] = {"flm32_chk3_rtn:int:16", |
| eDI_MP_flm32_chk3_rtn, 16}, |
| [eDI_MP_flm32_dif02_ratio] = {"flm32_dif02_ratio:int:8", |
| eDI_MP_flm32_dif02_ratio, 8}, |
| [eDI_MP_flm22_chk20_sml] = {"flm22_chk20_sml:int:6", |
| eDI_MP_flm22_chk20_sml, 6}, |
| [eDI_MP_flm22_chk21_sml] = {"flm22_chk21_sml:int:6", |
| eDI_MP_flm22_chk21_sml, 6}, |
| [eDI_MP_flm22_chk21_sm2] = {"flm22_chk21_sm2:int:10", |
| eDI_MP_flm22_chk21_sm2, 10}, |
| [eDI_MP_flm22_lavg_sft] = {"flm22_lavg_sft:int:4", |
| eDI_MP_flm22_lavg_sft, 4}, |
| [eDI_MP_flm22_lavg_lg] = {"flm22_lavg_lg:int:24", |
| eDI_MP_flm22_lavg_lg, 24}, |
| [eDI_MP_flm22_stl_sft] = {"flm22_stl_sft:int:7", |
| eDI_MP_flm22_stl_sft, 7}, |
| [eDI_MP_flm22_chk5_avg] = {"flm22_chk5_avg:int:50", |
| eDI_MP_flm22_chk5_avg, 50}, |
| [eDI_MP_flm22_chk6_max] = {"flm22_chk6_max:int:20", |
| eDI_MP_flm22_chk6_max, 20}, |
| [eDI_MP_flm22_anti_chk1] = {"flm22_anti_chk1:int:61", |
| eDI_MP_flm22_anti_chk1, 61}, |
| [eDI_MP_flm22_anti_chk3] = {"flm22_anti_chk3:int:140", |
| eDI_MP_flm22_anti_chk3, 140}, |
| [eDI_MP_flm22_anti_chk4] = {"flm22_anti_chk4:int:128", |
| eDI_MP_flm22_anti_chk4, 128}, |
| [eDI_MP_flm22_anti_ck140] = {"flm22_anti_ck140:int:32", |
| eDI_MP_flm22_anti_ck140, 32}, |
| [eDI_MP_flm22_anti_ck141] = {"flm22_anti_ck141:int:80", |
| eDI_MP_flm22_anti_ck141, 80}, |
| [eDI_MP_flm22_frmdif_max] = {"flm22_frmdif_max:int:50", |
| eDI_MP_flm22_frmdif_max, 50}, |
| [eDI_MP_flm22_flddif_max] = {"flm22_flddif_max:int:100", |
| eDI_MP_flm22_flddif_max, 100}, |
| [eDI_MP_flm22_minus_cntmax] = {"flm22_minus_cntmax:int:2", |
| eDI_MP_flm22_minus_cntmax, 2}, |
| [eDI_MP_flagdif01chk] = {"flagdif01chk:int:1", |
| eDI_MP_flagdif01chk, 1}, |
| [eDI_MP_dif01_ratio] = {"dif01_ratio:int:10", |
| eDI_MP_dif01_ratio, 10}, |
| /*************vof_soft_top**************/ |
| [eDI_MP_cmb32_blw_wnd] = {"cmb32_blw_wnd:int:180", |
| eDI_MP_cmb32_blw_wnd, 180}, |
| [eDI_MP_cmb32_wnd_ext] = {"cmb32_wnd_ext:int:11", |
| eDI_MP_cmb32_wnd_ext, 11}, |
| [eDI_MP_cmb32_wnd_tol] = {"cmb32_wnd_tol:int:4", |
| eDI_MP_cmb32_wnd_tol, 4}, |
| [eDI_MP_cmb32_frm_nocmb] = {"cmb32_frm_nocmb:int:40", |
| eDI_MP_cmb32_frm_nocmb, 40}, |
| [eDI_MP_cmb32_min02_sft] = {"cmb32_min02_sft:int:7", |
| eDI_MP_cmb32_min02_sft, 7}, |
| [eDI_MP_cmb32_cmb_tol] = {"cmb32_cmb_tol:int:10", |
| eDI_MP_cmb32_cmb_tol, 10}, |
| [eDI_MP_cmb32_avg_dff] = {"cmb32_avg_dff:int:48", |
| eDI_MP_cmb32_avg_dff, 48}, |
| [eDI_MP_cmb32_smfrm_num] = {"cmb32_smfrm_num:int:4", |
| eDI_MP_cmb32_smfrm_num, 4}, |
| [eDI_MP_cmb32_nocmb_num] = {"cmb32_nocmb_num:int:20", |
| eDI_MP_cmb32_nocmb_num, 20}, |
| [eDI_MP_cmb22_gcmb_rnum] = {"cmb22_gcmb_rnum:int:8", |
| eDI_MP_cmb22_gcmb_rnum, 8}, |
| [eDI_MP_flmxx_cal_lcmb] = {"flmxx_cal_lcmb:int:1", |
| eDI_MP_flmxx_cal_lcmb, 1}, |
| [eDI_MP_flm2224_stl_sft] = {"flm2224_stl_sft:int:7", |
| eDI_MP_flm2224_stl_sft, 7}, |
| [eDI_MP_SUB_PD_E] = {"pd end------", |
| eDI_MP_SUB_PD_E, 0}, |
| /**************************************/ |
| [eDI_MP_SUB_MTN_B] = {"mtn begin", |
| eDI_MP_SUB_MTN_B, 0}, |
| [eDI_MP_force_lev] = {"force_lev:int:0xff", |
| eDI_MP_force_lev, 0xff}, |
| [eDI_MP_dejaggy_flag] = {"dejaggy_flag:int:-1", |
| eDI_MP_dejaggy_flag, -1}, |
| [eDI_MP_dejaggy_enable] = {"dejaggy_enable:int:1", |
| eDI_MP_dejaggy_enable, 1}, |
| [eDI_MP_cmb_adpset_cnt] = {"cmb_adpset_cnt:int", |
| eDI_MP_cmb_adpset_cnt, 0}, |
| [eDI_MP_cmb_num_rat_ctl4] = {"cmb_num_rat_ctl4:int:64:0~255", |
| eDI_MP_cmb_num_rat_ctl4, 64}, |
| [eDI_MP_cmb_rat_ctl4_minthd] = {"cmb_rat_ctl4_minthd:int:64", |
| eDI_MP_cmb_rat_ctl4_minthd, 64}, |
| [eDI_MP_small_local_mtn] = {"small_local_mtn:uint:70", |
| eDI_MP_small_local_mtn, 70}, |
| [eDI_MP_di_debug_readreg] = {"di_debug_readreg:int", |
| eDI_MP_di_debug_readreg, 0}, |
| [eDI_MP_SUB_MTN_E] = {"mtn end----", |
| eDI_MP_SUB_MTN_E, 0}, |
| /**************************************/ |
| [eDI_MP_SUB_3D_B] = {"3d begin", |
| eDI_MP_SUB_3D_B, 0}, |
| [eDI_MP_chessbd_vrate] = {"chessbd_vrate:int:29", |
| eDI_MP_chessbd_vrate, 29}, |
| [eDI_MP_det3d_debug] = {"det3d_debug:bool:0", |
| eDI_MP_det3d_debug, 0}, |
| [eDI_MP_SUB_3D_E] = {"3d begin", |
| eDI_MP_SUB_3D_E, 0}, |
| |
| /**************************************/ |
| [eDI_MP_UI_T_END] = {"module para top end ", eDI_MP_UI_T_END, 0} |
| }; |
| |
| bool div3_mp_uit_check(unsigned int idx) |
| { |
| unsigned int tsize; |
| |
| tsize = ARRAY_SIZE(div3_mp_ui_top); |
| if (idx >= tsize) { |
| PR_ERR("div3_mp_uit_check:err:overflow:%d->%d\n", |
| idx, tsize); |
| return false; |
| } |
| if (idx != div3_mp_ui_top[idx].id) { |
| PR_ERR("%s:err:not map:%d->%d\n", |
| __func__, idx, div3_mp_ui_top[idx].id); |
| return false; |
| } |
| dbg_init("\t%-15s=%d\n", div3_mp_ui_top[idx].name, |
| div3_mp_ui_top[idx].default_val); |
| return true; |
| } |
| |
| char *div3_mp_uit_get_name(enum eDI_MP_UI_T idx) |
| { |
| return div3_mp_ui_top[idx].name; |
| } |
| |
| void div3_mp_uit_init_val(void) |
| { |
| int i; |
| |
| for (i = eDI_MP_UI_T_BEGIN; i < eDI_MP_UI_T_END; i++) { |
| if (!div3_mp_uit_check(i)) |
| continue; |
| dimp_set(i, div3_mp_ui_top[i].default_val); |
| } |
| } |
| #if 0 |
| int di_mp_uit_get(enum eDI_MP_UI_T idx) |
| { |
| return get_datal()->mp_uit[idx]; |
| } |
| |
| void di_mp_uit_set(enum eDI_MP_UI_T idx, int val) |
| { |
| get_datal()->mp_uit[idx] = val; |
| } |
| #endif |
| |
| /************************************** |
| * |
| * module para x |
| * unsigned int |
| **************************************/ |
| |
| const struct di_mp_uix_s div3_mpx[] = { |
| /*same order with enum eDI_MP_UI*/ |
| |
| /* module para for channel x*/ |
| [eDI_MP_UIX_BEGIN] = {"module para x begin ", eDI_MP_UIX_BEGIN, 0}, |
| /*debug: run_flag*/ |
| [eDI_MP_UIX_RUN_FLG] = {"run_flag(0:run;1:pause;2:step)", |
| eDI_MP_UIX_RUN_FLG, DI_RUN_FLAG_RUN}, |
| [eDI_MP_UIX_END] = {"module para x end ", eDI_MP_UIX_END, 0} |
| |
| }; |
| |
| bool div3_mp_uix_check(unsigned int idx) |
| { |
| unsigned int tsize; |
| |
| tsize = ARRAY_SIZE(div3_mpx); |
| if (idx >= tsize) { |
| PR_ERR("%s:err:overflow:%d->%d\n", |
| __func__, idx, tsize); |
| return false; |
| } |
| if (idx != div3_mpx[idx].id) { |
| PR_ERR("%s:err:not map:%d->%d\n", |
| __func__, idx, div3_mpx[idx].id); |
| return false; |
| } |
| dbg_init("\t%-15s=%d\n", div3_mpx[idx].name, div3_mpx[idx].default_val); |
| |
| return true; |
| } |
| |
| char *div3_mp_uix_get_name(enum eDI_MP_UIX_T idx) |
| { |
| return div3_mpx[idx].name; |
| } |
| |
| void div3_mp_uix_init_val(void) |
| { |
| int i, ch; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| dbg_init("%s:ch[%d]\n", __func__, ch); |
| for (i = eDI_MP_UIX_BEGIN; i < eDI_MP_UIX_END; i++) { |
| if (ch == 0) { |
| if (!div3_mp_uix_check(i)) |
| continue; |
| } |
| div3_mp_uix_set(ch, i, div3_mpx[i].default_val); |
| } |
| } |
| } |
| |
| unsigned int div3_mp_uix_get(unsigned int ch, enum eDI_MP_UIX_T idx) |
| { |
| return get_datal()->ch_data[ch].mp_uix[idx]; |
| } |
| |
| void div3_mp_uix_set(unsigned int ch, enum eDI_MP_UIX_T idx, unsigned int val) |
| { |
| get_datal()->ch_data[ch].mp_uix[idx] = val; |
| } |
| |
| bool div3_is_pause(unsigned int ch) |
| { |
| unsigned int run_flag; |
| |
| run_flag = div3_mp_uix_get(ch, eDI_MP_UIX_RUN_FLG); |
| |
| if (run_flag == DI_RUN_FLAG_PAUSE || |
| run_flag == DI_RUN_FLAG_STEP_DONE) |
| return true; |
| |
| return false; |
| } |
| |
| void div3_pause_step_done(unsigned int ch) |
| { |
| unsigned int run_flag; |
| |
| run_flag = div3_mp_uix_get(ch, eDI_MP_UIX_RUN_FLG); |
| if (run_flag == DI_RUN_FLAG_STEP) { |
| div3_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG, |
| DI_RUN_FLAG_STEP_DONE); |
| } |
| } |
| |
| void div3_pause(unsigned int ch, bool on) |
| { |
| PR_INF("%s:%d\n", __func__, on); |
| if (on) |
| div3_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG, |
| DI_RUN_FLAG_PAUSE); |
| else |
| div3_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG, |
| DI_RUN_FLAG_RUN); |
| } |
| |
| /************************************** |
| * |
| * summmary variable |
| * |
| **************************************/ |
| const struct di_sum_s div3_sum_tab[] = { |
| /*video_peek_cnt*/ |
| [eDI_SUM_O_PEEK_CNT] = {"o_peek_cnt", eDI_SUM_O_PEEK_CNT, 0}, |
| /*di_reg_unreg_cnt*/ |
| [eDI_SUM_REG_UNREG_CNT] = { |
| "di_reg_unreg_cnt", eDI_SUM_REG_UNREG_CNT, 100}, |
| |
| [eDI_SUM_NUB] = {"end", eDI_SUM_NUB, 0} |
| }; |
| |
| unsigned int div3_sum_get_tab_size(void) |
| { |
| return ARRAY_SIZE(div3_sum_tab); |
| } |
| |
| bool div3_sum_check(unsigned int ch, enum eDI_SUM id) |
| { |
| unsigned int tsize; |
| |
| tsize = ARRAY_SIZE(div3_sum_tab); |
| |
| if (id >= tsize) { |
| PR_ERR("%s:err:overflow:tsize[%d],id[%d]\n", |
| __func__, tsize, id); |
| return false; |
| } |
| if (div3_sum_tab[id].index != id) { |
| PR_ERR("%s:err:table:id[%d],tab_id[%d]\n", |
| __func__, id, div3_sum_tab[id].index); |
| return false; |
| } |
| return true; |
| } |
| |
| void div3_sum_reg_init(unsigned int ch) |
| { |
| unsigned int tsize; |
| int i; |
| |
| tsize = ARRAY_SIZE(div3_sum_tab); |
| |
| dbg_init("%s:ch[%d]\n", __func__, ch); |
| for (i = 0; i < tsize; i++) { |
| if (!div3_sum_check(ch, i)) |
| continue; |
| dbg_init("\t:%d:name:%s,%d\n", i, div3_sum_tab[i].name, |
| div3_sum_tab[i].default_val); |
| di_sum_set_l(ch, i, div3_sum_tab[i].default_val); |
| } |
| } |
| |
| void div3_sum_get_info(unsigned int ch, enum eDI_SUM id, char **name, |
| unsigned int *pval) |
| { |
| *name = div3_sum_tab[id].name; |
| *pval = div3_sum_get(ch, id); |
| } |
| |
| void div3_sum_set(unsigned int ch, enum eDI_SUM id, unsigned int val) |
| { |
| if (!div3_sum_check(ch, id)) |
| return; |
| |
| di_sum_set_l(ch, id, val); |
| } |
| |
| unsigned int div3_sum_inc(unsigned int ch, enum eDI_SUM id) |
| { |
| if (!div3_sum_check(ch, id)) |
| return 0; |
| return di_sum_inc_l(ch, id); |
| } |
| |
| unsigned int div3_sum_get(unsigned int ch, enum eDI_SUM id) |
| { |
| if (!div3_sum_check(ch, id)) |
| return 0; |
| return di_sum_get_l(ch, id); |
| } |
| |
| /**********************************/ |
| void dimv3_sumx_clear(unsigned int ch) |
| { |
| struct dim_sum_s *psumx = get_sumx(ch); |
| |
| memset(psumx, 0, sizeof(*psumx)); |
| } |
| |
| void dimv3_sumx_set(unsigned int ch) |
| { |
| struct dim_sum_s *psumx = get_sumx(ch); |
| struct di_mm_s *mm = dim_mm_get(ch); |
| unsigned int pst_kee; |
| |
| psumx->b_pre_free = listv3_count(ch, QUEUE_LOCAL_FREE); |
| psumx->b_pre_ready = div3_que_list_count(ch, QUE_PRE_READY); |
| psumx->b_pst_free = div3_que_list_count(ch, QUE_POST_FREE); |
| psumx->b_pst_ready = div3_que_list_count(ch, QUE_POST_READY); |
| psumx->b_recyc = listv3_count(ch, QUEUE_RECYCLE); |
| psumx->b_display = listv3_count(ch, QUEUE_DISPLAY); |
| |
| pst_kee = div3_que_list_count(ch, QUE_POST_KEEP); |
| |
| if (pst_kee && |
| (pst_kee + psumx->b_display) > (mm->cfg.num_post - 3)) |
| taskv3_send_cmd(LCMD1(ECMD_RL_KEEP_ALL, ch)); |
| } |
| |
| /****************************/ |
| /*call by event*/ |
| /****************************/ |
| void dipv3_even_reg_init_val(unsigned int ch) |
| { |
| } |
| |
| void dipv3_even_unreg_val(unsigned int ch) |
| { |
| } |
| |
| /****************************/ |
| static void dip_cma_init_val(void) |
| { |
| unsigned int ch; |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| /* CMA state */ |
| atomic_set(&pbm->cma_mem_state[ch], EDI_CMA_ST_IDL); |
| |
| /* CMA reg/unreg cmd */ |
| pbm->cma_reg_cmd[ch] = 0; |
| } |
| } |
| |
| void dipv3_cma_close(void) |
| { |
| unsigned int ch; |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| if (dipv3_cma_st_is_idl_all()) |
| return; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| if (!dipv3_cma_st_is_idle(ch)) { |
| dimv3_cma_top_release(ch); |
| PR_INF("%s:force release ch[%d]", __func__, ch); |
| atomic_set(&pbm->cma_mem_state[ch], EDI_CMA_ST_IDL); |
| |
| pbm->cma_reg_cmd[ch] = 0; |
| } |
| } |
| } |
| |
| static void dip_wq_cma_handler(struct work_struct *work) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| enum eDI_CMA_ST cma_st; |
| bool do_flg; |
| struct dim_wq_s *wq = container_of(work, struct dim_wq_s, wq_work); |
| |
| unsigned int ch = wq->ch; |
| |
| do_flg = false; |
| cma_st = dipv3_cma_get_st(ch); |
| dbg_wq("%s:ch[%d],cmd[%d],st[%d]\n", |
| __func__, ch, pbm->cma_reg_cmd[ch], cma_st); |
| switch (cma_st) { |
| case EDI_CMA_ST_IDL: |
| if (pbm->cma_reg_cmd[ch]) { |
| do_flg = true; |
| /*set:alloc:*/ |
| atomic_set(&pbm->cma_mem_state[ch], EDI_CMA_ST_ALLOC); |
| if (dimv3_cma_top_alloc(ch)) { |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_READY); |
| } |
| } |
| break; |
| case EDI_CMA_ST_READY: |
| |
| if (!pbm->cma_reg_cmd[ch]) { |
| do_flg = true; |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_RELEASE); |
| dimv3_cma_top_release(ch); |
| if (div3_que_is_empty(ch, QUE_POST_KEEP)) |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_IDL); |
| else |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_PART); |
| } |
| break; |
| case EDI_CMA_ST_PART: |
| if (pbm->cma_reg_cmd[ch]) { |
| do_flg = true; |
| /*set:alloc:*/ |
| atomic_set(&pbm->cma_mem_state[ch], EDI_CMA_ST_ALLOC); |
| if (dimv3_cma_top_alloc(ch)) { |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_READY); |
| } |
| } else { |
| do_flg = true; |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_RELEASE); |
| dimv3_cma_top_release(ch); |
| if (div3_que_is_empty(ch, QUE_POST_KEEP)) |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_IDL); |
| else |
| atomic_set(&pbm->cma_mem_state[ch], |
| EDI_CMA_ST_PART); |
| |
| } |
| |
| break; |
| case EDI_CMA_ST_ALLOC: /*do*/ |
| case EDI_CMA_ST_RELEASE:/*do*/ |
| default: |
| break; |
| } |
| if (!do_flg) |
| PR_INF("\tch[%d],do nothing[%d]\n", ch, cma_st); |
| else |
| taskv3_send_ready(); |
| |
| dbg_wq("%s:end\n", __func__); |
| } |
| |
| static void dip_wq_prob(void) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| pbm->wq.wq_cma = create_singlethread_workqueue("deinterlace"); |
| INIT_WORK(&pbm->wq.wq_work, dip_wq_cma_handler); |
| } |
| |
| static void dip_wq_ext(void) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| cancel_work_sync(&pbm->wq.wq_work); |
| destroy_workqueue(pbm->wq.wq_cma); |
| pr_info("%s:finish\n", __func__); |
| } |
| |
| void dipv3_wq_cma_run(unsigned char ch, bool reg_cmd) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| dbg_wq("%s:ch[%d] [%d]\n", __func__, ch, reg_cmd); |
| if (reg_cmd) |
| pbm->cma_reg_cmd[ch] = 1; |
| else |
| pbm->cma_reg_cmd[ch] = 0; |
| |
| pbm->wq.ch = ch; |
| queue_work(pbm->wq.wq_cma, &pbm->wq.wq_work); |
| } |
| |
| bool dipv3_cma_st_is_ready(unsigned int ch) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| bool ret = false; |
| |
| if (atomic_read(&pbm->cma_mem_state[ch]) == EDI_CMA_ST_READY) |
| ret = true; |
| |
| return ret; |
| } |
| |
| bool dipv3_cma_st_is_idle(unsigned int ch) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| bool ret = false; |
| |
| if (atomic_read(&pbm->cma_mem_state[ch]) == EDI_CMA_ST_IDL) |
| ret = true; |
| |
| return ret; |
| } |
| |
| bool dipv3_cma_st_is_idl_all(void) |
| { |
| unsigned int ch; |
| struct di_mng_s *pbm = get_bufmng(); |
| bool ret = true; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| if (atomic_read(&pbm->cma_mem_state[ch]) != EDI_CMA_ST_IDL) { |
| ret = true; |
| break; |
| } |
| } |
| return ret; |
| } |
| |
| enum eDI_CMA_ST dipv3_cma_get_st(unsigned int ch) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| return atomic_read(&pbm->cma_mem_state[ch]); |
| } |
| |
| const char * const div3_cma_state_name[] = { |
| "IDLE", |
| "do_alloc", |
| "READY", |
| "do_release", |
| "PART" |
| }; |
| |
| const char *div3_cma_dbg_get_st_name(unsigned int ch) |
| { |
| enum eDI_CMA_ST st = dipv3_cma_get_st(ch); |
| const char *p = "overflow"; |
| |
| if (st < ARRAY_SIZE(div3_cma_state_name)) |
| p = div3_cma_state_name[st]; |
| return p; |
| } |
| |
| void dipv3_cma_st_set_ready_all(void) |
| { |
| unsigned int ch; |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) |
| atomic_set(&pbm->cma_mem_state[ch], EDI_CMA_ST_READY); |
| } |
| |
| /****************************/ |
| /*channel STATE*/ |
| /****************************/ |
| void dipv3_chst_set(unsigned int ch, enum EDI_TOP_STATE chst) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| atomic_set(&pbm->ch_state[ch], chst); |
| } |
| |
| enum EDI_TOP_STATE dipv3_chst_get(unsigned int ch) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| return atomic_read(&pbm->ch_state[ch]); |
| } |
| |
| void dipv3_chst_init(void) |
| { |
| unsigned int ch; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) |
| dipv3_chst_set(ch, EDI_TOP_STATE_IDLE); |
| } |
| |
| int dipv3_event_reg_chst(unsigned int ch) |
| { |
| enum EDI_TOP_STATE chst; |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| bool err_flg = false; |
| bool ret = 0; |
| struct di_ch_s *pch; |
| |
| dbg_dbg("%s:ch[%d]\n", __func__, ch); |
| |
| if (get_reg_flag(ch)) { |
| PR_ERR("no muti instance.\n"); |
| return -1; |
| } |
| pch = get_chdata(ch); |
| chst = dipv3_chst_get(ch); |
| #if 0 /*move*/ |
| if (chst > eDI_TOP_STATE_NOPROB) |
| set_flag_trig_unreg(ch, false); |
| #endif |
| switch (chst) { |
| case EDI_TOP_STATE_IDLE: |
| |
| queuev3_init2(ch); |
| div3_que_init(ch); |
| /*di_vframe_reg(ch);*/ |
| #if 1 |
| /*need call below two function before dvfm_fill_in*/ |
| dimv3_reg_cfg_sys(pch); |
| dipv3_init_value_reg(ch); |
| #endif |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP1); |
| dimv3_htr_start(ch); |
| taskv3_send_cmd(LCMD1(eCMD_REG, ch)); |
| dbg_dbg("reg ok\n"); |
| break; |
| case eDI_TOP_STATE_REG_STEP1: |
| case eDI_TOP_STATE_REG_STEP1_P1: |
| case eDI_TOP_STATE_REG_STEP2: |
| case EDI_TOP_STATE_READY: |
| case eDI_TOP_STATE_BYPASS: |
| PR_WARN("have reg\n"); |
| ret = false; |
| break; |
| case eDI_TOP_STATE_UNREG_STEP1: |
| case eDI_TOP_STATE_UNREG_STEP2: |
| /*wait*/ |
| ppre->reg_req_flag_cnt = 0; |
| while (dipv3_chst_get(ch) != EDI_TOP_STATE_IDLE) { |
| usleep_range(10000, 10001); |
| if (ppre->reg_req_flag_cnt++ > |
| dimv3_get_reg_unreg_cnt()) { |
| dimv3_reg_timeout_inc(); |
| PR_ERR("%s,ch[%d] reg timeout!!!\n", |
| __func__, ch); |
| err_flg = true; |
| ret = false; |
| break; |
| } |
| } |
| if (!err_flg) { |
| /*same as IDLE*/ |
| queuev3_init2(ch); |
| div3_que_init(ch); |
| /*di_vframe_reg(ch);*/ |
| #if 1 |
| /*need call below two function before dvfm_fill_in*/ |
| dimv3_reg_cfg_sys(pch); |
| dipv3_init_value_reg(ch); |
| #endif |
| |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP1); |
| taskv3_send_cmd(LCMD1(eCMD_REG, ch)); |
| dbg_dbg("reg retry ok\n"); |
| } |
| break; |
| case eDI_TOP_STATE_NOPROB: |
| default: |
| ret = false; |
| PR_ERR("err: not prob[%d]\n", chst); |
| |
| break; |
| } |
| dbg_ev("ch[%d]:reg end\n", ch); |
| |
| return ret; |
| } |
| |
| bool dipv3_event_unreg_chst(unsigned int ch) |
| { |
| enum EDI_TOP_STATE chst, chst2; |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| bool ret = false; |
| bool err_flg = false; |
| unsigned int cnt; |
| |
| chst = dipv3_chst_get(ch); |
| dbg_reg("%s:ch[%d]:%s\n", __func__, ch, dipv3_chst_get_name(chst)); |
| #if 0 |
| if (chst > eDI_TOP_STATE_IDLE) |
| set_reg_flag(ch, false);/*set_flag_trig_unreg(ch, true);*/ |
| #endif |
| if (chst > eDI_TOP_STATE_NOPROB) |
| set_flag_trig_unreg(ch, true); |
| |
| switch (chst) { |
| case EDI_TOP_STATE_READY: |
| |
| //di_vframe_unreg(ch); |
| dimv3_htr_stop(ch); |
| /*trig unreg*/ |
| dipv3_chst_set(ch, eDI_TOP_STATE_UNREG_STEP1); |
| taskv3_send_cmd(LCMD1(eCMD_UNREG, ch)); |
| /*debug only di_dbg = di_dbg|DBG_M_TSK;*/ |
| |
| /*wait*/ |
| ppre->unreg_req_flag_cnt = 0; |
| chst2 = dipv3_chst_get(ch); |
| |
| while (chst2 != EDI_TOP_STATE_IDLE) { |
| taskv3_send_ready(); |
| usleep_range(10000, 10001); |
| /*msleep(5);*/ |
| if (ppre->unreg_req_flag_cnt++ |
| > dimv3_get_reg_unreg_cnt()) { |
| dimv3_reg_timeout_inc(); |
| PR_ERR("%s:ch[%d] unreg timeout!!!\n", |
| __func__, ch); |
| /*dim_unreg_process();*/ |
| err_flg = true; |
| break; |
| } |
| #if 0 /*debug only*/ |
| dbg_reg("\tch[%d]:s[%s],ecnt[%d]\n", |
| ch, |
| dipv3_chst_get_name(chst2), |
| ppre->unreg_req_flag_cnt); |
| #endif |
| chst2 = dipv3_chst_get(ch); |
| } |
| |
| /*debug only di_dbg = di_dbg & (~DBG_M_TSK);*/ |
| dbg_reg("%s:ch[%d] ready end\n", __func__, ch); |
| #if 0 |
| if (!err_flg) |
| set_reg_flag(ch, false); |
| #endif |
| break; |
| case eDI_TOP_STATE_BYPASS: |
| /*from bypass complet to unreg*/ |
| //di_vframe_unreg(ch); |
| div3_unreg_variable(ch); |
| |
| set_reg_flag(ch, false); |
| dimv3_htr_stop(ch); |
| if (!get_reg_flag_all()) { |
| div3_unreg_setting(); |
| dprev3_init(); |
| dpostv3_init(); |
| } |
| dipv3_chst_set(ch, EDI_TOP_STATE_IDLE); |
| ret = true; |
| |
| break; |
| case EDI_TOP_STATE_IDLE: |
| PR_WARN("have unreg\n"); |
| break; |
| case eDI_TOP_STATE_REG_STEP1: |
| dbg_dbg("%s:in reg step1\n", __func__); |
| //di_vframe_unreg(ch); |
| set_reg_flag(ch, false); |
| |
| dimv3_htr_stop(ch); |
| dipv3_chst_set(ch, EDI_TOP_STATE_IDLE); |
| |
| ret = true; |
| break; |
| case eDI_TOP_STATE_REG_STEP1_P1: |
| /*wait:*/ |
| cnt = 0; |
| chst2 = dipv3_chst_get(ch); |
| while (chst2 == eDI_TOP_STATE_REG_STEP1_P1 || cnt < 5) { |
| taskv3_send_ready(); |
| usleep_range(3000, 3001); |
| cnt++; |
| } |
| if (cnt >= 5) |
| PR_ERR("%s:ch[%d] in p1 timeout\n", __func__, ch); |
| |
| set_reg_flag(ch, false); |
| |
| //di_vframe_unreg(ch); |
| dimv3_htr_stop(ch); |
| /*trig unreg*/ |
| dipv3_chst_set(ch, eDI_TOP_STATE_UNREG_STEP1); |
| taskv3_send_cmd(LCMD1(eCMD_UNREG, ch)); |
| /*debug only di_dbg = di_dbg|DBG_M_TSK;*/ |
| |
| /*wait*/ |
| ppre->unreg_req_flag_cnt = 0; |
| chst2 = dipv3_chst_get(ch); |
| |
| while (chst2 != EDI_TOP_STATE_IDLE) { |
| taskv3_send_ready(); |
| usleep_range(10000, 10001); |
| /*msleep(5);*/ |
| if (ppre->unreg_req_flag_cnt++ |
| > dimv3_get_reg_unreg_cnt()) { |
| dimv3_reg_timeout_inc(); |
| PR_ERR("%s:ch[%d] unreg timeout!!!\n", |
| __func__, |
| ch); |
| /*di_unreg_process();*/ |
| err_flg = true; |
| break; |
| } |
| |
| chst2 = dipv3_chst_get(ch); |
| } |
| |
| /*debug only di_dbg = di_dbg & (~DBG_M_TSK);*/ |
| dbg_reg("%s:ch[%d] ready end\n", __func__, ch); |
| ret = true; |
| |
| break; |
| case eDI_TOP_STATE_REG_STEP2: |
| //di_vframe_unreg(ch); |
| div3_unreg_variable(ch); |
| set_reg_flag(ch, false); |
| dimv3_htr_stop(ch); |
| if (!get_reg_flag_all()) { |
| div3_unreg_setting(); |
| dprev3_init(); |
| dpostv3_init(); |
| } |
| |
| dipv3_chst_set(ch, EDI_TOP_STATE_IDLE); |
| |
| ret = true; |
| break; |
| case eDI_TOP_STATE_UNREG_STEP1: |
| case eDI_TOP_STATE_UNREG_STEP2: |
| taskv3_send_cmd(LCMD1(eCMD_UNREG, ch)); |
| |
| /*wait*/ |
| ppre->unreg_req_flag_cnt = 0; |
| while (dipv3_chst_get(ch) != EDI_TOP_STATE_IDLE) { |
| usleep_range(10000, 10001); |
| if (ppre->unreg_req_flag_cnt++ > |
| dimv3_get_reg_unreg_cnt()) { |
| dimv3_reg_timeout_inc(); |
| PR_ERR("%s:unreg_reg_flag timeout!!!\n", |
| __func__); |
| //di_vframe_unreg(ch); |
| dimv3_htr_stop(ch); |
| err_flg = true; |
| break; |
| } |
| } |
| break; |
| case eDI_TOP_STATE_NOPROB: |
| default: |
| PR_ERR("err: not prob[%d]\n", chst); |
| break; |
| } |
| if (err_flg) |
| ret = false; |
| |
| dbg_ev("ch[%d] ret[%d]unreg end\n", ch, ret); |
| |
| return ret; |
| } |
| |
| /*process for reg and unreg cmd*/ |
| void dipv3_chst_process_reg(unsigned int ch) |
| { |
| enum EDI_TOP_STATE chst; |
| //struct vframe_s *vframe; |
| void *vframe; |
| // struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| bool reflesh = true; |
| struct di_hpre_s *pre = get_hw_pre(); |
| struct di_ch_s *pch; |
| struct dim_dvfm_s *pdvfm; |
| |
| while (reflesh) { |
| reflesh = false; |
| |
| chst = dipv3_chst_get(ch); |
| |
| /*dbg_reg("%s:ch[%d]%s\n", __func__, ch, dipv3_chst_get_name(chst));*/ |
| |
| switch (chst) { |
| case eDI_TOP_STATE_NOPROB: |
| case EDI_TOP_STATE_IDLE: |
| break; |
| case eDI_TOP_STATE_REG_STEP1:/*wait peek*/ |
| //dim_htr_start(); |
| pch = get_chdata(ch); |
| vframe = pch->interf.opsi.peek(pch);//pw_vf_peek(ch); |
| |
| if (vframe) { |
| dimv3_tr_ops.pre_get(0); |
| set_flag_trig_unreg(ch, false); |
| #if 0 |
| di_reg_variable(ch); |
| |
| /*?how about bypass ?*/ |
| if (ppre->bypass_flag) { |
| /* complete bypass */ |
| setv3_bypass2_complete(ch, true); |
| if (!get_reg_flag_all()) { |
| /*first channel reg*/ |
| dprev3_init(); |
| dpostv3_init(); |
| div3_reg_setting(ch, vframe); |
| } |
| dipv3_chst_set(ch, eDI_TOP_STATE_BYPASS); |
| set_reg_flag(ch, true); |
| } else { |
| setv3_bypass2_complete(ch, false); |
| if (!get_reg_flag_all()) { |
| /*first channel reg*/ |
| dprev3_init(); |
| dpostv3_init(); |
| div3_reg_setting(ch, vframe); |
| } |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP2); |
| } |
| #else |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP1_P1); |
| #endif |
| |
| reflesh = true; |
| } |
| break; |
| case eDI_TOP_STATE_REG_STEP1_P1: |
| pch = get_chdata(ch); |
| vframe = pch->interf.opsi.peek(pch);//pw_vf_peek(ch); |
| if (!vframe) { |
| PR_ERR("%s:p1 vfm nop\n", __func__); |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP1); |
| |
| break; |
| } |
| #if 0 /*move to reg_step1*/ |
| /*need call below two function before dvfm_fill_in*/ |
| dimv3_reg_cfg_sys(pch); |
| dipv3_init_value_reg(ch); |
| #endif |
| pdvfm = pch->interf.op_dvfm_fill(pch);//dvfm_fill_in(pch); |
| if (!pdvfm) |
| break; |
| |
| //di_reg_variable(ch, pdvfm); |
| /*pre ops*/ |
| set_h_ppre(ch); |
| if (pre && pre->ops.reg_var) |
| pre->ops.reg_var(pre); |
| |
| /*di_reg_process_irq(ch);*/ /*check if bypass*/ |
| |
| /*?how about bypass ?*/ |
| //if (ppre->bypass_flag) { |
| if (pdvfm->wmode.need_bypass) { |
| /* complete bypass */ |
| setv3_bypass2_complete(ch, true); |
| di_reg_variable_needbypass(ch, pdvfm); |
| if (!get_reg_flag_all()) { |
| /*first channel reg*/ |
| dprev3_init(); |
| dpostv3_init(); |
| pdvfm->wmode.src_h = 480;/*only use for reg*/ |
| pdvfm->wmode.src_w = 720; |
| div3_reg_setting(ch, vframe, &pdvfm->wmode); |
| /*pre ops*/ |
| if (pre && pre->ops.reg_hw) |
| pre->ops.reg_hw(pre); |
| } |
| dipv3_chst_set(ch, eDI_TOP_STATE_BYPASS); |
| set_reg_flag(ch, true); |
| dimv3_htr_con_update((DIM_HTM_REG_BIT << ch), false); |
| dimv3_htr_con_update(DIM_HTM_W_INPUT, true); |
| } else { |
| setv3_bypass2_complete(ch, false); |
| di_reg_variable_normal(ch, pdvfm); |
| if (!get_reg_flag_all()) { |
| /*first channel reg*/ |
| dprev3_init(); |
| dpostv3_init(); |
| div3_reg_setting(ch, vframe, &pdvfm->wmode); |
| /*pre ops*/ |
| if (pre && pre->ops.reg_hw) |
| pre->ops.reg_hw(pre); |
| } |
| /*this will cause first local buf not alloc*/ |
| /*dimv3_bypass_first_frame(ch);*/ |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP2); |
| dimv3_htr_con_update((DIM_HTM_REG_BIT << ch), false); |
| dimv3_htr_con_update(DIM_HTM_W_INPUT, true); |
| /*set_reg_flag(ch, true);*/ |
| } |
| |
| reflesh = true; |
| break; |
| case eDI_TOP_STATE_REG_STEP2:/*now no change to do*/ |
| if (dipv3_cma_get_st(ch) == EDI_CMA_ST_READY) { |
| if (div3_cfg_top_get(EDI_CFG_first_bypass)) { |
| if (get_sum_g(ch) == 0) |
| dimv3_bypass_first_frame(ch); |
| else |
| PR_INF("ch[%d],g[%d]\n", |
| ch, get_sum_g(ch)); |
| } |
| dipv3_chst_set(ch, EDI_TOP_STATE_READY); |
| set_reg_flag(ch, true); |
| /*move to step1 dimv3_bypass_first_frame(ch);*/ |
| } |
| break; |
| case EDI_TOP_STATE_READY: |
| |
| break; |
| case eDI_TOP_STATE_BYPASS: |
| /*do nothing;*/ |
| break; |
| case eDI_TOP_STATE_UNREG_STEP1: |
| |
| #if 0 |
| if (!get_reg_flag(ch)) { /*need wait pre/post done*/ |
| dipv3_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); |
| reflesh = true; |
| } |
| #else |
| /*debug only dbg_reg("%s:UNREG_STEP1\n", __func__);*/ |
| |
| if (dprev3_can_exit(ch) && dpstv3_can_exit(ch)) { |
| dipv3_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); |
| set_reg_flag(ch, false); |
| reflesh = true; |
| } |
| #endif |
| break; |
| case eDI_TOP_STATE_UNREG_STEP2: |
| /*debug only dbg_reg("%s:ch[%d]:UNREG_STEP2\n",__func__, ch);*/ |
| div3_unreg_variable(ch); |
| |
| /*pre ops*/ |
| set_h_ppre(ch); |
| if (pre && pre->ops.unreg_var) |
| pre->ops.unreg_var(pre); |
| |
| //dim_htr_stop(ch); |
| if (!get_reg_flag_all()) { |
| div3_unreg_setting(); |
| /*pre ops*/ |
| if (pre && pre->ops.unreg_hw) |
| pre->ops.unreg_hw(pre); |
| dprev3_init(); |
| dpostv3_init(); |
| } |
| |
| dipv3_chst_set(ch, EDI_TOP_STATE_IDLE); |
| /*debug only dbg_reg("ch[%d]UNREG_STEP2 end\n",ch);*/ |
| break; |
| } |
| } |
| } |
| |
| void dipv3_chst_process_ch(void) |
| { |
| unsigned int ch; |
| unsigned int chst; |
| struct di_hpre_s *pre = get_hw_pre(); |
| struct di_ch_s *pch = NULL; |
| struct dim_dvfm_s *pdvfm; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| chst = dipv3_chst_get(ch); |
| if (chst > EDI_TOP_STATE_IDLE) |
| pch = get_chdata(ch); |
| |
| switch (chst) { |
| case eDI_TOP_STATE_REG_STEP2: |
| //pr_info("x2\n"); |
| if (dipv3_cma_get_st(ch) == EDI_CMA_ST_READY) { |
| if (div3_cfg_top_get(EDI_CFG_first_bypass)) { |
| if (get_sum_g(ch) == 0) |
| dimv3_bypass_first_frame(ch); |
| else |
| PR_INF("ch[%d],g[%d]\n", |
| ch, get_sum_g(ch)); |
| } |
| dipv3_chst_set(ch, EDI_TOP_STATE_READY); |
| set_reg_flag(ch, true); |
| } |
| break; |
| #if 1 |
| case eDI_TOP_STATE_UNREG_STEP1: |
| dvfmv3_recycle(pch); |
| if (dprev3_can_exit(ch) && dpstv3_can_exit(ch)) { |
| dipv3_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); |
| set_reg_flag(ch, false); |
| } |
| |
| break; |
| #endif |
| case eDI_TOP_STATE_UNREG_STEP2: |
| dbg_reg("%s:ch[%d]:at UNREG_STEP2\n", __func__, ch); |
| div3_unreg_variable(ch); |
| /*pre ops*/ |
| set_h_ppre(ch); |
| |
| //dim_htr_stop(ch); |
| if (pre && pre->ops.unreg_var) |
| pre->ops.unreg_var(pre); |
| |
| if (!get_reg_flag_all()) { |
| div3_unreg_setting(); |
| if (pre && pre->ops.unreg_hw) |
| pre->ops.unreg_hw(pre); |
| dprev3_init(); |
| dpostv3_init(); |
| } |
| |
| dipv3_chst_set(ch, EDI_TOP_STATE_IDLE); |
| dbg_reg("ch[%d]STEP2 end\n", ch); |
| break; |
| case EDI_TOP_STATE_READY: |
| dvfmv3_recycle(pch); |
| pch->interf.op_dvfm_fill(pch);//dvfm_fill_in(pch); |
| dimv3_post_keep_back_recycle(ch); |
| dimv3_sumx_set(ch); |
| break; |
| case eDI_TOP_STATE_BYPASS: |
| //pr_info("x0\n"); |
| dvfmv3_recycle(pch); |
| pdvfm = dvfmv3_peek(pch, QUED_T_IN); |
| if (pdvfm && !pdvfm->wmode.need_bypass) { |
| pr_info("x1\n"); |
| setv3_bypass2_complete(ch, false); |
| di_reg_variable_normal(ch, pdvfm); |
| dipv3_chst_set(ch, eDI_TOP_STATE_REG_STEP2); |
| //dvfm_fill_in(pch); |
| pch->interf.op_dvfm_fill(pch); |
| } |
| |
| break; |
| } |
| } |
| } |
| |
| bool dipv3_chst_change_2unreg(void) |
| { |
| unsigned int ch; |
| unsigned int chst; |
| bool ret = false; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| chst = dipv3_chst_get(ch); |
| dbg_poll("[%d]%d\n", ch, chst); |
| if (chst == eDI_TOP_STATE_UNREG_STEP1) { |
| dbg_reg("%s:ch[%d]to UNREG_STEP2\n", __func__, ch); |
| set_reg_flag(ch, false); |
| dipv3_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); |
| ret = true; |
| } |
| } |
| return ret; |
| } |
| |
| /**************************************************************** |
| * tmode |
| ****************************************************************/ |
| void dimv3_tmode_preset(void) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| unsigned int ch; |
| unsigned int cnt; |
| |
| /*EDIM_TMODE_1_PW_VFM*/ |
| cnt = min_t(size_t, DI_CHANNEL_NUB, cfgg(TMODE_1)); |
| for (ch = 0; ch < cnt; ch++) |
| pbm->tmode_pre[ch] = EDIM_TMODE_1_PW_VFM; |
| |
| /*EDIM_TMODE_2_PW_OUT*/ |
| cnt += cfgg(TMODE_2); |
| cnt = min_t(size_t, DI_CHANNEL_NUB, cnt); |
| for (; ch < cnt; ch++) |
| pbm->tmode_pre[ch] = EDIM_TMODE_2_PW_OUT; |
| |
| /*EDIM_TMODE_3_PW_LOCAL*/ |
| cnt += cfgg(TMODE_3); |
| cnt = min_t(size_t, DI_CHANNEL_NUB, cnt); |
| for (; ch < cnt; ch++) |
| pbm->tmode_pre[ch] = EDIM_TMODE_3_PW_LOCAL; |
| |
| /*dbg*/ |
| PR_INF("dimv3_tmode_preset:\n"); |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) |
| PR_INF("\tch[%d]:tmode[%d]\n", ch, pbm->tmode_pre[ch]); |
| } |
| |
| void dim_tmode_set(unsigned int ch, enum EDIM_TMODE tmode) |
| { |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| if (ch >= DI_CHANNEL_NUB) |
| return; |
| |
| pbm->tmode_pre[ch] = tmode; |
| } |
| |
| bool dimv3_tmode_is_localpost(unsigned int ch) |
| { |
| // struct di_mng_s *pbm = get_bufmng(); |
| struct di_ch_s *pch; |
| |
| if (ch >= DI_CHANNEL_NUB) { |
| PR_ERR("%s:ch[%d]\n", __func__, ch); |
| return false; |
| } |
| pch = get_chdata(ch); |
| |
| if (pch->interf.tmode == EDIM_TMODE_2_PW_OUT) |
| return false; |
| return true; |
| } |
| #if 0 |
| void di_reg_flg_check(void) |
| { |
| int ch; |
| unsigned int chst; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) |
| chst = dipv3_chst_get(ch); |
| } |
| #endif |
| |
| void dipv3_hw_process(void) |
| { |
| div3_dbg_task_flg = 5; |
| dprev3_process(); |
| div3_dbg_task_flg = 6; |
| prev3_mode_setting(); |
| div3_dbg_task_flg = 7; |
| dpstv3_process(); |
| div3_dbg_task_flg = 8; |
| } |
| |
| const char * const div3_top_state_name[] = { |
| "NOPROB", |
| "IDLE", |
| "REG_STEP1", |
| "REG_P1", |
| "REG_STEP2", |
| "READY", |
| "BYPASS", |
| "UNREG_STEP1", |
| "UNREG_STEP2" |
| }; |
| |
| const char *dipv3_chst_get_name_curr(unsigned int ch) |
| { |
| const char *p = ""; |
| enum EDI_TOP_STATE chst; |
| |
| chst = dipv3_chst_get(ch); |
| |
| if (chst < ARRAY_SIZE(div3_top_state_name)) |
| p = div3_top_state_name[chst]; |
| |
| return p; |
| } |
| |
| const char *dipv3_chst_get_name(enum EDI_TOP_STATE chst) |
| { |
| const char *p = ""; |
| |
| if (chst < ARRAY_SIZE(div3_top_state_name)) |
| p = div3_top_state_name[chst]; |
| |
| return p; |
| } |
| /*********************************************** |
| *mm cfg |
| **********************************************/ |
| static const struct di_mm_cfg_s c_mm_cfg_normal = { |
| .di_h = 1088, |
| .di_w = 1920, |
| .num_local = MAX_LOCAL_BUF_NUM, |
| .num_post = MAX_POST_BUF_NUM, |
| }; |
| |
| /**********************************/ |
| /* TIME OUT CHEKC api*/ |
| /**********************************/ |
| |
| void div3_tout_int(struct di_time_out_s *tout, unsigned int thd) |
| { |
| tout->en = false; |
| tout->timer_start = 0; |
| tout->timer_thd = thd; |
| } |
| |
| bool div3_tout_contr(enum eDI_TOUT_CONTR cmd, struct di_time_out_s *tout) |
| { |
| unsigned long ctimer; |
| unsigned long diff; |
| bool ret = false; |
| |
| ctimer = curv3_to_msecs(); |
| |
| switch (cmd) { |
| case eDI_TOUT_CONTR_EN: |
| tout->en = true; |
| tout->timer_start = ctimer; |
| break; |
| case eDI_TOUT_CONTR_FINISH: |
| if (tout->en) { |
| diff = ctimer - tout->timer_start; |
| |
| if (diff > tout->timer_thd) { |
| tout->over_flow_cnt++; |
| |
| if (tout->over_flow_cnt > 0xfffffff0) { |
| tout->over_flow_cnt = 0; |
| tout->flg_over = 1; |
| } |
| #if 0 |
| if (tout->do_func) |
| tout->do_func(); |
| |
| #endif |
| ret = true; |
| } |
| tout->en = false; |
| } |
| break; |
| |
| case eDI_TOUT_CONTR_CHECK: /*if time is overflow, disable timer*/ |
| if (tout->en) { |
| diff = ctimer - tout->timer_start; |
| |
| if (diff > tout->timer_thd) { |
| tout->over_flow_cnt++; |
| |
| if (tout->over_flow_cnt > 0xfffffff0) { |
| tout->over_flow_cnt = 0; |
| tout->flg_over = 1; |
| } |
| #if 0 |
| if (tout->do_func) |
| tout->do_func(); |
| |
| #endif |
| ret = true; |
| tout->en = false; |
| } |
| } |
| break; |
| case eDI_TOUT_CONTR_CLEAR: |
| tout->en = false; |
| tout->timer_start = ctimer; |
| break; |
| case eDI_TOUT_CONTR_RESET: |
| tout->en = true; |
| tout->timer_start = ctimer; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| const unsigned int div3_ch2mask_table[DI_CHANNEL_MAX] = { |
| DI_BIT0, |
| DI_BIT1, |
| DI_BIT2, |
| DI_BIT3, |
| }; |
| /**************************************** |
| *bit control |
| ****************************************/ |
| static const unsigned int bit_tab[32] = { |
| DI_BIT0, |
| DI_BIT1, |
| DI_BIT2, |
| DI_BIT3, |
| DI_BIT4, |
| DI_BIT5, |
| DI_BIT6, |
| DI_BIT7, |
| DI_BIT8, |
| DI_BIT9, |
| DI_BIT10, |
| DI_BIT11, |
| DI_BIT12, |
| DI_BIT13, |
| DI_BIT14, |
| DI_BIT15, |
| DI_BIT16, |
| DI_BIT17, |
| DI_BIT18, |
| DI_BIT19, |
| DI_BIT20, |
| DI_BIT21, |
| DI_BIT22, |
| DI_BIT23, |
| DI_BIT24, |
| DI_BIT25, |
| DI_BIT26, |
| DI_BIT27, |
| DI_BIT28, |
| DI_BIT29, |
| DI_BIT30, |
| DI_BIT31 |
| }; |
| |
| void bsetv3(unsigned int *p, unsigned int bitn) |
| { |
| *p = *p | bit_tab[bitn]; |
| } |
| |
| void bclrv3(unsigned int *p, unsigned int bitn) |
| { |
| *p = *p & (~bit_tab[bitn]); |
| } |
| |
| bool bgetv3(unsigned int *p, unsigned int bitn) |
| { |
| return (*p & bit_tab[bitn]) ? true : false; |
| } |
| |
| /****************************************/ |
| /* do_table */ |
| /****************************************/ |
| |
| /*for do_table_working*/ |
| #define K_DO_TABLE_LOOP_MAX 15 |
| |
| const struct do_table_s dov3_table_def = { |
| .ptab = NULL, |
| .data = NULL, |
| .size = 0, |
| .op_lst = K_DO_TABLE_ID_STOP, |
| .op_crr = K_DO_TABLE_ID_STOP, |
| .do_stop = 0, |
| .flg_stop = 0, |
| .do_pause = 0, |
| .do_step = 0, |
| .flg_repeat = 0, |
| |
| }; |
| |
| void dov3_table_init(struct do_table_s *pdo, |
| const struct do_table_ops_s *ptable, |
| unsigned int size_tab) |
| { |
| memcpy(pdo, &dov3_table_def, sizeof(struct do_table_s)); |
| |
| if (ptable) { |
| pdo->ptab = ptable; |
| pdo->size = size_tab; |
| } |
| } |
| |
| /*if change to async?*/ |
| /* now only call in same thread */ |
| void dov3_talbe_cmd(struct do_table_s *pdo, enum eDO_TABLE_CMD cmd) |
| { |
| switch (cmd) { |
| case eDO_TABLE_CMD_NONE: |
| PR_INF("test:%s\n", __func__); |
| break; |
| case eDO_TABLE_CMD_STOP: |
| pdo->do_stop = true; |
| break; |
| case eDO_TABLE_CMD_START: |
| if (pdo->op_crr == K_DO_TABLE_ID_STOP) { |
| pdo->op_lst = pdo->op_crr; |
| pdo->op_crr = K_DO_TABLE_ID_START; |
| pdo->do_stop = false; |
| pdo->flg_stop = false; |
| } else if (pdo->op_crr == K_DO_TABLE_ID_PAUSE) { |
| pdo->op_crr = pdo->op_lst; |
| pdo->op_lst = K_DO_TABLE_ID_PAUSE; |
| pdo->do_pause = false; |
| } else { |
| PR_INF("crr is [%d], not start\n", pdo->op_crr); |
| } |
| break; |
| case eDO_TABLE_CMD_PAUSE: |
| if (pdo->op_crr <= K_DO_TABLE_ID_STOP) { |
| /*do nothing*/ |
| } else { |
| pdo->op_lst = pdo->op_crr; |
| pdo->op_crr = K_DO_TABLE_ID_PAUSE; |
| pdo->do_pause = true; |
| } |
| break; |
| case eDO_TABLE_CMD_STEP: |
| pdo->do_step = true; |
| break; |
| case eDO_TABLE_CMD_STEP_BACK: |
| pdo->do_step = false; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| bool dov3_table_is_crr(struct do_table_s *pdo, unsigned int state) |
| { |
| if (pdo->op_crr == state) |
| return true; |
| return false; |
| } |
| |
| void dov3_table_working(struct do_table_s *pdo) |
| { |
| const struct do_table_ops_s *pcrr; |
| unsigned int ret = 0; |
| unsigned int next; |
| bool flash = false; |
| unsigned int cnt = 0; /*proction*/ |
| unsigned int lst_id; /*dbg only*/ |
| char *name = ""; /*dbg only*/ |
| bool need_pr = false; /*dbg only*/ |
| |
| if (!pdo || !pdo->ptab) { |
| PR_ERR("no pdo or ptab\n"); |
| return; |
| } |
| |
| if (pdo->op_crr >= pdo->size) { |
| PR_ERR("di:err:%s:crr=%d,size=%d\n", |
| __func__, |
| pdo->op_crr, |
| pdo->size); |
| return; |
| } |
| |
| pcrr = pdo->ptab + pdo->op_crr; |
| |
| if (pdo->name) |
| name = pdo->name; |
| /*stop ?*/ |
| if (pdo->do_stop && |
| (pcrr->mark & K_DO_TABLE_CAN_STOP)) { |
| dbg_dt("%s:do stop\n", name); |
| |
| /*do stop*/ |
| if (pcrr->do_stop_op) |
| pcrr->do_stop_op(pdo->data); |
| /*set status*/ |
| pdo->op_lst = pdo->op_crr; |
| pdo->op_crr = K_DO_TABLE_ID_STOP; |
| pdo->flg_stop = true; |
| pdo->do_stop = false; |
| |
| return; |
| } |
| |
| /*pause?*/ |
| if (pdo->op_crr == K_DO_TABLE_ID_STOP || |
| pdo->op_crr == K_DO_TABLE_ID_PAUSE) |
| return; |
| |
| do { |
| flash = false; |
| cnt++; |
| if (cnt > K_DO_TABLE_LOOP_MAX) { |
| PR_ERR("di:err:%s:loop more %d\n", name, cnt); |
| break; |
| } |
| |
| /*stop again? */ |
| if (pdo->do_stop && |
| (pcrr->mark & K_DO_TABLE_CAN_STOP)) { |
| /*do stop*/ |
| dbg_dt("%s: do stop in loop\n", name); |
| if (pcrr->do_stop_op) |
| pcrr->do_stop_op(pdo->data); |
| /*set status*/ |
| pdo->op_lst = pdo->op_crr; |
| pdo->op_crr = K_DO_TABLE_ID_STOP; |
| pdo->flg_stop = true; |
| pdo->do_stop = false; |
| |
| break; |
| } |
| |
| /*debug:*/ |
| lst_id = pdo->op_crr; |
| need_pr = true; |
| |
| if (pcrr->con) { |
| if (pcrr->con(pdo->data)) |
| ret = pcrr->do_op(pdo->data); |
| else |
| break; |
| |
| } else { |
| ret = pcrr->do_op(pdo->data); |
| dbg_dt("do_table:do:%d:ret=0x%x\n", pcrr->id, ret); |
| } |
| |
| /*not finish, keep current status*/ |
| if ((ret & K_DO_TABLE_R_B_FINISH) == 0) { |
| dbg_dt("%s:not finish,wait\n", __func__); |
| break; |
| } |
| |
| /*fix to next */ |
| if (ret & K_DO_TABLE_R_B_NEXT) { |
| pdo->op_lst = pdo->op_crr; |
| pdo->op_crr++; |
| if (pdo->op_crr >= pdo->size) { |
| pdo->op_crr = pdo->flg_repeat ? |
| K_DO_TABLE_ID_START |
| : K_DO_TABLE_ID_STOP; |
| dbg_dt("%s:to end,%d\n", __func__, |
| pdo->op_crr); |
| break; |
| } |
| /*return;*/ |
| flash = true; |
| } else { |
| next = ((ret & K_DO_TABLE_R_B_OTHER) >> |
| K_DO_TABLE_R_B_OTHER_SHIFT); |
| if (next < pdo->size) { |
| pdo->op_lst = pdo->op_crr; |
| pdo->op_crr = next; |
| if (next > K_DO_TABLE_ID_STOP) |
| flash = true; |
| else |
| flash = false; |
| } else { |
| PR_ERR("%s: next[%d] err:\n", |
| __func__, next); |
| } |
| } |
| /*debug 1:*/ |
| need_pr = false; |
| if (lst_id != pdo->op_crr) { |
| dbg_dt("do_table:%s:%s->%s\n", pdo->name, |
| pdo->ptab[lst_id].name, |
| pdo->ptab[pdo->op_crr].name); |
| } |
| |
| pcrr = pdo->ptab + pdo->op_crr; |
| } while (flash && !pdo->do_step); |
| |
| /*debug 2:*/ |
| if (need_pr) { |
| if (lst_id != pdo->op_crr) { |
| dbg_dt("do_table2:%s:%s->%s\n", pdo->name, |
| pdo->ptab[lst_id].name, |
| pdo->ptab[pdo->op_crr].name); |
| } |
| } |
| } |
| |
| /******************************************************************** |
| * dvfm |
| *******************************************************************/ |
| void dvfm_prob(struct di_ch_s *pch) |
| { |
| int i; |
| struct dim_dvfm_s *pdvfm; |
| |
| if (!pch) |
| return; |
| |
| for (i = 0; i < DIM_K_VFM_NUM; i++) { |
| pdvfm = &pch->dvfm[i]; |
| /*clear*/ |
| memset(pdvfm, 0, sizeof(*pdvfm)); |
| |
| /*set code*/ |
| // pdvfm->code_name = DIM_K_CODE_DVFM; |
| pdvfm->index = i; |
| } |
| } |
| |
| void dvfm_reg(struct di_ch_s *pch) |
| { |
| dvfm_prob(pch); |
| } |
| |
| struct dim_dvfm_s *dvfmv3_get(struct di_ch_s *pch, enum QUED_TYPE qtype) |
| { |
| struct dim_dvfm_s *pdvfm; |
| unsigned int dvfm_id; |
| bool ret; |
| |
| if (!pch) { |
| PR_ERR("%s:p is null\n", __func__); |
| return NULL; |
| } |
| |
| ret = qued_ops.out(pch, qtype, &dvfm_id); |
| |
| if (!ret || |
| dvfm_id >= DIM_K_VFM_NUM) { |
| PR_ERR("%s:ch[%d]:que:%s:get failed:ret[%d],id[0x%x]\n", |
| __func__, |
| pch->ch_id, |
| qued_ops.get_name(pch, qtype), |
| ret, dvfm_id); |
| return NULL; |
| } |
| |
| pdvfm = &pch->dvfm[dvfm_id]; |
| if (!pdvfm) |
| return NULL; |
| |
| return pdvfm; |
| } |
| |
| struct dim_dvfm_s *dvfmv3_peek(struct di_ch_s *pch, enum QUED_TYPE qtype) |
| { |
| struct dim_dvfm_s *pdvfm; |
| unsigned int dvfm_id; |
| bool ret; |
| |
| if (!pch) { |
| PR_ERR("%s:p is null\n", __func__); |
| return NULL; |
| } |
| |
| ret = qued_ops.peek(pch, qtype, &dvfm_id); |
| |
| if (ret && dvfm_id >= DIM_K_VFM_NUM) { |
| PR_ERR("%s:ch[%d]:que:%s:get failed:ret[%d],id[%d]\n", |
| __func__, |
| pch->ch_id, |
| qued_ops.get_name(pch, qtype), |
| ret, dvfm_id); |
| return NULL; |
| } |
| |
| if (!ret) /*empty*/ |
| pdvfm = NULL; |
| else |
| pdvfm = &pch->dvfm[dvfm_id]; |
| |
| return pdvfm; |
| } |
| |
| #define VFM_NEED_BYPASS (VIDTYPE_MVC | \ |
| VIDTYPE_VIU_444 | \ |
| VIDTYPE_PIC) |
| |
| /* for dvfm_fill_in use*/ |
| bool dimv3_need_bypass2(struct di_in_inf_s *in_inf, struct vframe_s *vf) |
| { |
| struct di_mm_s *mm; |
| |
| if (!in_inf || !vf) |
| return true; |
| |
| mm = dim_mm_get(in_inf->ch); |
| |
| if (!mm) |
| return true; |
| |
| /*vfm type*/ |
| if (vf->type & VFM_NEED_BYPASS) |
| return true; |
| if (vf->source_type == VFRAME_SOURCE_TYPE_PPMGR) |
| return true; |
| #if 1 |
| if (vfv3_type_is_prog(vf->type)) {/*temp bypass p*/ |
| return true; |
| } |
| #endif |
| /*true bypass for 720p above*/ |
| if ((vf->flag & VFRAME_FLAG_GAME_MODE) && |
| (vf->width > 720)) |
| return true; |
| /*support G12A and TXLX platform*/ |
| if (vf->type & VIDTYPE_COMPRESS) { |
| if (!dimhv3_afbc_is_supported()) |
| return true; |
| } |
| |
| if ((in_inf->w > mm->cfg.di_w) || |
| (in_inf->h > mm->cfg.di_h)) |
| return true; |
| |
| if ((dimp_get(eDI_MP_di_debug_flag) >> 20) & 0x1) |
| return true; |
| |
| return false; |
| } |
| |
| void dimv3_polic_cfg(unsigned int cmd, bool on) |
| { |
| //struct dim_policy_s *pp; |
| #ifdef TST_NEW_INS_RUN_Q |
| if (dil_get_diffver_flag() != 1) |
| return; |
| #endif |
| #if 0 |
| pp = get_dpolicy(); |
| switch (cmd) { |
| case K_DIM_BYPASS_CLEAR_ALL: |
| pp->cfg_d32 = 0x0; |
| break; |
| case K_DIM_I_FIRST: |
| pp->cfg_b.i_first = on; |
| break; |
| case K_DIM_BYPASS_ALL_P: |
| pp->cfg_b.bypass_all_p = on; |
| break; |
| default: |
| PR_WARN("%s:cmd is overflow[%d]\n", __func__, cmd); |
| break; |
| } |
| #endif |
| } |
| EXPORT_SYMBOL(dimv3_polic_cfg); |
| |
| unsigned int dimv3_get_trick_mode(void) |
| { |
| unsigned int trick_mode; |
| |
| if (dimp_get(eDI_MP_bypass_trick_mode)) { |
| int trick_mode_fffb = 0; |
| int trick_mode_i = 0; |
| |
| if (dimp_get(eDI_MP_bypass_trick_mode) & 0x1) |
| query_video_status(0, &trick_mode_fffb); |
| if (dimp_get(eDI_MP_bypass_trick_mode) & 0x2) |
| query_video_status(1, &trick_mode_i); |
| trick_mode = |
| trick_mode_fffb | (trick_mode_i << 1); |
| |
| return trick_mode; |
| } |
| return 0; |
| } |
| /********************************** |
| *diff with dim_is_bypass |
| * delet di_vscale_skip_enable |
| * use vf_in replace ppre |
| * for dvfm_fill_in |
| **********************************/ |
| bool isv3_bypass2(struct vframe_s *vf_in, struct di_ch_s *pch, |
| unsigned int *reason) |
| { |
| if (div3_cfgx_get(pch->ch_id, eDI_CFGX_BYPASS_ALL)) { |
| *reason = 1; |
| return true; |
| } |
| #if 0 |
| /*?*/ |
| if (dimp_get(eDI_MP_bypass_trick_mode)) { |
| int trick_mode_fffb = 0; |
| int trick_mode_i = 0; |
| |
| if (dimp_get(eDI_MP_bypass_trick_mode) & 0x1) |
| query_video_status(0, &trick_mode_fffb); |
| if (dimp_get(eDI_MP_bypass_trick_mode) & 0x2) |
| query_video_status(1, &trick_mode_i); |
| pdvfm->wmode.trick_mode = |
| trick_mode_fffb | (trick_mode_i << 1); |
| if (pdvfm->wmode.trick_mode) |
| return true; |
| } |
| #endif |
| /* check vframe */ |
| //vf_in = pdvfm->vfm_in; |
| if (!vf_in) |
| return false; |
| |
| if ((vf_in->width < 16) || (vf_in->height < 16)) { |
| *reason = 2; |
| return true; |
| } |
| |
| if (dimp_get(eDI_MP_bypass_3d) && |
| (vf_in->trans_fmt != 0)) { |
| *reason = 3; |
| return true; |
| } |
| |
| /*prot is conflict with di post*/ |
| if (vf_in->video_angle) { |
| *reason = 4; |
| return true; |
| } |
| |
| return false; |
| } |
| |
| void dimv3_reg_cfg_sys(struct di_ch_s *pch) |
| { |
| //struct di_data_l_s *pdata = get_datal(void) |
| bool bit10_pack_patch = false; |
| unsigned int width_roundup = 2; |
| struct di_mng_s *pbm = get_bufmng(); |
| unsigned int ch; |
| |
| if (!pch) |
| return; |
| |
| /*set width_roundup*/ |
| bit10_pack_patch = (is_meson_gxtvbb_cpu() || |
| is_meson_gxl_cpu() || |
| is_meson_gxm_cpu()); |
| |
| pch->cfgt.w_rdup = bit10_pack_patch ? 16 : width_roundup; |
| |
| /*set force_w | force_h*/ |
| pch->cfgt.f_w = dimp_get(eDI_MP_force_width); |
| pch->cfgt.f_h = dimp_get(eDI_MP_force_height); |
| if (dimp_get(eDI_MP_di_force_bit_mode) == 10) { |
| if (pch->cfgt.f_w) { |
| pch->cfgt.f_w = |
| roundup(pch->cfgt.f_w, width_roundup); |
| } |
| } |
| |
| if (dimp_get(eDI_MP_di_force_bit_mode) == 10) { |
| pch->cfgt.vfm_bitdepth = (BITDEPTH_Y10); |
| if (dimp_get(eDI_MP_full_422_pack)) |
| pch->cfgt.vfm_bitdepth |= (FULL_PACK_422_MODE); |
| } else { |
| pch->cfgt.vfm_bitdepth = (BITDEPTH_Y8); |
| } |
| |
| pch->cfgt.ens.en_32 = 0; |
| if (dimp_get(eDI_MP_pre_hsc_down_en)) |
| pch->cfgt.ens.b.h_sc_down = 1; |
| |
| if (dimp_get(eDI_MP_pps_en)) |
| pch->cfgt.ens.b.pps_enable = 1; |
| |
| if (cfgg(PMODE) == 2) { /*use 2 i buf*/ |
| dimp_set(eDI_MP_prog_proc_config, 0x03); |
| } |
| |
| /*tmode*/ |
| ch = pch->ch_id; |
| pch->cfgt.tmode = pbm->tmode_pre[ch]; |
| } |
| |
| unsigned int topv3_bot_config(unsigned int vtype) |
| { |
| unsigned int vfm_type = vtype; |
| |
| if ((vfm_type & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP) { |
| vfm_type &= (~VIDTYPE_TYPEMASK); |
| vfm_type |= VIDTYPE_INTERLACE_BOTTOM; |
| } else { |
| vfm_type &= (~VIDTYPE_TYPEMASK); |
| vfm_type |= VIDTYPE_INTERLACE_TOP; |
| } |
| return vfm_type; |
| } |
| |
| void dvfmv3_recycle(struct di_ch_s *pch) |
| { |
| int i; |
| struct dim_dvfm_s *pdvfm; |
| unsigned int back_in; |
| |
| for (i = 0; i < DIM_K_VFM_NUM; i++) { |
| pdvfm = dvfmv3_peek(pch, QUED_T_RECYCL); |
| if (!pdvfm) |
| break; |
| pdvfm = dvfmv3_get(pch, QUED_T_RECYCL); |
| // back_c = pdvfm->code_name; |
| back_in = pdvfm->index; |
| |
| memset(pdvfm, 0, sizeof(*pdvfm)); |
| // pdvfm->code_name = back_c; |
| pdvfm->index = back_in; |
| qued_ops.in(pch, QUED_T_FREE, pdvfm->index); |
| } |
| } |
| |
| /****************************/ |
| void dipv3_init_value_reg(unsigned int ch) |
| { |
| struct di_post_stru_s *ppost; |
| // struct di_buf_s *keep_post_buf; |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| struct di_ch_s *pch = get_chdata(ch); |
| // struct di_data_l_s *pdt = get_datal(); |
| // struct dim_dvfm_s *pdvfm; |
| int i; |
| |
| if (!pch) |
| return; |
| |
| PR_INF("%s:\n", __func__); |
| |
| /*post*/ |
| ppost = get_post_stru(ch); |
| /*keep buf:*/ |
| /*keep_post_buf = ppost->keep_buf_post;*/ |
| |
| memset(ppost, 0, sizeof(struct di_post_stru_s)); |
| ppost->next_canvas_id = 1; |
| |
| /*pre*/ |
| memset(ppre, 0, sizeof(struct di_pre_stru_s)); |
| |
| /*clear dvfm*/ |
| dvfm_reg(pch); |
| |
| /*qued*/ |
| qued_ops.reg(pch); |
| |
| /*put all dvfm to free*/ |
| for (i = 0; i < DIM_K_VFM_NUM; i++) |
| qued_ops.in(pch, QUED_T_FREE, i); |
| |
| if ((pch->interf.tmode == EDIM_TMODE_2_PW_OUT || |
| pch->interf.tmode == EDIM_TMODE_3_PW_LOCAL)) { |
| /*que buf*/ |
| for (i = 0; i < DIM_K_BUF_IN_LIMIT; i++) |
| qued_ops.in(pch, QUED_T_IS_FREE, i); |
| |
| for (i = 0; i < DIM_K_BUF_OUT_LIMIT; i++) |
| qued_ops.in(pch, QUED_T_IS_PST_FREE, i); |
| } else { |
| PR_INF("%s:tmod[%d]\n", __func__, pch->interf.tmode); |
| } |
| /*last dvfm*/ |
| memset(&pch->lst_dvfm, 0, sizeof(struct dim_dvfm_s)); |
| |
| di_bypass_state_set(ch, false); |
| } |
| |
| static bool dip_init_value(void) /*call in prob*/ |
| { |
| unsigned int ch; |
| struct di_post_stru_s *ppost; |
| struct di_mm_s *mm;// = dim_mm_get(); |
| struct dim_mm_t_s *mmt = dim_mmt_get(); |
| //struct di_data_l_s *pdata = get_datal(); |
| struct di_ch_s *pch; |
| bool ret = false; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| /*ch_data*/ |
| pch = get_chdata(ch); |
| pch->ch_id = ch; |
| |
| /*ppost*/ |
| ppost = get_post_stru(ch); |
| memset(ppost, 0, sizeof(struct di_post_stru_s)); |
| ppost->next_canvas_id = 1; |
| |
| /*que*/ |
| ret = div3_que_alloc(ch); |
| if (ret) { |
| pwv3_queue_clear(ch, QUE_POST_KEEP); |
| pwv3_queue_clear(ch, QUE_POST_KEEP_BACK); |
| } |
| |
| mm = dim_mm_get(ch); |
| |
| memcpy(&mm->cfg, &c_mm_cfg_normal, sizeof(struct di_mm_cfg_s)); |
| |
| /*qued*/ |
| qued_ops.prob(pch); |
| |
| /*dvfm*/ |
| dvfm_prob(pch); |
| } |
| /*mmm top*/ |
| mmt->mem_start = 0; |
| mmt->mem_size = 0; |
| mmt->total_pages = NULL; |
| set_current_channel(0); |
| |
| return ret; |
| } |
| |
| /****************************************** |
| * pq ops |
| *****************************************/ |
| void dipv3_init_pq_ops(void) |
| { |
| di_attach_ops_pulldown(&get_datal()->ops_pd); |
| di_attach_ops_3d(&get_datal()->ops_3d); |
| di_attach_ops_nr(&get_datal()->ops_nr); |
| di_attach_ops_mtn(&get_datal()->ops_mtn); |
| |
| dimv3_attach_to_local(); |
| } |
| |
| /**********************************/ |
| void dipv3_clean_value(void) |
| { |
| unsigned int ch; |
| struct di_data_l_s *pdt = get_datal(); |
| struct di_ch_s *pch; |
| |
| if (!pdt) |
| return; |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| /*que*/ |
| div3_que_release(ch); |
| |
| /*qued*/ |
| pch = get_chdata(ch); |
| qued_ops.remove(pch); |
| } |
| } |
| |
| bool dipv3_prob(void) |
| { |
| bool ret = true; |
| |
| ret = dip_init_value(); |
| |
| div3_cfgx_init_val(); |
| div3_cfg_top_init_val(); |
| div3_mp_uit_init_val(); |
| div3_mp_uix_init_val(); |
| |
| dimv3_tmode_preset(); /*need before vframe*/ |
| |
| devv3_vframe_init(); |
| didbgv3_fs_init(); |
| dip_wq_prob(); |
| dip_cma_init_val(); |
| dipv3_chst_init(); |
| |
| dprev3_init(); |
| dpostv3_init(); |
| |
| hprev3_prob(); |
| dipv3_init_pq_ops(); |
| |
| |
| return ret; |
| } |
| |
| void dipv3_exit(void) |
| { |
| dip_wq_ext(); |
| devv3_vframe_exit(); |
| dipv3_clean_value(); |
| didbgv3_fs_exit(); |
| } |
| |