From 7e77e276d6b64fc86358d323df3bb7aec33255ab Mon Sep 17 00:00:00 2001 From: "qianqian.cai" Date: Thu, 28 Dec 2023 16:45:17 +0800 Subject: [PATCH] deinterlace: di backend for new interface [1/1] PD#SWPL-146509 Problem: add new interface for di back Solution: 1.add api for release buffer when unreg/reg 2.add api for post/pre num Verify: sc2 Change-Id: Ie1eadc81751b3ca6da2d1f337e94d54dc1455c6c Signed-off-by: qianqian.cai --- drivers/media/di_local/di_local.c | 9 +++++++++ drivers/media/di_local/di_local.h | 1 + drivers/media/di_multi/deinterlace.c | 11 ++++++++--- drivers/media/di_multi/di_api.c | 3 ++- drivers/media/di_multi/di_data_l.h | 3 +++ drivers/media/di_multi/di_interface.c | 18 ++++++++++++++++++ drivers/media/di_multi/di_prc.c | 12 +++++++++++- drivers/media/di_multi/di_prc.h | 1 + drivers/media/di_multi/di_task.c | 8 ++++++-- include/linux/amlogic/media/di/di_interface.h | 11 +++++++++++ 10 files changed, 70 insertions(+), 7 deletions(-) diff --git a/drivers/media/di_local/di_local.c b/drivers/media/di_local/di_local.c index cbbfa55fa..dcc3bb60d 100644 --- a/drivers/media/di_local/di_local.c +++ b/drivers/media/di_local/di_local.c @@ -251,6 +251,15 @@ int di_release_keep_buf(struct di_buffer *buffer) } EXPORT_SYMBOL(di_release_keep_buf); +int di_set_buffer_num(unsigned int post, unsigned int pre) +{ + if (dil_api && dil_api->set_buffer_num) + return dil_api->set_buffer_num(post, pre); + PR_ERR("%s:not attach\n", __func__); + return 0; +} +EXPORT_SYMBOL(di_set_buffer_num); + int di_get_output_buffer_num(int index) { if (dil_api && dil_api->new_get_output_buffer_num) diff --git a/drivers/media/di_local/di_local.h b/drivers/media/di_local/di_local.h index 956f61c15..43feb06ed 100644 --- a/drivers/media/di_local/di_local.h +++ b/drivers/media/di_local/di_local.h @@ -54,6 +54,7 @@ struct di_ext_ops { int (*s_bypass_ch)(int index, bool on); unsigned int (*get_vpu_clkb_ext)(void); bool (*is_pre_link)(void); + int (*set_buffer_num)(unsigned int post, unsigned int pre); }; #endif /*__DI_LOCAL_H__*/ diff --git a/drivers/media/di_multi/deinterlace.c b/drivers/media/di_multi/deinterlace.c index f1af6daab..7bb891c8d 100644 --- a/drivers/media/di_multi/deinterlace.c +++ b/drivers/media/di_multi/deinterlace.c @@ -3064,7 +3064,7 @@ void dim_post_keep_cmd_proc(unsigned int ch, unsigned int index) *so FCC switch channel, the other two channel not work but also has di buffer. *We need free the buffer when EDI_TOP_STATE_REG_STEP1 (reg but no vf) */ - if (mm->fcc_value) + if (mm->fcc_value || pch->sts_keep) dim_post_keep_release_one_check(ch, index); else ndkb_qin_byidx(pch, index); @@ -5181,7 +5181,7 @@ static void re_build_buf(struct di_ch_s *pch, enum EDI_SGN sgn) struct mtsk_cmd_s blk_cmd; unsigned int ch; unsigned int release_post = 0, length_keep = 0; - unsigned int post_nub; + unsigned int post_nub, pre_nub; if (sgn == EDI_SGN_4K) is_4k = true; @@ -5211,6 +5211,10 @@ static void re_build_buf(struct di_ch_s *pch, enum EDI_SGN sgn) if (post_nub && post_nub < POST_BUF_NUM) mm->cfg.num_post = post_nub; + pre_nub = cfgg(PRE_NUB); + if (pre_nub && pre_nub < POST_BUF_NUM) + mm->cfg.num_local = pre_nub; + if (pch->ponly && dip_is_ponly_sct_mem(pch)) mm->cfg.dis_afbce = 0; else if (cfggch(pch, POUT_FMT) <= 2) @@ -10922,6 +10926,7 @@ void di_unreg_variable(unsigned int channel) pch->sumx.need_local = 0; pch->self_trig_need = 0; pch->rsc_bypass.d32 = 0; + pch->sts_keep = 0; #ifdef CONFIG_AMLOGIC_MEDIA_THERMAL pch->record_10bit_flag = 0; pch->record_8bit_flag = 0; @@ -11995,7 +12000,7 @@ bool dim_pre_link_state(void) if (IS_ERR_OR_NULL(de_devp)) return false; - if (DIM_IS_IC_BF(SC2)) + if (DIM_IS_IC_BF(T5) || DIM_IS_IC(T5D)) return false; return (cfgg(EN_PRE_LINK) && IS_IC_SUPPORT(PRE_VPP_LINK)); } diff --git a/drivers/media/di_multi/di_api.c b/drivers/media/di_multi/di_api.c index 45d85dfde..6d478a6d0 100644 --- a/drivers/media/di_multi/di_api.c +++ b/drivers/media/di_multi/di_api.c @@ -48,7 +48,8 @@ static const struct di_ext_ops di_ext = { .pre_vpp_link_sw = dpvpp_sw, .pre_vpp_get_ins_id = dpvpp_get_ins_id, .get_vpu_clkb_ext = dim_get_vpu_clk_ext, - .is_pre_link = dim_pre_link_state + .is_pre_link = dim_pre_link_state, + .set_buffer_num = set_buffer_num }; void dim_attach_to_local(void) diff --git a/drivers/media/di_multi/di_data_l.h b/drivers/media/di_multi/di_data_l.h index 8250e48a5..b3a40ffa1 100644 --- a/drivers/media/di_multi/di_data_l.h +++ b/drivers/media/di_multi/di_data_l.h @@ -176,6 +176,7 @@ enum EDI_CFG_TOP_IDX { #ifdef CONFIG_AMLOGIC_MEDIA_THERMAL EDI_CFG_TEMP_CONTROL, #endif + EDI_CFG_PRE_NUB, EDI_CFG_END, }; @@ -2093,6 +2094,8 @@ struct di_ch_s { unsigned int cur_index; unsigned int switch_index; #endif + unsigned int sts_keep : 1, + rev : 31; }; struct dim_policy_s { diff --git a/drivers/media/di_multi/di_interface.c b/drivers/media/di_multi/di_interface.c index c6c8bc0b5..afe59ef71 100644 --- a/drivers/media/di_multi/di_interface.c +++ b/drivers/media/di_multi/di_interface.c @@ -493,6 +493,7 @@ int new_create_instance(struct di_init_parm parm) pch->sum_reg_cnt++; dim_api_reg(DIME_REG_MODE_NEW, pch); npst_reset(pch); + pch->sts_keep = parm.buffer_keep; pch->itf.opins_m_back_in = nins_m_recycle_ins; pch->itf.op_m_unreg = nins_m_unreg_new; pch->ponly_set = false; @@ -868,6 +869,23 @@ int new_release_keep_buf(struct di_buffer *buffer) return 0; } +/********************************************************** + * @brief set_buffer_num + * + * @param[in] set buffer number pre/post + * + * @return number or fail type + *********************************************************/ +int set_buffer_num(unsigned int post, unsigned int pre) +{ + dbg_reg("%s:%d,%d\n", __func__, post, pre); + if (post) + cfgs(POST_NUB, post); + if (pre) + cfgs(PRE_NUB, pre); + return 0; +} + /********************************************************** * @brief di_get_output_buffer_num get output buffer num * diff --git a/drivers/media/di_multi/di_prc.c b/drivers/media/di_multi/di_prc.c index 7cc10b491..736651570 100644 --- a/drivers/media/di_multi/di_prc.c +++ b/drivers/media/di_multi/di_prc.c @@ -297,6 +297,12 @@ const struct di_cfg_ctr_s di_cfg_top_ctr[K_DI_CFG_NUB] = { 0, K_DI_CFG_T_FLG_DTS}, #endif + [EDI_CFG_PRE_NUB] = {"pre_nub", + /* 0:not config pre nub;*/ + EDI_CFG_PRE_NUB, + 5, + K_DI_CFG_T_FLG_DTS}, + [EDI_CFG_END] = {"cfg top end ", EDI_CFG_END, 0, K_DI_CFG_T_FLG_NONE}, @@ -3155,7 +3161,7 @@ void dip_init_value_reg(unsigned int ch, struct vframe_s *vframe) struct di_ch_s *pch = get_chdata(ch); struct div2_mm_s *mm; enum EDI_SGN sgn; - unsigned int post_nub; + unsigned int post_nub, pre_nub; bool ponly_enable = false; bool ponly_by_firstp = false; @@ -3272,6 +3278,10 @@ void dip_init_value_reg(unsigned int ch, struct vframe_s *vframe) else mm->cfg.fix_buf = 0; + pre_nub = cfgg(PRE_NUB); + if ((pre_nub) && pre_nub <= MAX_LOCAL_BUF_NUM) + mm->cfg.num_local = pre_nub; + if (pch->ponly) mm->cfg.num_local = 0; diff --git a/drivers/media/di_multi/di_prc.h b/drivers/media/di_multi/di_prc.h index 1a4ba7594..f356884f0 100644 --- a/drivers/media/di_multi/di_prc.h +++ b/drivers/media/di_multi/di_prc.h @@ -591,6 +591,7 @@ int new_destroy_instance(int index); enum DI_ERRORTYPE new_empty_input_buffer(int index, struct di_buffer *buffer); enum DI_ERRORTYPE new_fill_output_buffer(int index, struct di_buffer *buffer); int new_release_keep_buf(struct di_buffer *buffer); +int set_buffer_num(unsigned int post, unsigned int pre); int new_get_output_buffer_num(int index); int new_get_input_buffer_num(int index); bool dim_get_overturn(void); diff --git a/drivers/media/di_multi/di_task.c b/drivers/media/di_multi/di_task.c index c1b5992d9..20ce90fca 100644 --- a/drivers/media/di_multi/di_task.c +++ b/drivers/media/di_multi/di_task.c @@ -220,8 +220,11 @@ void task_polling_cmd_keep(unsigned int ch, unsigned int top_sts) // if (pbm->cma_flg_run) // return; + pch = get_chdata(ch); + if (IS_ERR_OR_NULL(pch)) + return; if (top_sts == EDI_TOP_STATE_READY) { - pch = get_chdata(ch); + //pch = get_chdata(ch); mem_cfg_realloc(pch); mem_cfg_pst(pch);//2020-12-17 //mem_cfg_realloc_wait(pch); @@ -238,7 +241,8 @@ void task_polling_cmd_keep(unsigned int ch, unsigned int top_sts) if (top_sts != EDI_TOP_STATE_IDLE && top_sts != EDI_TOP_STATE_READY && top_sts != EDI_TOP_STATE_BYPASS && - (top_sts != EDI_TOP_STATE_REG_STEP1 || !mm->fcc_value)) + (top_sts != EDI_TOP_STATE_REG_STEP1 || !mm->fcc_value || + !pch->sts_keep)) return; //ary 2020-12-09 spin_lock_irqsave(&plist_lock, flags); diff --git a/include/linux/amlogic/media/di/di_interface.h b/include/linux/amlogic/media/di/di_interface.h index f0f8d3539..f9320b62b 100644 --- a/include/linux/amlogic/media/di/di_interface.h +++ b/include/linux/amlogic/media/di/di_interface.h @@ -132,6 +132,8 @@ struct di_init_parm { struct di_operations_s ops; void *caller_data; enum di_output_format output_format; + unsigned int buffer_keep : 1, + rev : 31; }; struct di_status { @@ -213,6 +215,15 @@ int di_write(struct di_buffer *buffer, struct composer_dst *dst); */ int di_release_keep_buf(struct di_buffer *buffer); +/** + * @brief di_set_buffer_num + * + * @param[in] number pre/post + * + * @return 0 for success, or fail type if < 0 + */ +int di_set_buffer_num(unsigned int post, unsigned int pre); + /** * @brief di_get_output_buffer_num get output buffer num *