From 99d04263dc08347bc42ee0469db866806afbd077 Mon Sep 17 00:00:00 2001 From: "lukang.jia" Date: Mon, 15 Dec 2025 02:56:03 +0000 Subject: [PATCH] dpss: sync code from 5.15 to 6.12 [1/1] PD#SWPL-245970 Problem: sync code from 5.15 to 6.12 Solution: sync code from 5.15 to 6.12 574821 610996 615838 616810 Verify: T6X Change-Id: I8f2c55ba78d3bb6cb0ea4ea2f4ea37c31875ba19 Signed-off-by: lukang.jia --- drivers/media/dpss/dpss_func.h | 1 + drivers/media/dpss/dpss_hw.c | 231 ++++--- drivers/media/dpss/dpss_hw_frc.c | 568 +++++++++++++++--- drivers/media/dpss/dpss_hw_frc.h | 5 +- drivers/media/dpss/dpss_rdma_frc.c | 172 +++++- drivers/media/dpss/dpss_rdma_frc.h | 2 + drivers/media/dpss/dpss_s_frc.c | 231 +++++-- drivers/media/dpss/dpss_s_frc.h | 6 + drivers/media/dpss/dpss_sys.h | 24 +- drivers/media/dpss/hw/dpss_intf.c | 55 +- drivers/media/dpss/hw/dpss_intf.h | 2 + drivers/media/dpss/hw/dpss_lib.c | 40 +- drivers/media/dpss/hw/dpss_lib.h | 32 +- drivers/media/dpss/hw/dpss_param.h | 6 + drivers/media/dpss/sys_def.h | 1 + drivers/media/video_sink/video_func.c | 3 + include/linux/amlogic/media/dpss/dpss_frc.h | 1 + .../linux/amlogic/media/dpss/frc_common_x.h | 21 +- 18 files changed, 1096 insertions(+), 305 deletions(-) diff --git a/drivers/media/dpss/dpss_func.h b/drivers/media/dpss/dpss_func.h index f304c76dd..b638f7296 100644 --- a/drivers/media/dpss/dpss_func.h +++ b/drivers/media/dpss/dpss_func.h @@ -286,5 +286,6 @@ void _prm_top_init_buffer(struct PRM_DPSS_TOP *prm_top, struct dpss_ch_s *pch, unsigned int src); void _prm_top_init_vfm(struct dpss_ch_s *pch, struct PRM_DPSS_TOP *prm_top, struct dpss_sub_vf_s *vfms, bool is_ex_di); //user case +inline u32 update_reg_val(u32 reg_val, u32 val, u8 start, u8 len); #endif /*__DPSS_FUNC_H__*/ diff --git a/drivers/media/dpss/dpss_hw.c b/drivers/media/dpss/dpss_hw.c index ab2e290a8..230cfb369 100644 --- a/drivers/media/dpss/dpss_hw.c +++ b/drivers/media/dpss/dpss_hw.c @@ -1748,33 +1748,71 @@ void hw_cfg_dpss_dpe_no_buf_update(enum DPSS_WORK_MODE dpe_mode, unsigned int dpss_int = IRQ_MODE_CASE_0_SRC0_NR_DI; //bit 0 for dae module_param_named(dpss_int, dpss_int, uint, 0664); +static void mc_put_buffer(struct frc_state_s *state_st) +{ + u8 drop_idx; + u8 dst_buf_cnt; + struct display_buffer_info_s *display_buf_info; + + if (!state_st) + return; + + cfg_dpss_done_trigger(FRC_DST_DONE); + drop_idx = display_buf_q.drop_idx; + display_buf_info = &display_buf_q.data[drop_idx]; + state_st->mc_drop_idx = display_buf_info->p; + display_buf_q.drop_idx = (display_buf_q.drop_idx + 1) % DPSS_QUEEN_NUM; + dst_buf_cnt = get_dst_buf_cnt(&display_buf_q); + pr_frc(1, "drop_idx=%d, mc_idx=%d, inp_idx=%d, diff=%d, mc_drop=%d, mc_display=%d\n", + display_buf_q.drop_idx, display_buf_q.mc_idx, display_buf_q.inp_idx, + dst_buf_cnt, state_st->mc_drop_idx, state_st->mc_disp_st.disp_idx); +} + +static bool mc_need_drop_frame(struct dpss_frc_top_type_s *frc_top, struct frc_state_s *state_st) +{ + u32 frc_dst_buf; + u32 nr_buf_state; + u8 nr_dae_ibuf_level; + u8 nr_dpe_free_buf_level; + bool ret = false; + + if (!frc_top || !state_st) + return false; + + frc_dst_buf = rd(DPSS_FRC_DST_BUFF_STATUS) & 0xf; + nr_buf_state = rd(DPSS_FBUF_BUF_CNT); + nr_dpe_free_buf_level = nr_buf_state >> 8 & 0x1f; + nr_dae_ibuf_level = nr_buf_state >> 16 & 0x1f; + + if (frc_dst_buf > 0 && frc_top->need_dpe_mix) + ret = true; + else if (!state_st->force_disable_dpe_mix && nr_dpe_free_buf_level < 2 && + (frc_dst_buf > state_st->dst_buf_th || + (frc_dst_buf > 0 && nr_dae_ibuf_level > 2))) + ret = true; + frc_top->need_dpe_mix = 0; + dbg_f2("nr_dae_ibuf:%d nr_dpe_free_buf:%d frc_dst_buf=%d dpe_mix=%d\n", + nr_dae_ibuf_level, nr_dpe_free_buf_level, frc_dst_buf, ret); + return ret; +} + void irq_pre_vs(void) { struct frc_chip_st *pchip_st; struct frc_state_s *state_st; struct dpss_frc_fw_data_s *pfw_data; struct dpss_frc_top_type_s *frc_top; - u32 ro_disp_info_0; bool src0_disp_obuf_rdy = 0; - unsigned int dpss_frc_vpp_link; - // unsigned int mc_ibuf_stats = rd(DPSS_FRC_MC_IUFF_STATUS); - unsigned int pre_idx, cur_idx; + bool display_ready; struct PRM_DPSS_TOP *prm_top = prm_dpss_top; struct frc_interrupt_s *frc_int_st; - u32 dae_frm_phs; - u32 dpe_intp_phs; - bool mc_ibuf_vld; bool is_vd1_link; bool manual_disable_link = false; - bool phs_swth = false; u64 timestamp = sched_clock(); - u32 rls_dae_buf_rule; - u32 rls_dae_buf_cnt = 0; u32 frc_dst_buf; - u32 nr_buf_state; - u8 nr_dae_ibuf_level; - u8 nr_dpe_free_buf_level; - static u32 cur_idx_last; + u8 mc_drop_idx; + u8 drop_idx; + struct display_buffer_info_s *display_buf_info; pchip_st = dpss_get_frc_st(); @@ -1797,97 +1835,46 @@ void irq_pre_vs(void) frc_int_st->pre_vsync_cnt++; dbg_h2("irq_pre_vsync start %d\n", frc_int_st->pre_vsync_cnt); - dpss_frc_vpp_link = rd(FRC_DPSS_VPP_LINK); src0_disp_obuf_rdy = state_st->src0_disp_obuf_rdy; - rls_dae_buf_rule = rd(FRC_REG_TOP_RESERVE3); - nr_buf_state = rd(DPSS_FBUF_BUF_CNT); - nr_dpe_free_buf_level = nr_buf_state >> 8 & 0x1f; - nr_dae_ibuf_level = nr_buf_state >> 16 & 0x1f; + frc_undone_check(); - if (dpss_frc_vpp_link) - frc_undone_check(); - - if (src0_disp_obuf_rdy && dpss_frc_vpp_link) { - w_reg_bit(FRC_DAE_SW_CTRL0, 1, 25, 1); - cfg_dpss_done_trigger(FRC_DST_DONE); //last frame - } + if (src0_disp_obuf_rdy && display_queue_put(&display_buf_q)) + mc_put_buffer(state_st); frc_dst_buf = rd(DPSS_FRC_DST_BUFF_STATUS) & 0xf; dbg_f2("frc_dst_buf pre = %d\n", frc_dst_buf); - if (rls_dae_buf_rule & C_BIT16) { - if (prm_top->mc_auto_en) { - dbg_f2("need check, mc is auto mode\n"); - } else { - dbg_f2("rls_dae_buf_rule=%#x\n", rls_dae_buf_rule); - rls_dae_buf_cnt = rls_dae_buf_rule & 0xffff; - while (rls_dae_buf_cnt && frc_dst_buf > 0) { - cfg_dpss_done_trigger(FRC_DST_DONE); - rls_dae_buf_cnt--; - frc_dst_buf = rd(DPSS_FRC_DST_BUFF_STATUS) & 0xf; - dbg_f2("rls_dae_buf_cnt=%#x\n", rls_dae_buf_cnt); - } - rls_dae_buf_rule = rls_dae_buf_rule & 0xf0000000; - wr(FRC_REG_TOP_RESERVE3, rls_dae_buf_rule); + while (src0_disp_obuf_rdy && frc_dst_buf > 0 && display_queue_put(&display_buf_q)) { + drop_idx = (display_buf_q.drop_idx + 1) % DPSS_QUEEN_NUM; + display_buf_info = &display_buf_q.data[drop_idx]; + mc_drop_idx = display_buf_info->p; + if (state_st->mc_disp_st.disp_idx == state_st->mc_drop_idx && + mc_drop_idx != state_st->mc_drop_idx) { + pr_frc(2, "now_mc_drop_idx=%d\n", mc_drop_idx); + break; } + mc_put_buffer(state_st); + frc_top->dpe_mix_cnt++; + if (display_buf_info->dae_mix) + frc_top->dpe_mix_cnt--; + pr_frc(2, "dpe_mix_cnt=%d\n", frc_top->dpe_mix_cnt); } - if (!state_st->force_disable_dpe_mix && src0_disp_obuf_rdy && nr_dpe_free_buf_level < 2 && - (frc_dst_buf > state_st->dst_buf_th || - (frc_dst_buf > 0 && nr_dae_ibuf_level > 2))) { - cfg_dpss_done_trigger(FRC_DST_DONE); - frc_dst_buf = rd(DPSS_FRC_DST_BUFF_STATUS) & 0xf; - rls_dae_buf_rule = rls_dae_buf_rule >> 28; - rls_dae_buf_rule++; - rls_dae_buf_rule = rls_dae_buf_rule << 28; - wr(FRC_REG_TOP_RESERVE3, rls_dae_buf_rule); - dbg_f2("frc_dst_buf post=%d rls_dae_buf_rule=%#x\n", - frc_dst_buf, rls_dae_buf_rule); - } + + if (!state_st->dpe_mix) + state_st->dpe_mix = mc_need_drop_frame(frc_top, state_st); check_dpss_frc_status(); dpss_pre_vs_reg_monitor(); - dbg_f2("nr_dae_ibuf:%d nr_dpe_free_buf:%d DPSS_FBUF_PROC_STATUS:%#x\n", - nr_dae_ibuf_level, nr_dpe_free_buf_level, rd(DPSS_FBUF_PROC_STATUS)); + src0_disp_obuf_rdy = disp_obuf_trigger(FRC_DST_DONE); - dbg_h2("src0_disp_obuf_rdy_cur: %d\n", src0_disp_obuf_rdy); - - dae_frm_phs = (rd(FRC_DPSS_DISP_BUFF_INFO_1) >> 12) & 0x1; - - if (frc_top->force_mix == 1 && dpss_frc_vpp_link) { - ro_disp_info_0 = rd(FRC_DPSS_DISP_BUFF_INFO_0); - while (dae_frm_phs == 0 && src0_disp_obuf_rdy) { - dbg_h2("dpe_force_mixer_phs\n"); - if (prm_top->sw_tbc_ctrl_en == 1) { - w_reg_bit(DPSS_FNR_SW_DRV_CTRL1, - (ro_disp_info_0 >> 2) & 0xf, 4, 4); - w_reg_bit(DPSS_FNR_SW_DRV_CTRL0, 1, 1, 1); - w_reg_bit(FRC_DAE_SW_CTRL0, 1, 25, 1); - } - cfg_dpss_done_trigger(FRC_DST_DONE); - src0_disp_obuf_rdy = disp_obuf_trigger(FRC_DST_DONE); - dae_frm_phs = (rd(FRC_DPSS_DISP_BUFF_INFO_1) >> 12) & 0x1; - ro_disp_info_0 = rd(FRC_DPSS_DISP_BUFF_INFO_0); - } - } - state_st->src0_disp_obuf_rdy = src0_disp_obuf_rdy; frc_ocnt_status = src0_disp_obuf_rdy; - ro_disp_info_0 = rd(FRC_DPSS_DISP_BUFF_INFO_0); - pre_idx = (ro_disp_info_0 >> 2) & 0xf; - cur_idx = (ro_disp_info_0 >> 8) & 0xf; - if (src0_disp_obuf_rdy) { - if (cur_idx_last == pre_idx) - phs_swth = true; - cur_idx_last = cur_idx; - dbg_f2("ro_disp_info_0:%#x pre_idx/cur_idx:%x %x, phs_swth=%d, cur_last=%x\n", - ro_disp_info_0, pre_idx, cur_idx, phs_swth, cur_idx_last); - } is_vd1_link = is_vd1_link_state(); if (!enable_mc_link && !is_vd1_link) manual_disable_link = true; - hw_dpss_dpe_info_cfg(prm_top, src0_disp_obuf_rdy); - if (src0_disp_obuf_rdy && frc_top->fw_pause == 0 && pfw_data->pre_vsync_irq_handler) + display_ready = hw_dpss_dpe_info_cfg(prm_top, src0_disp_obuf_rdy); + if (display_ready && frc_top->fw_pause == 0 && pfw_data->pre_vsync_irq_handler) pfw_data->pre_vsync_irq_handler(pfw_data); if (state_st->need_switch_to_vd1 || state_st->mc_bypass || manual_disable_link) { @@ -1898,10 +1885,7 @@ void irq_pre_vs(void) state_st->mc_set_phase0 = true; } - mc_ibuf_vld = (rd(DPSS_FRC_MC_IUFF_STATUS) >> 4) & 0x1; - dpe_intp_phs = mc_ibuf_vld ? (rd(FRC_DPSS_DISP_BUFF_INFO_0) >> 22) & 0xff : 0; - - if (state_st->mc_bypass && phs_swth && state_st->have_update_vfcd && + if (state_st->mc_bypass && state_st->have_update_vfcd && !state_st->mc_bypass_always && frc_top->memc_enable) { if (state_st->mc_bypass_cnt) { dbg_f2("mc_bypass_cnt = %d\n", state_st->mc_bypass_cnt); @@ -1915,8 +1899,8 @@ void irq_pre_vs(void) } } - dbg_f2("mc_intp_phs=%x, mc_phase=%x, mc_ibuf_vld=%d, mc_bypass:%d\n", - dpe_intp_phs, rd(DPSS_DPE_MC_PHASE), mc_ibuf_vld, state_st->mc_bypass); + dbg_f2("mc_phase=%3d, mc_bypass=%d, obuf_rdy=%d, display_ready=%d\n", + rd(DPSS_DPE_MC_PHASE), state_st->mc_bypass, src0_disp_obuf_rdy, display_ready); //don't add logic after triggle function,add by fxj hw_cfg_dpss_mc_pre_triggle(); @@ -1937,12 +1921,6 @@ void irq_display(void) struct frc_state_s *state_st; struct dpss_frc_fw_data_s *pfw_data; struct dpss_frc_top_type_s *frc_top; - bool src0_disp_obuf_rdy; - u32 dpss_frc_vpp_link; - u32 dpss_fnr_vpp_link; - u32 ro_disp_info; - u32 mc_ibuf_rdy = 0; - bool phs_swth; u64 timestamp = sched_clock(); struct frc_interrupt_s *frc_int_st; @@ -1967,28 +1945,10 @@ void irq_display(void) frc_int_st->frc_vsync_cnt++; state_st = &pchip_st->state_st; - dpss_frc_vpp_link = rd(FRC_DPSS_VPP_LINK); - dpss_fnr_vpp_link = rd(DPSS_NR_VPP_LINK); dpss_vsync_reg_monitor(); if (frc_ocnt_status) dpss_disp0_frm_cnt++; - src0_disp_obuf_rdy = disp_obuf_trigger(FRC_DST_DONE); - - //=============== sw tbc ================ - - ro_disp_info = rd(FRC_DPSS_DISP_BUFF_INFO_0); - mc_ibuf_rdy = (rd(DPSS_FRC_MC_IUFF_STATUS) >> 4) & 0x1; - state_st->pre_idx = state_st->cur_idx; - if (mc_ibuf_rdy == 1) - state_st->cur_idx = (ro_disp_info >> 2) & 0xf; - phs_swth = state_st->pre_idx != state_st->cur_idx; - - if (phs_swth && src0_disp_obuf_rdy) { - dbg_h2("now mc rls pre_idx: %d\n", state_st->pre_idx); - w_reg_bit(DPSS_FNR_SW_DRV_CTRL1, state_st->pre_idx, 4, 4); - w_reg_bit(DPSS_FNR_SW_DRV_CTRL0, 1, 1, 1); - } if (frc_top->fw_pause == 0) { if (pfw_data->vsync_irq_handler) pfw_data->vsync_irq_handler(pfw_data); @@ -2004,7 +1964,7 @@ void irq_display(void) #ifdef USE_FRC_PRE_VS_RDMA // dpss_rdma_auto_wr_reg(reg, val + idx); DPSS_RDMA_WR_VS(FRC_REG_TOP_RESERVE1, dpss_disp0_frm_cnt); - dpss_rdma_auto_wr_tri(2); + // dpss_rdma_auto_wr_tri(2); #endif } @@ -2260,6 +2220,8 @@ void irq_dae0(void) u32 cur_fid; u32 nxt_fid; u32 phs_swth; + u32 start_mode; + u8 display_inp_idx; //u32 tmpseg; struct dpss_frc_fw_data_s *pfw_data; struct dpss_frc_top_type_s *frc_top; @@ -2298,6 +2260,9 @@ void irq_dae0(void) return; } + if (!state_st->dae_ready && frc_int_st->dae0_int_cnt >= 3) + state_st->dae_ready = true; + if (state_st->mc_bypass_always && state_st->dae0_bypass_mode == 1) { if (frc_int_st->dae0_int_cnt <= 30 && dae_film_mode != DPSS_VIDEO) state_st->dae0_bypass_mode = 0; @@ -2306,7 +2271,7 @@ void irq_dae0(void) dbg_f2("irq_dae_0: dae0_bypass_mode=%d\n", state_st->dae0_bypass_mode); } - if (frc_top->memc_enable == 0 || state_st->need_drop_dd) + if (state_st->need_drop_dd) state_st->enable_last_drop = true; else state_st->enable_last_drop = false; @@ -2320,8 +2285,23 @@ void irq_dae0(void) if (dpss_slt_mode) w_reg_bit(FRC_ME_CMV_CTRL, 1, 31, 1); dpss_dae0_reg_monitor(); - if (phs_swth) + if (phs_swth) { dpss_enqueue(&mc_ibuf_q, nxt_fid); + if (state_st->me_pcn_st.use == 0) { + state_st->me_pcn_st.p = nxt_fid; + state_st->me_pcn_st.use++; + } else if (state_st->me_pcn_st.use == 1) { + state_st->me_pcn_st.c = nxt_fid; + state_st->me_pcn_st.use++; + } else if (state_st->me_pcn_st.use == 2) { + state_st->me_pcn_st.n = nxt_fid; + state_st->me_pcn_st.use++; + } else { + state_st->me_pcn_st.p = state_st->me_pcn_st.c; + state_st->me_pcn_st.c = state_st->me_pcn_st.n; + state_st->me_pcn_st.n = nxt_fid; + } + } dbg_h2("phs_swth=%d,pre_fid = %d,cur_fid = %d,nxt_fid= %d\r\n", phs_swth, pre_fid, cur_fid, nxt_fid); @@ -2365,10 +2345,14 @@ void irq_dae0(void) pfw_data->dae_irq_handler(pfw_data); // hw_config_dae_loop_tab(prm_dpss_top.frc_ratio, dae_film_mode, 0); - //don't add logic after triggle function,add by fxj - unsigned int start_mode = rd(VPU_DAE_WRAP_CTRL) & 0x1; + if (state_st->dae_ready) { + display_inp_idx = display_buf_q.inp_idx; + hw_update_display_info(&display_buf_q.data[display_inp_idx]); + display_buf_q.inp_idx = (display_buf_q.inp_idx + 1) % DPSS_QUEEN_NUM; + } - dbg_h2("dae0 start_mode = %d\n", start_mode); + //don't add logic after triggle function,add by fxj + start_mode = rd(VPU_DAE_WRAP_CTRL) & 0x1; if (start_mode == 1) cfg_dae_triggle(); } @@ -2586,6 +2570,7 @@ void irq_dpe1(void) if (dpss_dpe_nr_frm_cnt < 2) { ro_index = 0; temp_index = 0; + pd_index = 0; } else { temp_index = dpss_dpe_nr_frm_cnt - 1; ro_index = temp_index % prm_top->num_nr_me_ro; //DPSS_DPS_NUB diff --git a/drivers/media/dpss/dpss_hw_frc.c b/drivers/media/dpss/dpss_hw_frc.c index 47eca9826..f1fcc8791 100644 --- a/drivers/media/dpss/dpss_hw_frc.c +++ b/drivers/media/dpss/dpss_hw_frc.c @@ -14,22 +14,33 @@ #endif #include "dpss_base.h" #include "dpss_hw.h" -#include "dpss_hw_frc.h" #include "dpss_s.h" #include "dpss_sys.h" #include "dpss_rdma_frc.h" #include "dpss_s_frc.h" +#include "dpss_hw_frc.h" #include "./hw/define.h" #include "./hw/dpss.h" #include "./hw/dpss_intf.h" #include "./hw/dpss_mc.h" #include "./hw/vfcd.h" +#include "hw/dpss_lib.h" #include "dpss_func.h" unsigned int used_rdma; //force g_dpss_tst_case module_param_named(used_rdma, used_rdma, uint, 0664); +u32 update_reg_val(u32 reg_val, u32 val, u8 start, u8 len) +{ + u32 mask = (((1L << len) - 1) << start); + u32 tmp; + + tmp = reg_val & ~mask; + tmp |= (val << start) & mask; + return tmp; +} + void hw_cfg_dpss_mc_ini(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr) { bool game_mode = prm_top->dpe_game_mode & 0x1; @@ -126,14 +137,12 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm pix_rmif->pad_hmode = prm_mc->pad_hmode; pix_rmif->pad_vmode = prm_mc->pad_vmode; - pix_rmif->slc_x_st[0] = cut_win_en ? prm_top->prm_cut_win.win_hbgn : 0; - pix_rmif->slc_x_ed[0] = cut_win_en ? prm_top->prm_cut_win.win_hend : - prm_top->frm_hsize - 1; - //pix_rmif->slc_x_ed[0] = cut_win_en ? prm_top->prm_cut_win.win_hend : frm_hsize - 1; - pix_rmif->slc_y_st[0] = cut_win_en ? prm_top->prm_cut_win.win_vbgn : 0; - pix_rmif->slc_y_ed[0] = cut_win_en ? prm_top->prm_cut_win.win_vend : - prm_top->frm_vsize - 1; - //pix_rmif->slc_y_ed[0] = cut_win_en ? prm_top->prm_cut_win.win_vend : frm_vsize - 1; + pix_rmif->slc_x_st[0] = cut_win_en ? prm_top->prm_cut_win.win_hbgn_align : 0; + pix_rmif->slc_x_ed[0] = + cut_win_en ? prm_top->prm_cut_win.win_hend_align : prm_top->frm_hsize - 1; + pix_rmif->slc_y_st[0] = cut_win_en ? prm_top->prm_cut_win.win_vbgn_align : 0; + pix_rmif->slc_y_ed[0] = + cut_win_en ? prm_top->prm_cut_win.win_vend_align : prm_top->frm_vsize - 1; pix_rmif->skip_line = mc_skip_mode_v; pix_rmif->cut_win_en = cut_win_en; @@ -143,9 +152,9 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm pix_rmif->src_vsize = cut_win_en ? prm_top->prm_cut_win.frm_vsize : prm_mc->frm_vsize; pix_rmif->slc_x_ed[0] = cut_win_en ? - prm_top->prm_cut_win.win_hend : prm_mc->frm_hsize - 1; + prm_top->prm_cut_win.win_hend_align : prm_mc->frm_hsize - 1; pix_rmif->slc_y_ed[0] = cut_win_en ? - prm_top->prm_cut_win.win_vend : prm_mc->frm_vsize - 1; + prm_top->prm_cut_win.win_vend_align : prm_mc->frm_vsize - 1; } // nr+frc 422 10bit 2plane if (prm_top->dpss_mode == DPSS_FRC_MODE) { @@ -183,10 +192,12 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm vfcd->src_hsize = cut_win_en ? prm_top->prm_cut_win.frm_hsize : prm_top->frm_hsize; vfcd->src_vsize = cut_win_en ? prm_top->prm_cut_win.frm_vsize : prm_top->frm_vsize; vfcd->fmt444_out = fmt444_out; - vfcd->win_bgn_h[0] = cut_win_en ? prm_top->prm_cut_win.win_hbgn : 0; - vfcd->win_end_h[0] = cut_win_en ? prm_top->prm_cut_win.win_hend : prm_top->frm_hsize - 1; - vfcd->win_bgn_v[0] = cut_win_en ? prm_top->prm_cut_win.win_vbgn : 0; - vfcd->win_end_v[0] = cut_win_en ? prm_top->prm_cut_win.win_vend : prm_top->frm_vsize - 1; + vfcd->win_bgn_h[0] = cut_win_en ? prm_top->prm_cut_win.win_hbgn_align : 0; + vfcd->win_end_h[0] = + cut_win_en ? prm_top->prm_cut_win.win_hend_align : prm_top->frm_hsize - 1; + vfcd->win_bgn_v[0] = cut_win_en ? prm_top->prm_cut_win.win_vbgn_align : 0; + vfcd->win_end_v[0] = + cut_win_en ? prm_top->prm_cut_win.win_vend_align : prm_top->frm_vsize - 1; vfcd->compbits_y = dec_src_bit;// pix_rmif.src_bit == BIT_8 ? 8 :pix_rmif.src_bit == BIT_12 ? 12 :10 ; vfcd->compbits_c = @@ -200,9 +211,9 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm vfcd->src_vsize = cut_win_en ? prm_top->prm_cut_win.frm_vsize : prm_mc->frm_vsize; vfcd->win_end_h[0] = cut_win_en ? - prm_top->prm_cut_win.win_hend : prm_mc->frm_hsize - 1; + prm_top->prm_cut_win.win_hend_align : prm_mc->frm_hsize - 1; vfcd->win_end_v[0] = cut_win_en ? - prm_top->prm_cut_win.win_vend : prm_mc->frm_vsize - 1; + prm_top->prm_cut_win.win_vend_align : prm_mc->frm_vsize - 1; } vfcd->src_fmt = fmt; @@ -263,6 +274,10 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm u32 cur_logo_hsize = prm_top->frm_hsize >> x_scl; u32 mv_hsize = pre_logo_hsize >> 2; u32 me_logo_hsize = pre_logo_hsize >> 2; + u32 mc_out_hbgn = 0; + u32 mc_out_hend = 0; + u32 mc_out_vbgn = 0; + u32 mc_out_vend = 0; struct PRM_INTF_TYPE *pre_logo_rmif = &pchip->pre_logo_rmif; struct PRM_INTF_TYPE *cur_logo_rmif = &pchip->cur_logo_rmif; struct PRM_INTF_TYPE *mv_rmif = &pchip->mv_rmif; @@ -288,15 +303,15 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm mv_rmif->pack_mode = 4; me_logo_rmif->pack_mode = 0; - pre_logo_rmif->slc_x_st[0] = prm_top->prm_cut_win.win_hbgn >> x_scl; - pre_logo_rmif->slc_x_ed[0] = prm_top->prm_cut_win.win_hend >> x_scl; - pre_logo_rmif->slc_y_st[0] = prm_top->prm_cut_win.win_vbgn >> y_scl; - pre_logo_rmif->slc_y_ed[0] = prm_top->prm_cut_win.win_vend >> y_scl; + pre_logo_rmif->slc_x_st[0] = prm_top->prm_cut_win.win_hbgn_align >> x_scl; + pre_logo_rmif->slc_x_ed[0] = prm_top->prm_cut_win.win_hend_align >> x_scl; + pre_logo_rmif->slc_y_st[0] = prm_top->prm_cut_win.win_vbgn_align >> y_scl; + pre_logo_rmif->slc_y_ed[0] = prm_top->prm_cut_win.win_vend_align >> y_scl; - cur_logo_rmif->slc_x_st[0] = prm_top->prm_cut_win.win_hbgn >> x_scl; - cur_logo_rmif->slc_x_ed[0] = prm_top->prm_cut_win.win_hend >> x_scl; - cur_logo_rmif->slc_y_st[0] = prm_top->prm_cut_win.win_vbgn >> y_scl; - cur_logo_rmif->slc_y_ed[0] = prm_top->prm_cut_win.win_vend >> y_scl; + cur_logo_rmif->slc_x_st[0] = prm_top->prm_cut_win.win_hbgn_align >> x_scl; + cur_logo_rmif->slc_x_ed[0] = prm_top->prm_cut_win.win_hend_align >> x_scl; + cur_logo_rmif->slc_y_st[0] = prm_top->prm_cut_win.win_vbgn_align >> y_scl; + cur_logo_rmif->slc_y_ed[0] = prm_top->prm_cut_win.win_vend_align >> y_scl; mv_rmif->slc_x_st[0] = pre_logo_rmif->slc_x_st[0] >> 2; mv_rmif->slc_x_ed[0] = pre_logo_rmif->slc_x_ed[0] >> 2; @@ -322,6 +337,20 @@ void hw_cfg_dpss_mc_intf(struct PRM_DPSS_TOP *prm_top, struct DPSS_MC0_TYPE *prm cfg_mc_sub_rdmif(me_logo_rmif, 3, 0); w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0xf, 3, 4); + w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0x1, 8, 1); + + mc_out_hbgn = prm_top->prm_cut_win.win_hbgn; + mc_out_hend = prm_top->prm_cut_win.win_hend; + mc_out_vbgn = prm_top->prm_cut_win.win_vbgn; + mc_out_vend = prm_top->prm_cut_win.win_vend; + + w_reg_bit(DPSS_DPE_MC_WIN_CUT_H, mc_out_hbgn, 0, 13); + w_reg_bit(DPSS_DPE_MC_WIN_CUT_H, mc_out_hend, 16, 13); + w_reg_bit(DPSS_DPE_MC_WIN_CUT_V, mc_out_vbgn, 0, 13); + w_reg_bit(DPSS_DPE_MC_WIN_CUT_V, mc_out_vend, 16, 13); + } else { + w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0x0, 8, 1); + w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0x0, 3, 4); } } @@ -364,8 +393,8 @@ void hw_cfg_dpss_mc0(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr, struct DPSS_ // frm_hsize = prm_top->frm_hsize; // frm_vsize = prm_top->frm_vsize; //} - frm_hsize = frm_hsize > 1920 ? (frm_hsize + 15) / 16 * 16 : (frm_hsize + 7) / 8 * 8; + //frm_hsize = frm_hsize > 1920 ? (frm_hsize + 15) / 16 * 16 : (frm_hsize + 7) / 8 * 8; if (prm_mc->pad_en && prm_top->org_hsize != 0xffff) { src_hsize = cut_win_en ? win_hsize @@ -639,6 +668,128 @@ void hw_cfg_dpss_mc0(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr, struct DPSS_ w_reg_bit(DPSS_FBUF_TOP_CTRL, 0, 3, 1); } +void frc_me_cut(struct PRM_DPSS_TOP *prm_top) +{ + u32 x_scl = prm_top->dpe_dw_dsx; + u32 y_scl = prm_top->dpe_dw_dsy; + u32 pre_logo_rmif_bits = 1; + u32 cur_logo_rmif_bits = 1; + u32 mv_rmif_bits = 64; + u32 me_logo_rmif_bits = 1; + + u32 frm_hsize; + u32 pre_logo_hsize; + u32 cur_logo_hsize; + u32 mv_hsize; + u32 me_logo_hsize; + u32 mc_out_hbgn = 0; + u32 mc_out_hend = 0; + u32 mc_out_vbgn = 0; + u32 mc_out_vend = 0; + u32 tmp_reg_value; + struct PRM_INTF_TYPE *pre_logo_rmif; + struct PRM_INTF_TYPE *cur_logo_rmif; + struct PRM_INTF_TYPE *mv_rmif; + struct PRM_INTF_TYPE *me_logo_rmif; + struct frc_chip_st *pchip = dpss_get_frc_st(); + bool cut_win_en; + + if (!pchip) { + dbg_h2("%s pchip is null\n", __func__); + return; + } + pre_logo_rmif = &pchip->pre_logo_rmif; + cur_logo_rmif = &pchip->cur_logo_rmif; + mv_rmif = &pchip->mv_rmif; + me_logo_rmif = &pchip->me_logo_rmif; + + frm_hsize = prm_top->frm_hsize; + pre_logo_hsize = frm_hsize >> x_scl; + cur_logo_hsize = frm_hsize >> x_scl; + mv_hsize = pre_logo_hsize >> 2; + me_logo_hsize = pre_logo_hsize >> 2; + cut_win_en = prm_top->cut_win_en; + + memset((void *)(pre_logo_rmif), 0, sizeof(struct PRM_INTF_TYPE)); + memset((void *)(cur_logo_rmif), 0, sizeof(struct PRM_INTF_TYPE)); + memset((void *)(mv_rmif), 0, sizeof(struct PRM_INTF_TYPE)); + memset((void *)(me_logo_rmif), 0, sizeof(struct PRM_INTF_TYPE)); + + pre_logo_rmif->burst_len = 2; + cur_logo_rmif->burst_len = 2; + mv_rmif->burst_len = 2; + me_logo_rmif->burst_len = 2; + if (cut_win_en) { + pre_logo_rmif->bits_mode = 12; + cur_logo_rmif->bits_mode = 12; + mv_rmif->bits_mode = 4; + me_logo_rmif->bits_mode = 12; + + pre_logo_rmif->pack_mode = 4; + cur_logo_rmif->pack_mode = 4; + mv_rmif->pack_mode = 4; + me_logo_rmif->pack_mode = 0; + + pre_logo_rmif->slc_x_st[0] = prm_top->prm_cut_win.win_hbgn_align >> x_scl; + pre_logo_rmif->slc_x_ed[0] = prm_top->prm_cut_win.win_hend_align >> x_scl; + pre_logo_rmif->slc_y_st[0] = prm_top->prm_cut_win.win_vbgn_align >> y_scl; + pre_logo_rmif->slc_y_ed[0] = prm_top->prm_cut_win.win_vend_align >> y_scl; + + cur_logo_rmif->slc_x_st[0] = prm_top->prm_cut_win.win_hbgn_align >> x_scl; + cur_logo_rmif->slc_x_ed[0] = prm_top->prm_cut_win.win_hend_align >> x_scl; + cur_logo_rmif->slc_y_st[0] = prm_top->prm_cut_win.win_vbgn_align >> y_scl; + cur_logo_rmif->slc_y_ed[0] = prm_top->prm_cut_win.win_vend_align >> y_scl; + + mv_rmif->slc_x_st[0] = pre_logo_rmif->slc_x_st[0] >> 2; + mv_rmif->slc_x_ed[0] = pre_logo_rmif->slc_x_ed[0] >> 2; + mv_rmif->slc_y_st[0] = pre_logo_rmif->slc_y_st[0] >> 2; + mv_rmif->slc_y_ed[0] = pre_logo_rmif->slc_y_ed[0] >> 2; + + me_logo_rmif->slc_x_st[0] = pre_logo_rmif->slc_x_st[0] >> 2; + me_logo_rmif->slc_x_ed[0] = pre_logo_rmif->slc_x_ed[0] >> 2; + me_logo_rmif->slc_y_st[0] = pre_logo_rmif->slc_y_st[0] >> 2; + me_logo_rmif->slc_y_ed[0] = pre_logo_rmif->slc_y_ed[0] >> 2; + + pre_logo_rmif->stride = (((pre_logo_hsize * pre_logo_rmif_bits + 127) >> + 7) + 3) >> 2 << 2; + cur_logo_rmif->stride = (((cur_logo_hsize * cur_logo_rmif_bits + 127) >> + 7) + 3) >> 2 << 2; + mv_rmif->stride = (((mv_hsize * mv_rmif_bits + 127) >> 7) + 3) >> 2 << 2; + me_logo_rmif->stride = (((me_logo_hsize * me_logo_rmif_bits + 127) >> + 7) + 3) >> 2 << 2; + + hw_cfg_mc_sub_rdmif(pre_logo_rmif, 0, 0); + hw_cfg_mc_sub_rdmif(cur_logo_rmif, 1, 0); + hw_cfg_mc_sub_rdmif(mv_rmif, 2, 0); + hw_cfg_mc_sub_rdmif(me_logo_rmif, 3, 0); + + //w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0xf, 3, 4); + //w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0x1, 8, 1); + tmp_reg_value = rd(DPSS_DPE_MC_MIF_CTRL0); + tmp_reg_value &= 0xfffffe87; + tmp_reg_value |= 0x178; + DPSS_RDMA_WR_VS(DPSS_DPE_MC_MIF_CTRL0, tmp_reg_value); + + mc_out_hbgn = prm_top->prm_cut_win.win_hbgn; + mc_out_hend = prm_top->prm_cut_win.win_hend; + mc_out_vbgn = prm_top->prm_cut_win.win_vbgn; + mc_out_vend = prm_top->prm_cut_win.win_vend; + //w_reg_bit(DPSS_DPE_MC_WIN_CUT_H, mc_out_hbgn, 0, 13); + //w_reg_bit(DPSS_DPE_MC_WIN_CUT_H, mc_out_hend, 16, 13); + //w_reg_bit(DPSS_DPE_MC_WIN_CUT_V, mc_out_vbgn, 0, 13); + //w_reg_bit(DPSS_DPE_MC_WIN_CUT_V, mc_out_vend, 16, 13); + tmp_reg_value = mc_out_hbgn | (mc_out_hend << 16); + DPSS_RDMA_WR_VS(DPSS_DPE_MC_WIN_CUT_H, tmp_reg_value); + tmp_reg_value = mc_out_vbgn | (mc_out_vend << 16); + DPSS_RDMA_WR_VS(DPSS_DPE_MC_WIN_CUT_V, tmp_reg_value); + } else { + tmp_reg_value = rd(DPSS_DPE_MC_MIF_CTRL0); + tmp_reg_value &= 0xfffffe87; + tmp_reg_value |= 0x01; + DPSS_RDMA_WR_VS(DPSS_DPE_MC_MIF_CTRL0, tmp_reg_value); + } +} + void hw_cfg_dpss_mc_pre_triggle(void) { // cfg @go_filed // w_reg_bit(DPSS_DPE_MC_START_CTRL, 1, 0, 1); @@ -775,17 +926,14 @@ void hw_cfg_dpss_mc_bbd(u32 frm_hsize, u32 frm_vsize, u32 bbd_en, u32 bbd_sel, u w_reg_bit(FRC_BBD_MISC, 10, 4, 4); } -void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) +bool hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) { u32 data32; u32 dpe_pre_pixl_buf; u32 dpe_cur_pixl_buf; - u32 dpe_ibuf_nr_byps_pre; - u32 dpe_ibuf_nr_byps_cur; u32 dpe_plogo_buf; u32 dpe_clogo_buf; u32 dpe_intp_phs; - u32 dpe_byp_en; u32 dpe_mvlogo_buf; u32 dpe_mv_cur_frm_idx; u32 dpe_image_cur_frm_idx; @@ -806,7 +954,6 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) u32 mc_pix_logo_step; u32 mc_blk_logo_step; u32 mc_vpmc_mv_step; - u32 mc_ibuf_vld; u32 game_mode_ntm; u32 mc_luma0_rdmif_baddr0; @@ -826,35 +973,69 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) bool is_pause_state = false; bool is_empty = false; + u8 display_mc_idx; struct frc_chip_st *pchip_st = dpss_get_frc_st(); struct frc_state_s *state_st; + struct display_buffer_info_s *display_buf_info; if (!pchip_st) - return; + return false; state_st = &pchip_st->state_st; if (!obuf_rdy) { if (!state_st->enable_last_drop) - return; + return false; is_pause_state = true; } data32 = rd(DPSS_FRC_MC_IUFF_STATUS); - mc_ibuf_vld = (data32 >> 4) & 0x1; game_mode_ntm = (rd(FRC_DPSS_LLM) >> 2) & 0x1; - data32 = rd(FRC_DPSS_DISP_BUFF_INFO_0); - dpe_pre_pixl_buf = (data32 >> 2) & 0xf; - dpe_cur_pixl_buf = (data32 >> 8) & 0xf; + data32 = display_buf_q.mc_idx; + if (data32 >= DPSS_QUEEN_NUM || data32 == display_buf_q.inp_idx) { + pr_frc(2, "display_buf_q: mc_idx=%d, inp_idx=%d\n", data32, display_buf_q.inp_idx); + return false; + } + display_buf_info = &display_buf_q.data[data32]; + while (display_buf_info->dae_mix) { + data32 = (display_buf_q.mc_idx + 1) % DPSS_QUEEN_NUM; + if (data32 == display_buf_q.inp_idx) { + pr_frc(2, "can not do dae mix:mc_idx=%d, inp_idx=%d\n", + display_buf_q.mc_idx, display_buf_q.inp_idx); + return false; + } + display_buf_q.mc_idx = (display_buf_q.mc_idx + 1) % DPSS_QUEEN_NUM; + display_buf_info = &display_buf_q.data[data32]; + } + if (state_st->dpe_mix) { + data32 = (display_buf_q.mc_idx + 1) % DPSS_QUEEN_NUM; + state_st->dpe_mix = false; + if (data32 == display_buf_q.inp_idx) { + pr_frc(2, "can not do dpe mix:mc_idx=%d, inp_idx=%d\n", + display_buf_q.mc_idx, display_buf_q.inp_idx); + return false; + } + display_buf_q.mc_idx = (display_buf_q.mc_idx + 1) % DPSS_QUEEN_NUM; + display_buf_info = &display_buf_q.data[data32]; + } + display_mc_idx = display_buf_q.mc_idx; + dpe_pre_pixl_buf = display_buf_info->p; + dpe_cur_pixl_buf = display_buf_info->c; + dpe_plogo_buf = display_buf_info->logo_pre; + dpe_clogo_buf = display_buf_info->logo_cur; + dpe_intp_phs = display_buf_info->mc_phase; + dpe_mvlogo_buf = display_buf_info->mv_buf; - dpe_ibuf_nr_byps_pre = (data32 >> 12) & 0x1; - dpe_ibuf_nr_byps_cur = (data32 >> 13) & 0x1; - dpe_plogo_buf = (data32 >> 14) & 0xf; - dpe_clogo_buf = (data32 >> 18) & 0xf; - dpe_intp_phs = (mc_ibuf_vld) ? (data32 >> 22) & 0xff : 0; - dpe_byp_en = (data32 >> 30) & 0x1; + dpe_mv_cur_frm_idx = dpe_mvlogo_buf; + dpe_image_cur_frm_idx = dpe_cur_pixl_buf; + dpe_image_pre_frm_idx = dpe_pre_pixl_buf; + + display_buf_q.mc_idx = (display_buf_q.mc_idx + 1) % DPSS_QUEEN_NUM; + + pr_frc(1, "display_buf_q:drop_idx=%d, mc_idx=%d, inp_idx=%d\n", + display_buf_q.drop_idx, display_buf_q.mc_idx, display_buf_q.inp_idx); if (pchip_st && (pchip_st->state_st.mc_bypass || pchip_st->state_st.force_mc_phase0)) dpe_intp_phs = 0; @@ -883,7 +1064,7 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) if (is_pause_state) { if (is_empty) { state_st->is_wait_mc_state = true; - return; + return false; } dpss_put_queue(&mc_ibuf_q, &state_st->mc_q_idx, &is_empty); if (!state_st->is_pause_state_last_frmae) { @@ -906,26 +1087,33 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) } if (state_st->is_wait_mc_state) - return; + return false; - pr_frc(1, "mc_q_idx=%d, dpe_pre_pixl_buf=%d, dpe_cur_pixl_buf=%d, pause_st_last=%d\n", - state_st->mc_q_idx, dpe_pre_pixl_buf, dpe_cur_pixl_buf, + state_st->dpe_ready = true; +// if (state_st->mc_disp_st.step == 0) { +// state_st->mc_disp_st.wr_idx = dpe_pre_pixl_buf; +// state_st->mc_disp_st.step = 1; +// } else { +// state_st->mc_disp_st.disp_idx = state_st->mc_disp_st.wr_idx; +// state_st->mc_disp_st.wr_idx = dpe_pre_pixl_buf; +// } + state_st->mc_disp_st.disp_idx = dpe_pre_pixl_buf; + + pr_frc(1, "mc_q_idx=%d, display_mc_idx=%d, dpe_pre=%d, dpe_cur=%d, pause_st_last=%d\n", + state_st->mc_q_idx, display_mc_idx, dpe_pre_pixl_buf, dpe_cur_pixl_buf, state_st->is_pause_state_last_frmae); - pr_frc(1, "display buff info: %x\n", data32); - pr_frc(1, "dpe_ibuf_nr_byps_pre = %#x\n", dpe_ibuf_nr_byps_pre); - pr_frc(1, "dpe_ibuf_nr_byps_cur = %#x\n", dpe_ibuf_nr_byps_cur); - pr_frc(1, "dpe_plogo_buf = %#x\n", dpe_plogo_buf); - pr_frc(1, "dpe_clogo_buf = %#x\n", dpe_clogo_buf); - pr_frc(1, "dpe_intp_phs = %#x\n", dpe_intp_phs); - pr_frc(1, "dpe_byp_en = %#x\n", dpe_byp_en); + pr_frc(1, "mc:pc=%d,%d, logo=%d,%d, mv=%d, mc_phs=%3d\n", + dpe_pre_pixl_buf, dpe_cur_pixl_buf, dpe_plogo_buf, + dpe_clogo_buf, dpe_mvlogo_buf, dpe_intp_phs); + + data32 = rd(FRC_DPSS_DISP_BUFF_INFO_0); + pr_frc(1, "ro:pc=%d,%d, logo=%d,%d, mc_phs=%3d, byp_en=%d\n", + (data32 >> 2) & 0xf, (data32 >> 8) & 0xf, (data32 >> 14) & 0xf, + (data32 >> 18) & 0xf, (data32 >> 22) & 0xff, (data32 >> 30) & 0x1); data32 = rd(FRC_DPSS_DISP_BUFF_INFO_1); - dpe_mvlogo_buf = (data32 >> 0) & 0xf; - dpe_mv_cur_frm_idx = dpe_mvlogo_buf; - dpe_image_cur_frm_idx = dpe_cur_pixl_buf; - dpe_image_pre_frm_idx = dpe_pre_pixl_buf; - pr_frc(1, "dpe_mv_cur_frm_idx = %#x\n", dpe_mv_cur_frm_idx); + pr_frc(1, "ro:dpe_mv_cur_frm_idx=%d\n", data32 & 0xf); bool mc_mif_reg_mode = (rd(DPSS_DPE_MC_MIF_CTRL0) >> 2) & 0x1; u32 dpe_pixl_buf_idx0 = @@ -966,7 +1154,7 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) mc_inp_head_cbuf_addr = rd(DPSS_SRC0_DIOUT_CHEAD_ADDR); mc_inp_head_ybuf_step = rd(DPSS_SRC0_DIOUT_YHEAD_STEP); mc_inp_head_cbuf_step = rd(DPSS_SRC0_DIOUT_CHEAD_STEP); - } else if (dpe_ibuf_nr_byps_cur | game_mode_ntm) { + } else if (game_mode_ntm) { src0_fbuf_yaddr[0] = rd(DPSS_SRC0_FBUF_YADDR0 + dpe_pixl_buf_idx0); src0_fbuf_caddr[0] = rd(DPSS_SRC0_FBUF_CADDR0 + dpe_pixl_buf_idx0); src0_fbuf_yaddr[1] = rd(DPSS_SRC0_FBUF_YADDR0 + dpe_pixl_buf_idx1); @@ -1006,14 +1194,14 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) // dpe input data //=====================================================================================//// mc_luma0_rdmif_baddr0 = mc_inp_body_ybuf_addr[0] << 5; - if (dpe_ibuf_nr_byps_cur | game_mode_ntm) + if (game_mode_ntm) mc_luma0_rdmif_baddr1 = prm_top->src0_head_yaddr[dpe_pixl_buf_idx0]; else mc_luma0_rdmif_baddr1 = mc_inp_head_ybuf_addr + mc_inp_head_ybuf_step * dpe_pixl_buf_idx0; mc_luma1_rdmif_baddr0 = mc_inp_body_ybuf_addr[1] << 5; - if (dpe_ibuf_nr_byps_cur | game_mode_ntm) + if (game_mode_ntm) mc_luma1_rdmif_baddr1 = prm_top->src0_head_yaddr[dpe_pixl_buf_idx1]; else mc_luma1_rdmif_baddr1 = mc_inp_head_ybuf_addr + @@ -1041,19 +1229,21 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) dpe_melogo_baddr = mc_blk_logo_buf + dpe_mvlogo_buf * mc_blk_logo_step; dpe_vpmc_mv_baddr = mc_vpmc_mv_buf + dpe_mvlogo_buf * mc_vpmc_mv_step; - pr_frc(1, "%s mc_luma0_rdmif_baddr1= %x\n", __func__, mc_luma0_rdmif_baddr1); - pr_frc(1, "%s mc_luma0_rdmif_baddr0= %x\n", __func__, mc_luma0_rdmif_baddr0); - pr_frc(1, "%s mc_chrm0_rdmif_baddr1= %x\n", __func__, mc_chrm0_rdmif_baddr1); - pr_frc(1, "%s mc_chrm0_rdmif_baddr0= %x\n", __func__, mc_chrm0_rdmif_baddr0); - pr_frc(1, "%s mc_luma1_rdmif_baddr1= %x\n", __func__, mc_luma1_rdmif_baddr1); - pr_frc(1, "%s mc_luma1_rdmif_baddr0= %x\n", __func__, mc_luma1_rdmif_baddr0); - pr_frc(1, "%s mc_chrm1_rdmif_baddr1= %x\n", __func__, mc_chrm1_rdmif_baddr1); - pr_frc(1, "%s mc_chrm1_rdmif_baddr0= %x\n", __func__, mc_chrm1_rdmif_baddr0); + if (state_st->check_frc_status_en) { + pr_frc(1, "%s mc_luma0_rdmif_baddr1= %x\n", __func__, mc_luma0_rdmif_baddr1); + pr_frc(1, "%s mc_luma0_rdmif_baddr0= %x\n", __func__, mc_luma0_rdmif_baddr0); + pr_frc(1, "%s mc_chrm0_rdmif_baddr1= %x\n", __func__, mc_chrm0_rdmif_baddr1); + pr_frc(1, "%s mc_chrm0_rdmif_baddr0= %x\n", __func__, mc_chrm0_rdmif_baddr0); + pr_frc(1, "%s mc_luma1_rdmif_baddr1= %x\n", __func__, mc_luma1_rdmif_baddr1); + pr_frc(1, "%s mc_luma1_rdmif_baddr0= %x\n", __func__, mc_luma1_rdmif_baddr0); + pr_frc(1, "%s mc_chrm1_rdmif_baddr1= %x\n", __func__, mc_chrm1_rdmif_baddr1); + pr_frc(1, "%s mc_chrm1_rdmif_baddr0= %x\n", __func__, mc_chrm1_rdmif_baddr0); - pr_frc(1, "%s ip_logo0_rdmif_baddr = %x\n", __func__, ip_logo0_rdmif_baddr); - pr_frc(1, "%s ip_logo1_rdmif_baddr = %x\n", __func__, ip_logo1_rdmif_baddr); - pr_frc(1, "%s dpe_melogo_baddr = %x\n", __func__, dpe_melogo_baddr); - pr_frc(1, "%s dpe_vpmc_mv_baddr = %x\n", __func__, dpe_vpmc_mv_baddr); + pr_frc(1, "%s ip_logo0_rdmif_baddr = %x\n", __func__, ip_logo0_rdmif_baddr); + pr_frc(1, "%s ip_logo1_rdmif_baddr = %x\n", __func__, ip_logo1_rdmif_baddr); + pr_frc(1, "%s dpe_melogo_baddr = %x\n", __func__, dpe_melogo_baddr); + pr_frc(1, "%s dpe_vpmc_mv_baddr = %x\n", __func__, dpe_vpmc_mv_baddr); + } ////==========================================================//// //// dpe input data @@ -1062,8 +1252,6 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) u32 mc_use_tbc_addr = rd(DPSS_TOP_APB_TBC_SEL_CTRL) & 0x1; if (mc_use_tbc_addr == 0) { - pr_frc(1, "MC use driver config\n"); - wr(DPSS_DPE_MC_DIN_LUMA0_BADDR0, mc_luma0_rdmif_baddr0); wr(DPSS_DPE_MC_DIN_LUMA0_BADDR1, mc_luma0_rdmif_baddr1); @@ -1107,23 +1295,15 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) w_reg_bit(DPSS_DPE_MC_PHASE, dpe_intp_phs, 0, 8); dpss_dpe_dbg_cfg(); - } else { - pr_frc(1, "MC use tbc config\n"); } bool cut_win_en = prm_top->cut_win_en; u32 get_pix_logo_mode; - struct frc_chip_st *pchip = dpss_get_frc_st(); - if (unlikely(!pchip)) { - DBG_ERR("dpe cfg null pointer: pchip is NULL\n"); - return; - } - - struct PRM_INTF_TYPE *pre_logo_rmif = &pchip->pre_logo_rmif; - struct PRM_INTF_TYPE *cur_logo_rmif = &pchip->cur_logo_rmif; - struct PRM_INTF_TYPE *mv_rmif = &pchip->mv_rmif; - struct PRM_INTF_TYPE *me_logo_rmif = &pchip->me_logo_rmif; + struct PRM_INTF_TYPE *pre_logo_rmif = &pchip_st->pre_logo_rmif; + struct PRM_INTF_TYPE *cur_logo_rmif = &pchip_st->cur_logo_rmif; + struct PRM_INTF_TYPE *mv_rmif = &pchip_st->mv_rmif; + struct PRM_INTF_TYPE *me_logo_rmif = &pchip_st->me_logo_rmif; memset((void *)(pre_logo_rmif), 0, sizeof(struct PRM_INTF_TYPE)); memset((void *)(cur_logo_rmif), 0, sizeof(struct PRM_INTF_TYPE)); @@ -1148,6 +1328,7 @@ void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy) cfg_mc_sub_rdmif(mv_rmif, 2, 1); cfg_mc_sub_rdmif(me_logo_rmif, 3, 1); } + return true; } #define PIC_ORG_Y_BADDR 0x72000000 @@ -1736,3 +1917,214 @@ void hw_config_dae_loop_tab(enum DPSS_FRC_RATIO frc_ratio, enum DPSS_FILM_MODE f } } +void frc_mc_cut_0(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr) +{ + struct frc_chip_st *pchip = dpss_get_frc_st(); + struct DPSS_MC0_TYPE *prm_mc; + + if (!pchip) { + dbg_h2("%s pchip is null\n", __func__); + return; + } + prm_mc = &pchip->prm_mc; + hw_cfg_dpss_mc0(prm_top, src_from_nr, prm_mc); + hw_cfg_dpss_mc_intf(prm_top, prm_mc); +} + +void frc_mc_cut_1(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr) +{ + struct frc_chip_st *pchip = dpss_get_frc_st(); + struct DPSS_MC0_TYPE *prm_mc; + struct PRM_INTF_TYPE *pix_rmif; + struct VFCD_t *vfcd; + bool cut_win_en; + u32 win_hsize; + u32 win_vsize; + u32 frm_hsize; + u32 frm_vsize; + u32 mc_size_sel; + u32 mc_skip_mode; + u32 tmp_reg_value; + u32 src_hsize; //= prm_top.org_hsize; + u32 src_vsize; //= prm_top.org_vsize; + u32 fmt; + u32 fmt444_out; + + if (!pchip) { + dbg_h2("%s pchip is null\n", __func__); + return; + } + pix_rmif = &pchip->mc_pix_rmif; + vfcd = &pchip->mc_vfcd; + prm_mc = &pchip->prm_mc; + fmt = prm_mc->pix_fmt == YUV444 ? 0 : prm_mc->pix_fmt == YUV422 ? 1 : 2; + fmt444_out = ((prm_top->frc_vfcd_vfmt == 1) && (fmt == 2)) ? 2 : 0; + + mc_skip_mode = prm_top->mc_skip_mode; + cut_win_en = prm_top->cut_win_en; + win_hsize = prm_top->prm_cut_win.win_hsize; + win_vsize = prm_top->prm_cut_win.win_vsize; + mc_size_sel = prm_top->nr_hscale_on || prm_top->nr_aapps_up || + prm_top->frc_ds_scale_en || mc_skip_mode; + + frm_hsize = cut_win_en ? win_hsize : mc_size_sel ? + prm_top->dpe_mc_size.frm_hsize : prm_top->frm_hsize; + frm_vsize = cut_win_en ? win_vsize : mc_size_sel ? + prm_top->dpe_mc_size.frm_vsize : prm_top->frm_vsize; + frm_hsize = frm_hsize > 1920 ? (frm_hsize + 15) / 16 * 16 : + (frm_hsize + 7) / 8 * 8; + + if (prm_mc->pad_en && prm_top->org_hsize != 0xffff) { + src_hsize = cut_win_en ? win_hsize + : mc_size_sel ? prm_top->dpe_mc_size.src_hsize + : prm_top->org_hsize; + src_vsize = cut_win_en ? win_vsize + : mc_size_sel ? prm_top->dpe_mc_size.src_vsize + : prm_top->org_vsize; + } else { + src_hsize = cut_win_en ? win_hsize + : mc_size_sel ? prm_top->dpe_mc_size.frm_hsize + : prm_top->frm_hsize; + src_vsize = cut_win_en ? win_vsize + : mc_size_sel ? prm_top->dpe_mc_size.frm_vsize + : prm_top->frm_vsize; + } + + u32 me_dsx; + u32 me_dsy; + u32 me_hsize; + u32 me_vsize; + u32 me_blk_hsize; + u32 me_blk_vsize; + + if (prm_top->dpss_mode == DPSS_FRC_MODE) { + me_dsx = prm_top->dae_dsx_scale; + me_dsy = prm_top->dae_dsy_scale; + } else { + me_dsx = prm_top->dpe_dw_dsx; + me_dsy = prm_top->dpe_dw_dsy; + } + me_hsize = (frm_hsize + (1 << me_dsx) - 1) >> me_dsx; + me_vsize = (frm_vsize + (1 << me_dsy) - 1) >> me_dsy; + me_blk_hsize = (me_hsize + 3) >> 2; + me_blk_vsize = (me_vsize + 3) >> 2; + + //w_reg_bit(DPSS_DPE_MC_BLKBAR_X, src_hsize - 1, 16, 13); // reg_blackbar_xyxy2 + //w_reg_bit(DPSS_DPE_MC_BLKBAR_X, 0, 0, 13); // reg_blackbar_xyxy0 + //w_reg_bit(DPSS_DPE_MC_BLKBAR_Y, src_vsize - 1, 16, 13); // reg_blackbar_xyxy3 + //w_reg_bit(DPSS_DPE_MC_BLKBAR_Y, 0, 0, 13); // reg_blackbar_xyxy1 + tmp_reg_value = (src_hsize - 1) << 16; + DPSS_RDMA_WR_VS(DPSS_DPE_MC_BLKBAR_X, tmp_reg_value); + tmp_reg_value = (src_vsize - 1) << 16; + DPSS_RDMA_WR_VS(DPSS_DPE_MC_BLKBAR_Y, tmp_reg_value); + + //wr(DPSS_DPE_MC_TOP_FSIZE, (frm_hsize << 16) | frm_vsize); + //wr(DPSS_DPE_MC_SRC_FSIZE, (src_hsize << 16) | src_vsize); + tmp_reg_value = frm_hsize << 16 | frm_vsize; + DPSS_RDMA_WR_VS(DPSS_DPE_MC_TOP_FSIZE, tmp_reg_value); + tmp_reg_value = src_hsize << 16 | src_vsize; + DPSS_RDMA_WR_VS(DPSS_DPE_MC_SRC_FSIZE, tmp_reg_value); + + //hw_cfg_dpss_mc_slice(frm_hsize, frm_vsize, 1); // slc_num); + //w_reg_bit(FRC_MC_SLC_CTRL3, mc_slice_x_end[0], 0, 16); // reg_slc0_xend + tmp_reg_value = frm_hsize - 1; + DPSS_RDMA_WR_VS(FRC_MC_SLC_CTRL3, tmp_reg_value); + + //hw_cfg_dpss_mc_bbd(frm_hsize, frm_vsize, bbd_en, 0x0, src_hsize, src_vsize); + //w_reg_bit(FRC_MC_BB_HANDLE_ORG_ME_BB_XYXY_RIGHT_BOT, (src_hsize >> me_dsx) - 1, 16, + // 16); // reg_mc_org_me_blk_bb_xyxy_2 //org me size + //w_reg_bit(FRC_MC_BB_HANDLE_ORG_ME_BB_XYXY_RIGHT_BOT, (src_vsize >> me_dsy) - 1, 0, + // 16); // reg_mc_org_me_blk_bb_xyxy_3 //org me size + tmp_reg_value = ((src_hsize >> me_dsx) - 1) << 16 | ((src_vsize >> me_dsy) - 1); + DPSS_RDMA_WR_VS(FRC_MC_BB_HANDLE_ORG_ME_BB_XYXY_RIGHT_BOT, tmp_reg_value); + //w_reg_bit(FRC_MC_BB_HANDLE_ORG_ME_BLK_BB_XYXY_RIT_AND_BOT, + // ((src_hsize >> me_dsx) >> 2) - 1, 16, 16); // reg_mc_org_me_blk_bb_xyxy_2 + //w_reg_bit(FRC_MC_BB_HANDLE_ORG_ME_BLK_BB_XYXY_RIT_AND_BOT, + // ((src_vsize >> me_dsy) >> 2) - 1, 0, 16); // reg_mc_org_me_blk_bb_xyxy_3 + tmp_reg_value = (((src_hsize >> me_dsx) >> 2) - 1) << 16; + tmp_reg_value |= (((src_vsize >> me_dsy) >> 2) - 1); + DPSS_RDMA_WR_VS(FRC_MC_BB_HANDLE_ORG_ME_BLK_BB_XYXY_RIT_AND_BOT, tmp_reg_value); + //w_reg_bit(FRC_MC_BB_HANDLE_ME_BLK_BB_XYXY_RIT_AND_BOT, me_blk_hsize - 1, 16, + // 16); // reg_mc_me_blk_bb_xyxy_2 + //w_reg_bit(FRC_MC_BB_HANDLE_ME_BLK_BB_XYXY_RIT_AND_BOT, me_blk_vsize - 1, 0, + // 16); // reg_mc_me_blk_bb_xyxy_3 + tmp_reg_value = ((me_blk_hsize - 1) << 16) | (me_blk_vsize - 1); + DPSS_RDMA_WR_VS(FRC_MC_BB_HANDLE_ME_BLK_BB_XYXY_RIT_AND_BOT, tmp_reg_value); + + //w_reg_bit(FRC_MC_WRAP_BB_1, src_hsize - 1, 16, 13); // reg_blackbar_xyxy2 + //w_reg_bit(FRC_MC_WRAP_BB_1, src_vsize - 1, 0, 13); // reg_blackbar_xyxy3 + tmp_reg_value = (src_hsize - 1) << 16 | (src_vsize - 1); + DPSS_RDMA_WR_VS(FRC_MC_WRAP_BB_1, tmp_reg_value); + + //hw_cfg_dpss_mc_intf(prm_top, prm_mc); // below implement + pix_rmif->src_hsize = cut_win_en ? prm_top->prm_cut_win.frm_hsize : + prm_top->frm_hsize; + pix_rmif->src_vsize = cut_win_en ? prm_top->prm_cut_win.frm_vsize : + prm_top->frm_vsize; + + pix_rmif->slc_x_st[0] = cut_win_en ? prm_top->prm_cut_win.win_hbgn_align : 0; + pix_rmif->slc_x_ed[0] = + cut_win_en ? prm_top->prm_cut_win.win_hend_align : prm_top->frm_hsize - 1; + pix_rmif->slc_y_st[0] = cut_win_en ? prm_top->prm_cut_win.win_vbgn_align : 0; + pix_rmif->slc_y_ed[0] = + cut_win_en ? prm_top->prm_cut_win.win_vend_align : prm_top->frm_vsize - 1; + //pix_rmif->skip_line = mc_skip_mode_v; + pix_rmif->cut_win_en = cut_win_en; + + frc_cfg_vfcd_rdmif_2ch(DPSS_RMIF_MC0, pix_rmif, fmt444_out); + frc_cfg_vfcd_rdmif_2ch(DPSS_RMIF_MC1, pix_rmif, fmt444_out); + dbg_h2("%s src_bit %d pix_bit %d\n", __func__, pix_rmif->src_bit, prm_mc->pix_bit); + dbg_h2("%s update mif\n", __func__); + vfcd->cut_win_en = cut_win_en; + vfcd->src_hsize = cut_win_en ? prm_top->prm_cut_win.frm_hsize : prm_top->frm_hsize; + vfcd->src_vsize = cut_win_en ? prm_top->prm_cut_win.frm_vsize : prm_top->frm_vsize; + vfcd->fmt444_out = fmt444_out; + vfcd->win_bgn_h[0] = cut_win_en ? prm_top->prm_cut_win.win_hbgn_align : 0; + vfcd->win_end_h[0] = + cut_win_en ? prm_top->prm_cut_win.win_hend_align : prm_top->frm_hsize - 1; + vfcd->win_bgn_v[0] = cut_win_en ? prm_top->prm_cut_win.win_vbgn_align : 0; + vfcd->win_end_v[0] = + cut_win_en ? prm_top->prm_cut_win.win_vend_align : prm_top->frm_vsize - 1; + + dbg_h2("%s vfcd->src_h/v size:(%d,%d)\n", __func__, vfcd->src_hsize, vfcd->src_vsize); + dbg_h2("%s pix_rmif.slc_x:(%d,%d), .slc_y:(%d,%d)\n", __func__, vfcd->win_bgn_h[0], + vfcd->win_end_h[0], vfcd->win_bgn_v[0], vfcd->win_end_v[0]); + frc_cfg_vfcd_dec(4, vfcd); // mc0 + frc_cfg_vfcd_dec(5, vfcd); // mc1 + frc_me_cut(prm_top); +} + +void hw_update_display_info(struct display_buffer_info_s *display_buf_info) +{ + struct frc_chip_st *pchip_st = dpss_get_frc_st(); + struct frc_state_s *state_st; + struct me_pcn_s *me_pcn_st; + + if (!pchip_st || !display_buf_info) { + dbg_h0("%s pchip_st is null\n", __func__); + return; + } + state_st = &pchip_st->state_st; + me_pcn_st = &state_st->me_pcn_st; + display_buf_info->dae_mix = (rd(FRC_REG_CURSOR) & 0x7) == 7 ? 1 : 0; + display_buf_info->p = me_pcn_st->p; + display_buf_info->c = me_pcn_st->c; + display_buf_info->n = me_pcn_st->n; + display_buf_info->logo_pre = rd(FRC_REG_OUT_FID) >> 4 & 0xf; + display_buf_info->logo_cur = rd(FRC_REG_OUT_FID) & 0xf; + display_buf_info->mc_phase = rd(FRC_REG_OUT_PHS) >> 12 & 0xfff; + if (display_buf_info->dae_mix) { + if (state_st->mv_buf_idx == 0) + state_st->mv_buf_idx = DPSS_SML_NUB - 1; + else + state_st->mv_buf_idx--; + } + display_buf_info->mv_buf = pchip_st->state_st.mv_buf_idx; + state_st->mv_buf_idx = (state_st->mv_buf_idx + 1) % DPSS_SML_NUB; + + pr_frc(2, "dae_mix=%d, pcn=(%d,%d,%d), logo=(%d,%d,%d), mc_phase=%3d\n", + display_buf_info->dae_mix, display_buf_info->p, display_buf_info->c, + display_buf_info->n, display_buf_info->logo_pre, display_buf_info->logo_cur, + display_buf_info->mv_buf, display_buf_info->mc_phase); +} + diff --git a/drivers/media/dpss/dpss_hw_frc.h b/drivers/media/dpss/dpss_hw_frc.h index 55c95b608..dd9a5604d 100644 --- a/drivers/media/dpss/dpss_hw_frc.h +++ b/drivers/media/dpss/dpss_hw_frc.h @@ -14,7 +14,7 @@ void hw_cfg_dpss_mc_triggle(void); void hw_cfg_dpss_mc_slice(u32 frm_hsize, u32 frm_vsize, u32 slice_num); void hw_cfg_dpss_mc_bbd(u32 frm_hsize, u32 frm_vsize, u32 bbd_en, u32 bbd_sel, u32 src_hsize, u32 src_vsize); -void hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy); +bool hw_dpss_dpe_info_cfg(struct PRM_DPSS_TOP *prm_top, bool obuf_rdy); void hw_dpss_dpe_info_cfg_sw(u32 *base_addr, u32 *base_oft, u32 buf_num, u32 out_addr_en, struct PRM_DPSS_TOP *prm_top, u32 dae_frm_idx, u32 vdin_frm_idx); void hw_mc_vfcd_cfg_update(void); @@ -22,5 +22,8 @@ void dpss_dpe_dbg_cfg(void); void hw_afbcd_420_mc_bypass_cfg(struct PRM_DPSS_TOP *prm_top); void hw_config_dae_loop_tab(enum DPSS_FRC_RATIO frc_ratio, enum DPSS_FILM_MODE film_mode, u32 cfg_at_inp_site); +void frc_mc_cut_0(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr); +void frc_mc_cut_1(struct PRM_DPSS_TOP *prm_top, u32 src_from_nr); +void hw_update_display_info(struct display_buffer_info_s *display_buf_info); #endif diff --git a/drivers/media/dpss/dpss_rdma_frc.c b/drivers/media/dpss/dpss_rdma_frc.c index 375e7e829..7eb8e3e85 100644 --- a/drivers/media/dpss/dpss_rdma_frc.c +++ b/drivers/media/dpss/dpss_rdma_frc.c @@ -17,6 +17,7 @@ /*dma_get_cma_size_int_byte*/ #include #include +#include #endif //RUN_ON_ARM #include "dpss_base.h" #include "dpss_s.h" @@ -34,6 +35,8 @@ static unsigned int buf_alloced; static struct dpss_rdma_info rdma_info[RDMA_CHANNEL]; // 0: man 1:pre vsync 2:vsync +static unsigned int RDMA_IRQ_PRE_VSYNC = 0x1; +static unsigned int RDMA_IRQ_VSYNC = 0x2; static unsigned int rdma_handle_irq_pre_vs = 0x2; // pre vs tri bit:1 // static unsigned int rdma_handle_irq_vs = 0x10000000; //vs tri bit:28 static unsigned int rdma_handle_irq_vs = 0x1; //vs tri bit:0 @@ -148,44 +151,92 @@ void dpss_rdma_man_wr_tri(void) } } +int rdma_find_table_adr_pre_vs(u32 addr) +{ + int i; + int index = -1; + struct dpss_rdma_info *rdma_info_pre_vs; + + rdma_info_pre_vs = &rdma_info[RDMA_IRQ_PRE_VSYNC]; + if (rdma_info_pre_vs->rdma_item_count == 0) + return index; + dbg_a1("rdma_item_count:%d addr:%x\n", + rdma_info_pre_vs->rdma_item_count, addr); + for (i = (rdma_info_pre_vs->rdma_item_count - 1) * 2; i >= 0; i -= 2) { + if (rdma_info_pre_vs->rdma_table_addr[i] == addr) { + index = i; + dbg_a1("index:%d, table_addr[%d]=%x, table_value[%d]=%x", + index, i, rdma_info_pre_vs->rdma_table_addr[i], i + 1, + rdma_info_pre_vs->rdma_table_addr[i + 1]); + break; + } + } + return index; +} + +int rdma_find_table_adr_vs(u32 addr) +{ + int i; + int index = -1; + struct dpss_rdma_info *rdma_info_vs; + + rdma_info_vs = &rdma_info[RDMA_IRQ_VSYNC]; + if (rdma_info_vs->rdma_item_count == 0) + return index; + dbg_a1("rdma_item_count:%d addr:%x\n", + rdma_info_vs->rdma_item_count, addr); + for (i = (rdma_info_vs->rdma_item_count - 1) * 2; i >= 0; i -= 2) { + if (rdma_info_vs->rdma_table_addr[i] == addr) { + index = i; + dbg_a1("index:%d, table_addr[%d]=%x, table_value[%d]=%x", + index, i, rdma_info_vs->rdma_table_addr[i], i + 1, + rdma_info_vs->rdma_table_addr[i + 1]); + break; + } + } + return index; +} // pre_vs void dpss_rdma_pre_vs_table_config(unsigned int addr, unsigned int val) { unsigned int i; + struct dpss_rdma_info *rdma_info_pre_vs; // dbg_a1("%s addr:%#x, val:%#x\n", __func__, addr, val); - i = rdma_info[1].rdma_item_count; // pre_vs + rdma_info_pre_vs = &rdma_info[RDMA_IRQ_PRE_VSYNC]; + i = rdma_info_pre_vs->rdma_item_count; // pre_vs - if ((i + 1) * 8 > rdma_info[1].rdma_table_size) { + if ((i + 1) * 8 > rdma_info_pre_vs->rdma_table_size) { dbg_a1("dpss rdma in buffer overflow\n"); return; } - rdma_info[1].rdma_table_addr[i * 2] = addr & 0xffffffff; - rdma_info[1].rdma_table_addr[i * 2 + 1] = val & 0xffffffff; + rdma_info_pre_vs->rdma_table_addr[i * 2] = addr & 0xffffffff; + rdma_info_pre_vs->rdma_table_addr[i * 2 + 1] = val & 0xffffffff; - rdma_info[1].rdma_item_count++; + rdma_info_pre_vs->rdma_item_count++; } // vsync void dpss_rdma_vs_table_config(unsigned int addr, unsigned int val) { unsigned int i; + struct dpss_rdma_info *rdma_info_vs; // dbg_a1("%s addr:%#x, val:%#x\n", __func__, addr, val); + rdma_info_vs = &rdma_info[RDMA_IRQ_VSYNC]; + i = rdma_info_vs->rdma_item_count; // vs - i = rdma_info[2].rdma_item_count; // vs - - if ((i + 1) * 8 > rdma_info[2].rdma_table_size) { + if ((i + 1) * 8 > rdma_info_vs->rdma_table_size) { dbg_a1("dpss rdma in buffer overflow\n"); return; } - rdma_info[2].rdma_table_addr[i * 2] = addr & 0xffffffff; - rdma_info[2].rdma_table_addr[i * 2 + 1] = val & 0xffffffff; + rdma_info_vs->rdma_table_addr[i * 2] = addr & 0xffffffff; + rdma_info_vs->rdma_table_addr[i * 2 + 1] = val & 0xffffffff; - rdma_info[2].rdma_item_count++; + rdma_info_vs->rdma_item_count++; } int _dpss_rdma_wr_reg_pre_vs(u32 addr, u32 val) @@ -224,6 +275,69 @@ int _dpss_rdma_wr_reg_vs(u32 addr, u32 val) return 0; } +int _dpss_rdma_wr_bit_reg_pre_vs(u32 addr, u32 val, u32 start, u32 len) +{ + int index = -1; + u32 read_val, write_val, mask; + + if (rdma_enable()) { + dbg_a2("addr:%x, val:%d, start:%d, len:%d\n", + addr, val, start, len); + index = rdma_find_table_adr_pre_vs(addr); + if (index == -1) { + read_val = rd(addr); + mask = (((1L << len) - 1) << start); + write_val = read_val & ~mask; + write_val |= (val << start) & mask; + dpss_rdma_pre_vs_table_config(addr, write_val); + } else { + read_val = rdma_info[RDMA_IRQ_PRE_VSYNC].rdma_table_addr[index + 1]; + mask = (((1L << len) - 1) << start); + write_val = read_val & ~mask; + write_val |= (val << start) & mask; + rdma_info[RDMA_IRQ_PRE_VSYNC].rdma_table_addr[index + 1] = write_val; + dbg_a2("update bits:addr:0x%04x, reg_val<0x%08x->0x%08x>\n", + addr, read_val, write_val); + } + } else { + w_reg_bit(addr, val, start, len); + dbg_a2("rdma off, channel in addr:0x%04x, val:0x%08x\n", + addr, val); + } + return 0; +} + +int _dpss_rdma_wr_bit_reg_vs(u32 addr, u32 val, u32 start, u32 len) +{ + int index = -1; + u32 read_val, write_val, mask; + + if (rdma_enable()) { + dbg_a2("addr:%x, val:%d, start:%d, len:%d\n", + addr, val, start, len); + index = rdma_find_table_adr_vs(addr); + if (index == -1) { + read_val = rd(addr); + mask = (((1L << len) - 1) << start); + write_val = read_val & ~mask; + write_val |= (val << start) & mask; + dpss_rdma_vs_table_config(addr, write_val); + } else { + read_val = rdma_info[RDMA_IRQ_VSYNC].rdma_table_addr[index + 1]; + mask = (((1L << len) - 1) << start); + write_val = read_val & ~mask; + write_val |= (val << start) & mask; + rdma_info[RDMA_IRQ_VSYNC].rdma_table_addr[index + 1] = write_val; + dbg_a2("update bits:addr:0x%04x, reg_val<0x%08x->0x%08x>\n", + addr, read_val, write_val); + } + } else { + w_reg_bit(addr, val, start, len); + dbg_a2("rdma off, channel in addr:0x%04x, val:0x%08x\n", + addr, val); + } + return 0; +} void DPSS_RDMA_WR_PRE_VS(u32 addr, u32 val) { if (unlikely(addr < 0x8000 || addr > 0xffff)) { @@ -235,6 +349,15 @@ void DPSS_RDMA_WR_PRE_VS(u32 addr, u32 val) } EXPORT_SYMBOL(DPSS_RDMA_WR_PRE_VS); +void DPSS_RDMA_WR_BIT_PRE_VS(u32 addr, u32 val, u32 start, u32 len) +{ + if (unlikely(addr < 0x8000 || addr > 0xffff)) { + DBG_ERR("rdma not support addr:%x\n", addr); + return; + } + _dpss_rdma_wr_bit_reg_pre_vs(addr, val, start, len); +} +EXPORT_SYMBOL(DPSS_RDMA_WR_BIT_PRE_VS); void DPSS_RDMA_WR_VS(u32 addr, u32 val) { if (unlikely(addr < 0x8000 || addr > 0xffff)) { @@ -245,6 +368,15 @@ void DPSS_RDMA_WR_VS(u32 addr, u32 val) _dpss_rdma_wr_reg_vs(addr, val); } EXPORT_SYMBOL(DPSS_RDMA_WR_VS); +void DPSS_RDMA_WR_BIT_VS(u32 addr, u32 val, u32 start, u32 len) +{ + if (unlikely(addr < 0x8000 || addr > 0xffff)) { + DBG_ERR("rdma not support addr:%x\n", addr); + return; + } + _dpss_rdma_wr_bit_reg_vs(addr, val, start, len); +} +EXPORT_SYMBOL(DPSS_RDMA_WR_BIT_VS); void irq_rdma(void) { @@ -267,6 +399,14 @@ void irq_rdma(void) } } +void post_vsync_signal_to_dpss_rdma(void) +{ +//#ifdef USE_FRC_VS_RDMA + if (!rdma_enable()) + return; + dpss_rdma_auto_wr_tri(RDMA_IRQ_VSYNC); +//#endif +} void dpss_rdma_auto_wr_tri(u32 handle) { unsigned int handle_irq = 0x2; @@ -279,15 +419,15 @@ void dpss_rdma_auto_wr_tri(u32 handle) if (!rdma_enable()) return; - if (handle == 1) + if (handle == RDMA_IRQ_PRE_VSYNC) handle_irq = rdma_handle_irq_pre_vs; - else if (handle == 2) + else if (handle == RDMA_IRQ_VSYNC) handle_irq = rdma_handle_irq_vs; - dbg_a2("%s handle:%d auto count:%d\n", __func__, - handle, rdma_info[handle].rdma_item_count); + // dbg_a2("%s handle:%d auto count:%d\n", __func__, + // handle, rdma_info[handle].rdma_item_count); - if (1) { + if (rdma_info_p->rdma_item_count > 0) { //auto RDMA // w_reg_bit(rdma_regadr->trigger_mask_reg, 0, // rdma_regadr->trigger_mask_reg_bitpos, 1); diff --git a/drivers/media/dpss/dpss_rdma_frc.h b/drivers/media/dpss/dpss_rdma_frc.h index 8e41c441e..9d210962d 100644 --- a/drivers/media/dpss/dpss_rdma_frc.h +++ b/drivers/media/dpss/dpss_rdma_frc.h @@ -58,6 +58,8 @@ int rdma_enable(void); // void dpss_rdma_auto_wr_reg(unsigned int addr, unsigned int val); void dpss_rdma_auto_wr_tri(u32 handle); void DPSS_RDMA_WR_PRE_VS(u32 addr, u32 val); +void DPSS_RDMA_WR_BIT_PRE_VS(u32 addr, u32 val, u32 start, u32 len); void DPSS_RDMA_WR_VS(u32 addr, u32 val); +void DPSS_RDMA_WR_BIT_VS(u32 addr, u32 val, u32 start, u32 len); #endif //__DPSS_RDMA_FRC_H__ diff --git a/drivers/media/dpss/dpss_s_frc.c b/drivers/media/dpss/dpss_s_frc.c index 216eb7b0a..a2e8352d5 100644 --- a/drivers/media/dpss/dpss_s_frc.c +++ b/drivers/media/dpss/dpss_s_frc.c @@ -53,6 +53,7 @@ static struct dpss_frc_fw_data_s fw_data; // important 2021_0510 static const char frc_alg_def_ver[] = "alg_ver:default"; struct dpss_queue mc_ibuf_q; +struct display_queue display_buf_q; int enable_mc_link = 1; int frc_delay_dbg; // for avsync debug @@ -266,6 +267,17 @@ static struct class_attribute frc_class_attrs[] = { __ATTR_NULL }; +static inline unsigned int frc_align_up(unsigned int x, unsigned int a) +{ + // return (x + (a - 1)) & ~(a - 1); + return (x + a) & ~(a - 1); +} + +static inline unsigned int frc_align_down(unsigned int x, unsigned int a) +{ + return x & ~(a - 1); +} + unsigned int dpss_dbg_in_fmt_frc; module_param_named(dpss_dbg_in_fmt_frc, dpss_dbg_in_fmt_frc, uint, 0664); @@ -1030,8 +1042,6 @@ static void frc_state_init(void) } state_st = &pchip_st->state_st; - state_st->pre_idx = 0; - state_st->cur_idx = 0; state_st->frc_src = FROM_DEC; state_st->src0_disp_obuf_rdy = 0; state_st->mc_bypass = true; @@ -1050,12 +1060,19 @@ static void frc_state_init(void) state_st->is_pause_state_last_frmae = false; state_st->is_wait_mc_state = false; state_st->need_drop_dd = false; + state_st->dae_ready = false; + state_st->dpe_ready = false; + state_st->dpe_mix = false; + state_st->mv_buf_idx = 0; if (state_st->force_n2m == 0) memset(&state_st->n2m_status, 0, sizeof(state_st->n2m_status)); + memset(&state_st->me_pcn_st, 0, sizeof(state_st->me_pcn_st)); + memset(&state_st->mc_disp_st, 0, sizeof(state_st->mc_disp_st)); memset(&pchip_st->win_st, 0, sizeof(struct frc_cut_win_s)); memset(&state_st->frc_int_st, 0, sizeof(state_st->frc_int_st)); memset(&g_frc_work_stats, 0, sizeof(struct frc_state_s)); vpu_initqueue(&inp_bufQ); + display_init_queue(&display_buf_q); } static void frc_compress_fmt_parse(struct dpss_sub_vf_s *vfs) @@ -1123,6 +1140,16 @@ void init_frc_pre(struct dpss_sub_vf_s *vfs) frc_top->vsize = dpss_en_pps ? pps_out_h : prm_top->frm_vsize; frc_top->auto_align_en = 0; frc_top->motion_ctrl = prm_top->amdv_2_frc_frm; + frc_top->hsize = prm_top->frm_hsize; + frc_top->vsize = prm_top->frm_vsize; + frc_top->mc_hsize = prm_top->frm_hsize; + frc_top->mc_vsize = prm_top->frm_vsize; + frc_top->crop_top = 0; + frc_top->crop_left = 0; + frc_top->crop_bottom = 0; + frc_top->crop_right = 0; + frc_top->need_dpe_mix = 0; + frc_top->dpe_mix_cnt = 0; if (pfw_data->frc_input_cfg) pfw_data->frc_input_cfg(pfw_data); @@ -1143,6 +1170,7 @@ void init_frc_pre(struct dpss_sub_vf_s *vfs) bbd_init = 1; frc_state_init(); dpss_initqueue(&mc_ibuf_q); + display_init_queue(&display_buf_q); frc_compress_fmt_parse(vfs); frc_fw_alg_ctrl = &pfw_data->frc_fw_alg_ctrl; prm_top->frc_melogo_en = frc_fw_alg_ctrl->melogo_en; @@ -1244,6 +1272,8 @@ void init_frc_post(struct dpss_ch_s *pch, struct dpss_sub_vf_s *vfs) if (state_st->mc_cut_position == 1) w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 1, 8, 1); + else + w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0, 8, 1); w_reg_bit(DPSS_REG_DAE_WRPT_FULL_NUM, dae_wrpt_full_num, 0, 4); w_reg_bit(FRC_REG_CURSOR, 0, 0, 3); //cancel dae force mix @@ -1903,7 +1933,7 @@ void frc_update_ds_scale(struct vframe_s *vfm) } } -void frc_cut_win_check_2_step(struct frc_win_s *win, struct vframe_s *vfm) +void frc_cut_win_chk_2_step(struct frc_win_s *win, struct vframe_s *vfm) { struct PRM_DPSS_TOP *prm_top; struct frc_chip_st *pchip_st; @@ -1913,7 +1943,18 @@ void frc_cut_win_check_2_step(struct frc_win_s *win, struct vframe_s *vfm) unsigned int src_width, src_height; struct frc_state_s *state_st; static bool win_size_chg_flag; - u32 temp_value; // src_from_nr + u32 src_from_nr; + u32 align_base_h = 8, align_base_v = 8; + u32 win_hbgn_align = 0; + u32 win_hend_align = 0; + u32 win_vbgn_align = 0; + u32 win_vend_align = 0; + u16 mc_hsize = 0; + u16 mc_vsize = 0; + u16 crop_top = 0; + u16 crop_left = 0; + u16 crop_bottom = 0; + u16 crop_right = 0; pchip_st = dpss_get_frc_st(); pfw_data = (struct dpss_frc_fw_data_s *)dpss_get_fw_data(); @@ -1925,8 +1966,12 @@ void frc_cut_win_check_2_step(struct frc_win_s *win, struct vframe_s *vfm) prm_top = prm_dpss_top; state_st = &pchip_st->state_st; frc_top = &pfw_data->frc_top_type; - if (frc_top->mc_cut_en == 0) - return; + + if (state_st->mc_cut_position == 1) + return; // cut after mc + + //if (frc_top->mc_cut_en == 0) + // return; if (win->x_size == 0 || win->y_size == 0) { dbg_f1("%s: win size = 0, chg_fleg reset 0\n", __func__); @@ -1940,7 +1985,15 @@ void frc_cut_win_check_2_step(struct frc_win_s *win, struct vframe_s *vfm) src_width = vfm->width; src_height = vfm->height; } - // pr_frc(1, "src_size <%d,%d>\n", src_width, src_height); + + if (src_width > 1920) { + align_base_h = 16; + if (src_height > 1080) + align_base_v = 16; + } else if (src_height > 1080) { + align_base_h = 16; + align_base_v = 16; + } win_s = &pchip_st->win_st; if (win_s->win_hbgn != win->x_st || win_s->win_hend != win->x_end || win_s->win_vbgn != win->y_st || win_s->win_vend != win->y_end) { @@ -1963,53 +2016,82 @@ void frc_cut_win_check_2_step(struct frc_win_s *win, struct vframe_s *vfm) win->orig_w, win->orig_h); dbg_f1("frc_cut_win_1_step:win_size_chg_flag = %d\n", win_size_chg_flag); - return; + if (frc_top->mc_cut_en == 0) + return; } if (win_size_chg_flag == 1) { - //if (prm_top->dpss_mode == DPSS_FRC_MODE) - // src_from_nr = 0; - //else - // src_from_nr = 1; + if (prm_top->dpss_mode == DPSS_FRC_MODE) + src_from_nr = 0; + else + src_from_nr = 1; if (win_s->cut_win_en == 1) { - if (state_st->mc_cut_position == 1) { - prm_top->cut_win_en = 0; - prm_top->cut_win_position = 1; - //w_reg_bit(DPSS_DPE_MC_WIN_CUT_H, win_s->win_hbgn, 0, 13); - //w_reg_bit(DPSS_DPE_MC_WIN_CUT_H, win_s->win_hend, 16, 13); - temp_value = win_s->win_hbgn | (win_s->win_hend << 16); - wr(DPSS_DPE_MC_WIN_CUT_H, temp_value); - //w_reg_bit(DPSS_DPE_MC_WIN_CUT_V, win_s->win_vbgn, 0, 13); - //w_reg_bit(DPSS_DPE_MC_WIN_CUT_V, win_s->win_vend, 16, 13); - temp_value = win_s->win_vbgn | (win_s->win_vend << 16); - wr(DPSS_DPE_MC_WIN_CUT_V, temp_value); - w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 1, 8, 1); - } else { - prm_top->cut_win_en = 1; - prm_top->cut_win_position = 0; - prm_top->prm_cut_win.frm_hsize = src_width; - prm_top->prm_cut_win.frm_vsize = src_height; - prm_top->prm_cut_win.win_hsize = win_s->win_hsize; - prm_top->prm_cut_win.win_vsize = win_s->win_vsize; - prm_top->prm_cut_win.win_hbgn = win_s->win_hbgn; - prm_top->prm_cut_win.win_hend = win_s->win_hend; - prm_top->prm_cut_win.win_vbgn = win_s->win_vbgn; - prm_top->prm_cut_win.win_vend = win_s->win_vend; - // hw_cfg_dpss_top(prm_top); - //hw_cfg_dpss_mc_ini(prm_top, src_from_nr); - } - dbg_f1("frc_cut_win_en=<%d, %d> mc_ini_1\n", + prm_top->cut_win_en = 1; + prm_top->prm_cut_win.frm_hsize = src_width; + prm_top->prm_cut_win.frm_vsize = src_height; + + win_hbgn_align = frc_align_down(win_s->win_hbgn, align_base_h); + win_hend_align = frc_align_up(win_s->win_hend, align_base_h) - 1; + win_vbgn_align = frc_align_down(win_s->win_vbgn, align_base_v); + win_vend_align = frc_align_up(win_s->win_vend, align_base_v) - 1; + if (win_vend_align > prm_top->frm_vsize) + win_vend_align = win_s->win_vend; + + prm_top->prm_cut_win.win_hbgn_align = win_hbgn_align; + prm_top->prm_cut_win.win_hend_align = win_hend_align; + prm_top->prm_cut_win.win_vbgn_align = win_vbgn_align; + prm_top->prm_cut_win.win_vend_align = win_vend_align; + + prm_top->prm_cut_win.win_hsize_align = win_hend_align - win_hbgn_align + 1; + prm_top->prm_cut_win.win_vsize_align = win_vend_align - win_vbgn_align + 1; + + mc_hsize = prm_top->prm_cut_win.win_hsize_align; + mc_vsize = prm_top->prm_cut_win.win_vsize_align; + crop_top = win_vbgn_align; + crop_left = win_hbgn_align; + crop_bottom = src_height - 1 - win_vend_align; + crop_right = frc_align_up(src_width, align_base_v) - 1 - win_hend_align; + + prm_top->prm_cut_win.win_hbgn = win_s->win_hbgn - win_hbgn_align; + prm_top->prm_cut_win.win_hend = win_s->win_hend - win_hbgn_align; + prm_top->prm_cut_win.win_vbgn = win_s->win_vbgn - win_vbgn_align; + prm_top->prm_cut_win.win_vend = win_s->win_vend - win_vbgn_align; + + prm_top->prm_cut_win.win_hsize = prm_top->prm_cut_win.win_hsize_align; + prm_top->prm_cut_win.win_vsize = prm_top->prm_cut_win.win_vsize_align; + dbg_f1("frc_cut_win_1_step:prm_cut_win point <%d,%d,%d,%d>\n", + prm_top->prm_cut_win.win_hbgn, + prm_top->prm_cut_win.win_hend, + prm_top->prm_cut_win.win_vbgn, + prm_top->prm_cut_win.win_vend); + dbg_f1("frc_cut_win_1_step:prm_cut_win size <%d,%d>,<%d,%d>\n", + prm_top->prm_cut_win.win_hsize, + prm_top->prm_cut_win.win_vsize, + prm_top->prm_cut_win.win_hsize_align, + prm_top->prm_cut_win.win_vsize_align); + + if (frc_top->mc_cut_en == 0) + frc_mc_cut_0(prm_top, src_from_nr); + else + frc_mc_cut_1(prm_top, src_from_nr); + //dpss_rdma_auto_wr_tri(2); + update_mc_cut_size_to_fw(mc_hsize, mc_vsize, + crop_top, crop_left, crop_bottom, crop_right); + dbg_f1("cut_win_en=<%d, %d> frc_mc_cut_1_1\n", win_s->cut_win_en, prm_top->cut_win_en); - } else { // (win_s->cut_win_en is 0) - if (state_st->mc_cut_position == 1) { - prm_top->cut_win_position = 0; - w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 0, 8, 1); - } else if (prm_top->cut_win_en == 1) { - prm_top->cut_win_en = 0; - w_reg_bit(DPSS_DPE_MC_MIF_CTRL0, 1, 0, 8); - } - //hw_cfg_dpss_mc_ini(prm_top, src_from_nr); - dbg_f1("frc_cut_win_en=<%d, %d> mc_ini_2\n", + } else if (win_s->cut_win_en == 0 && prm_top->cut_win_en == 1) { + prm_top->cut_win_en = 0; + if (frc_top->mc_cut_en == 0) + frc_mc_cut_0(prm_top, src_from_nr); + else + frc_mc_cut_1(prm_top, src_from_nr); + //dpss_rdma_auto_wr_tri(2); + update_mc_cut_size_to_fw(prm_top->frm_hsize, prm_top->frm_vsize, + 0, 0, 0, 0); + dbg_f1("cut_win_en=<%d, %d> frc_mc_cut_1_2\n", + win_s->cut_win_en, prm_top->cut_win_en); + } else { + dbg_f1("cut_win_en=<%d, %d>\n", win_s->cut_win_en, prm_top->cut_win_en); } dbg_f1("frc_cut_win_2_step: win set <%d, %d, %d, %d>\n", @@ -2041,10 +2123,9 @@ void frc_cut_win_set_2_step(struct frc_win_s *win, struct vframe_s *vfm) prm_top = prm_dpss_top; state_st = &pchip_st->state_st; frc_top = &pfw_data->frc_top_type; - if (frc_top->mc_cut_en == 0) - return; + if (state_st->mc_cut_position == 0) - return; + return; // // cut before mc prm_top->cut_win_en = 0; if (vfm->type & VIDTYPE_COMPRESS) { @@ -2077,7 +2158,7 @@ void frc_cut_win_set_2_step(struct frc_win_s *win, struct vframe_s *vfm) DPSS_RDMA_WR_VS(DPSS_DPE_MC_WIN_CUT_H, temp_value); temp_value1 = win_s->win_vbgn | (win_s->win_vend << 16); DPSS_RDMA_WR_VS(DPSS_DPE_MC_WIN_CUT_V, temp_value1); - dpss_rdma_auto_wr_tri(2); + // dpss_rdma_auto_wr_tri(2); // use new rdam function win_size_chg_flag = 0; } else { win_size_chg_flag = 1; @@ -2270,7 +2351,7 @@ int pvpp_display_frc(struct vframe_s *vfm, state_st = &pchip_st->state_st; - if (!state_st->dpss_reg) + if (!state_st->dpss_reg || !state_st->dpe_ready) return ret; get_nr_buf_idx(vfm, state_st); @@ -2304,7 +2385,7 @@ int pvpp_display_frc(struct vframe_s *vfm, if (in_para->win.x_size == 0 || in_para->win.y_size == 0) dbg_f1("%s in_para win_size (%d, %d)\n", __func__, in_para->win.x_size, in_para->win.y_size); - // frc_cut_win_check_2_step(&in_para->win, vfm); + frc_cut_win_chk_2_step(&in_para->win, vfm); frc_cut_win_set_2_step(&in_para->win, vfm); frc_transform_check(vfm, in_para); check_readback_reg(BIT_0); @@ -2654,6 +2735,21 @@ void frc_set_mc_bypass(u8 bypass) dbg_h1("%s bypass:%d\n", __func__, bypass); } +void frc_set_mc_bypass_rdma(u8 bypass) +{ + if (bypass == 1) { + DPSS_RDMA_WR_BIT_PRE_VS(FRC_MC_DBG_PHASE_EN, 0x3, 16, 2); + DPSS_RDMA_WR_BIT_PRE_VS(FRC_MC_HW_CTRL0, 0x1, 0, 2); + } else if (bypass == 3) { + DPSS_RDMA_WR_BIT_PRE_VS(FRC_MC_DBG_PHASE_EN, 0x3, 16, 2); + DPSS_RDMA_WR_BIT_PRE_VS(FRC_MC_HW_CTRL0, 0x3, 0, 2); + } else if (bypass == 0) { + DPSS_RDMA_WR_BIT_PRE_VS(FRC_MC_DBG_PHASE_EN, 0x0, 16, 2); + DPSS_RDMA_WR_BIT_PRE_VS(FRC_MC_HW_CTRL0, 0x0, 0, 2); + } + dbg_h1("%s bypass:%d\n", __func__, bypass); +} + void dpss_frc_set_mc_bypass(u8 enable_mc) { struct dpss_frc_fw_data_s *pfw_data; @@ -3842,3 +3938,28 @@ void dpss_frc_resume(void) if (pfw_data->frc_fw_reinit) pfw_data->frc_fw_reinit(pfw_data); } + +void update_mc_cut_size_to_fw(u16 mc_hsize, u16 mc_vsize, + u16 crop_top, u16 crop_left, u16 crop_bottom, u16 crop_right) +{ + struct dpss_frc_fw_data_s *pfw_data; + struct dpss_frc_top_type_s *frc_top; + + pfw_data = (struct dpss_frc_fw_data_s *)dpss_get_fw_data(); + if (!pfw_data) { + DBG_ERR("%s: frc_fw is null\n", __func__); + return; + } + + frc_top = &pfw_data->frc_top_type; + frc_top->mc_hsize = mc_hsize; + frc_top->mc_vsize = mc_vsize; + frc_top->crop_top = crop_top; + frc_top->crop_left = crop_left; + frc_top->crop_bottom = crop_bottom; + frc_top->crop_right = crop_right; + + if (pfw_data->frc_input_cfg) + pfw_data->frc_input_cfg(pfw_data); +} + diff --git a/drivers/media/dpss/dpss_s_frc.h b/drivers/media/dpss/dpss_s_frc.h index d1f206c44..7450c6b7c 100644 --- a/drivers/media/dpss/dpss_s_frc.h +++ b/drivers/media/dpss/dpss_s_frc.h @@ -31,6 +31,7 @@ void dpss_enable_mc_link(bool enable); void check_dpss_frc_status(void); void frc_undone_check(void); void frc_set_mc_bypass(u8 bypass); +void frc_set_mc_bypass_rdma(u8 bypass); void dpss_frc_check_reg_stats(void); void dpss_frc_check_undone_stats(void); @@ -52,4 +53,9 @@ int dpss_frc_tell_alg_vendor(u8 vendor_info); void dpss_frc_get_memc_gmv(struct memc_gmv_s *memc_gmv); void dpss_frc_resume(void); +//fw +void update_n2m_info_to_fw(enum DPSS_FRC_RATIO frc_ratio); +void update_mc_cut_size_to_fw(u16 mc_hsize, u16 mc_vsize, + u16 crop_top, u16 crop_left, u16 crop_bottom, u16 crop_right); + #endif diff --git a/drivers/media/dpss/dpss_sys.h b/drivers/media/dpss/dpss_sys.h index d2918fa70..2db6a8315 100644 --- a/drivers/media/dpss/dpss_sys.h +++ b/drivers/media/dpss/dpss_sys.h @@ -389,6 +389,19 @@ struct frc_interrupt_s { u64 frc_vsync_timestamp; }; +struct me_pcn_s { + unsigned p:4; + unsigned c:4; + unsigned n:4; + unsigned use:4; +}; + +struct mc_disp_s { + u8 wr_idx; + u8 disp_idx; + u8 step; +}; + struct frc_work_s { // struct work_struct clk_work; struct work_struct print_work; @@ -421,18 +434,21 @@ struct frc_state_s { bool force_disable_dpe_mix; bool force_disable_check_fallback; bool is_dos; + bool dae_ready; + bool dpe_ready; + u8 dpe_mix; + u8 mv_buf_idx; u8 check_fallback; - u8 detect_threshold; + u8 detect_threshold; u8 dae0_bypass_mode; u8 dst_buf_th; u8 enable_frclink_cnt; u8 nr_buf_idx; u8 force_mc_cur_idx; + u8 mc_drop_idx; u32 mc_bypass_cnt; u32 force_mc_byp_cnt; u32 pre_vsync_offset; - unsigned int pre_idx; - unsigned int cur_idx; unsigned int put_frame_cnt; enum compress_fmt_s compr_sel; unsigned int big_fmt; @@ -454,6 +470,8 @@ struct frc_state_s { struct undone_s undone_stats; struct n2m_s n2m_status; struct frc_interrupt_s frc_int_st; + struct me_pcn_s me_pcn_st; + struct mc_disp_s mc_disp_st; struct dpss_frc_i_s *src_frc_inp[16]; }; diff --git a/drivers/media/dpss/hw/dpss_intf.c b/drivers/media/dpss/hw/dpss_intf.c index 65a3dfc1a..db59795b1 100644 --- a/drivers/media/dpss/hw/dpss_intf.c +++ b/drivers/media/dpss/hw/dpss_intf.c @@ -12,6 +12,7 @@ #include "../dpss_base.h" #include "../dpss_s.h" #include "../dpss_sys.h" +#include "../dpss_func.h" #include @@ -3143,8 +3144,6 @@ void cfg_mc_sub_rdmif(struct PRM_INTF_TYPE *prm_mif, s32 mif_index, s32 regs_ofst_sub3 = (0xe060 - 0xc100); //ary addr change *4 s32 regs_ofst; - dbg_h2("cfg_mc_sub_rd_mifstart\n"); - switch (mif_index) { case 0: regs_ofst = regs_ofst_sub0; @@ -3188,6 +3187,58 @@ void cfg_mc_sub_rdmif(struct PRM_INTF_TYPE *prm_mif, s32 mif_index, dbg_h2("cfg_mc_sub_rd_mif end\n"); } +void hw_cfg_mc_sub_rdmif(struct PRM_INTF_TYPE *prm_mif, s32 mif_index, + s32 only_change_addr) +{ + s32 regs_ofst_sub0 = (0xe000 - 0xc100); //ary addr change *4 + s32 regs_ofst_sub1 = (0xe020 - 0xc100); //ary addr change *4 + s32 regs_ofst_sub2 = (0xe040 - 0xc100); //ary addr change *4 + s32 regs_ofst_sub3 = (0xe060 - 0xc100); //ary addr change *4 + s32 regs_ofst; + + switch (mif_index) { + case 0: + regs_ofst = regs_ofst_sub0; + break; + case 1: + regs_ofst = regs_ofst_sub1; + break; + case 2: + regs_ofst = regs_ofst_sub2; + break; + case 3: + regs_ofst = regs_ofst_sub3; + break; + default: + regs_ofst = regs_ofst_sub0; + break; + } + + s32 stride = prm_mif->stride; + s32 baddr = prm_mif->src_baddr[0]; + s32 x_start = prm_mif->slc_x_st[0]; + s32 x_end = prm_mif->slc_x_ed[0]; + s32 y_start = prm_mif->slc_y_st[0]; + s32 y_end = prm_mif->slc_y_ed[0]; + s32 bits_mode = prm_mif->bits_mode; + s32 pack_mode = prm_mif->pack_mode; + u32 tmp_reg_value; + + if (only_change_addr == 1) { + DPSS_RDMA_WR_VS(regs_ofst + VPU_VPSS_RMIF_CTRL4, baddr); + } else { + tmp_reg_value = rd(regs_ofst + VPU_VPSS_RMIF_CTRL3); + tmp_reg_value = update_reg_val(tmp_reg_value, stride, 0, 13); + DPSS_RDMA_WR_VS(regs_ofst + VPU_VPSS_RMIF_CTRL3, tmp_reg_value); + DPSS_RDMA_WR_VS(regs_ofst + VPU_VPSS_RMIF_CTRL4, baddr); + DPSS_RDMA_WR_VS(regs_ofst + VPU_VPSS_RMIF_SCOPE_X, (x_end << 16 | x_start)); + DPSS_RDMA_WR_VS(regs_ofst + VPU_VPSS_RMIF_SCOPE_Y, (y_end << 16 | y_start)); + tmp_reg_value = rd(regs_ofst + VPU_VPSS_RMIF_CTRL5); + tmp_reg_value = update_reg_val(tmp_reg_value, bits_mode << 3 | pack_mode, 0, 7); + DPSS_RDMA_WR_VS(regs_ofst + VPU_VPSS_RMIF_CTRL5, tmp_reg_value); + } +} + void cfg_lcevc_top(u32 lcevc_en, u32 src1_frm_hsize, //normal_afbcd_hsize, input u32 src1_frm_vsize, u32 src1_head_ybaddr, u32 src1_body_ybaddr, u32 src1_head_cbaddr, diff --git a/drivers/media/dpss/hw/dpss_intf.h b/drivers/media/dpss/hw/dpss_intf.h index 95951b87a..20ec342e3 100644 --- a/drivers/media/dpss/hw/dpss_intf.h +++ b/drivers/media/dpss/hw/dpss_intf.h @@ -211,4 +211,6 @@ void cfg_viu_pix_rdmif_baddr(s32 mif_index, u32 ybaddr, u32 cbbaddr, void cfg_vfcd_rdmif_ext(enum dpss_mif_e mif_index, struct PRM_INTF_TYPE *prm_mif); void dpss_dae_wrmif_cfg_brst_len(u32 burst_len); void dpss_dae_rdmif_cfg_brst_len(u32 burst_len); +void hw_cfg_mc_sub_rdmif(struct PRM_INTF_TYPE *prm_mif, s32 mif_index, + s32 only_change_addr); #endif diff --git a/drivers/media/dpss/hw/dpss_lib.c b/drivers/media/dpss/hw/dpss_lib.c index 37d709c0d..276e647d6 100644 --- a/drivers/media/dpss/hw/dpss_lib.c +++ b/drivers/media/dpss/hw/dpss_lib.c @@ -61,10 +61,10 @@ bool dpss_is_queue_empty(struct dpss_queue *queue) bool dpss_enqueue(struct dpss_queue *queue, int value) { - if ((queue->rear + 1) % QUEEN_NUM == queue->front) + if ((queue->rear + 1) % DPSS_QUEEN_NUM == queue->front) return 0; queue->data[queue->rear] = value; - queue->rear = (queue->rear + 1) % QUEEN_NUM; + queue->rear = (queue->rear + 1) % DPSS_QUEEN_NUM; return 1; } @@ -85,7 +85,7 @@ bool dpss_put_queue(struct dpss_queue *queue, int *value, bool *empty) return 0; } *value = queue->data[queue->front]; - queue->front = (queue->front + 1) % QUEEN_NUM; + queue->front = (queue->front + 1) % DPSS_QUEEN_NUM; return 1; } @@ -103,8 +103,40 @@ void dpss_put_last_queue(struct dpss_queue *queue, bool *empty, u32 *value) if (queue->rear != 0) tmp_idx--; else - tmp_idx = QUEEN_NUM - 1; + tmp_idx = DPSS_QUEEN_NUM - 1; *value = queue->data[tmp_idx]; } +void display_init_queue(struct display_queue *queue) +{ + memset(queue, 0x0, sizeof(struct display_queue)); +} + +bool display_queue_is_empty(struct display_queue *queue) +{ + return queue->inp_idx == queue->drop_idx; +} + +bool display_queue_put(struct display_queue *queue) +{ + u8 drop_index = queue->drop_idx; + u8 mc_index = queue->mc_idx; + + if (mc_index < drop_index) + mc_index += DPSS_QUEEN_NUM; + + return mc_index > drop_index ? true : false; +} + +u8 get_dst_buf_cnt(struct display_queue *queue) +{ + u8 drop_index = queue->drop_idx; + u8 inp_index = queue->inp_idx; + + if (inp_index < drop_index) + inp_index += DPSS_QUEEN_NUM; + + return inp_index - drop_index; +} + diff --git a/drivers/media/dpss/hw/dpss_lib.h b/drivers/media/dpss/hw/dpss_lib.h index d7718f81e..85ce4a7cd 100644 --- a/drivers/media/dpss/hw/dpss_lib.h +++ b/drivers/media/dpss/hw/dpss_lib.h @@ -8,7 +8,32 @@ #include #include "dpss_param.h" -#define QUEEN_NUM 60 +#define DPSS_QUEEN_NUM 10 + +struct display_buffer_info_s { + u8 dae_mix; + u8 p; + u8 c; + u8 n; + u8 logo_pre; + u8 logo_cur; + u8 mv_buf; + u8 mc_phase; +}; + +struct dpss_queue { + u32 data[DPSS_QUEEN_NUM]; + u16 front; + u16 rear; +}; + +struct display_queue { + struct display_buffer_info_s data[DPSS_QUEEN_NUM]; + u8 drop_idx; + u8 mc_idx; + u8 inp_idx; +}; + void vpu_initqueue(struct Vpu_queue *queue); bool vpu_is_queue_empty(struct Vpu_queue *queue); bool vpu_enqueue(struct Vpu_queue *queue, int value); @@ -19,6 +44,11 @@ bool dpss_peek_queue(struct dpss_queue *queue, int *value, bool *empty); bool dpss_put_queue(struct dpss_queue *queue, int *value, bool *empty); void dpss_put_last_queue(struct dpss_queue *queue, bool *empty, u32 *value); +void display_init_queue(struct display_queue *queue); +bool display_queue_is_empty(struct display_queue *queue); +bool display_queue_put(struct display_queue *queue); +u8 get_dst_buf_cnt(struct display_queue *queue); + extern struct Vpu_queue inp_bufQ; extern unsigned int g_SIM_FRM_NUM; extern unsigned int g_SIM_FRM_NUM_SRC1; diff --git a/drivers/media/dpss/hw/dpss_param.h b/drivers/media/dpss/hw/dpss_param.h index 27ce1758e..bbbbda7c6 100644 --- a/drivers/media/dpss/hw/dpss_param.h +++ b/drivers/media/dpss/hw/dpss_param.h @@ -206,10 +206,16 @@ struct DPSS_CUT_WIN { u32 frm_vsize; u32 win_hsize; u32 win_vsize; + u32 win_hsize_align; + u32 win_vsize_align; u32 win_hbgn; u32 win_hend; u32 win_vbgn; u32 win_vend; + u32 win_hbgn_align; + u32 win_hend_align; + u32 win_vbgn_align; + u32 win_vend_align; }; struct PRM_MC_SET { diff --git a/drivers/media/dpss/sys_def.h b/drivers/media/dpss/sys_def.h index 8a96fb641..0ea26906c 100644 --- a/drivers/media/dpss/sys_def.h +++ b/drivers/media/dpss/sys_def.h @@ -370,6 +370,7 @@ extern u32 mc_undone_cnt; extern unsigned int dpss_dbg_step;//tmp extern int enable_mc_link; extern struct dpss_queue mc_ibuf_q; +extern struct display_queue display_buf_q; extern unsigned int dpss_t6x_direct; extern unsigned int dpss_en_dct; diff --git a/drivers/media/video_sink/video_func.c b/drivers/media/video_sink/video_func.c index f46d392c7..58975296b 100644 --- a/drivers/media/video_sink/video_func.c +++ b/drivers/media/video_sink/video_func.c @@ -6223,6 +6223,9 @@ exit: if (vd_fake_func[i].vd_late_process) vd_fake_func[i].vd_late_process(0xff, i); } +#ifdef CONFIG_AMLOGIC_DPSS_PROCESS + post_vsync_signal_to_dpss_rdma(); +#endif LATE_PROC: misc_late_proc(); for (i = 0; i < MAX_VD_LAYER; i++) diff --git a/include/linux/amlogic/media/dpss/dpss_frc.h b/include/linux/amlogic/media/dpss/dpss_frc.h index c6dfde638..edfe96968 100644 --- a/include/linux/amlogic/media/dpss/dpss_frc.h +++ b/include/linux/amlogic/media/dpss/dpss_frc.h @@ -66,6 +66,7 @@ int pvpp_sw_frc(bool on); void frc_disable_plink_notify(bool async); void frc_plink_state_changed_notify(void); void irq_display(void); +void post_vsync_signal_to_dpss_rdma(void); int dpss_frc_get_video_latency(void); int dpss_frc_get_video_latency_for_gd(void); diff --git a/include/linux/amlogic/media/dpss/frc_common_x.h b/include/linux/amlogic/media/dpss/frc_common_x.h index 1533481a1..8500d808e 100644 --- a/include/linux/amlogic/media/dpss/frc_common_x.h +++ b/include/linux/amlogic/media/dpss/frc_common_x.h @@ -87,11 +87,14 @@ struct dpss_frc_top_type_s { /*input*/ u16 hsize; u16 vsize; - u16 inp_padding_xofst; - u16 inp_padding_yofst; + u16 mc_hsize; + u16 mc_vsize; + + u16 crop_top; + u16 crop_left; + u16 crop_bottom; + u16 crop_right; - u32 vfp;//line num before vsync,VIDEO_VSO_BLINE - u32 vfb;//line num before de ,VIDEO_VAVON_BLINE u32 frc_fb_num; //buffer num for frc loop enum frc_ratio_mode_type frc_ratio_mode; enum en_drv_film_mode film_mode;//film_mode @@ -104,8 +107,8 @@ struct dpss_frc_top_type_s { u16 other_set1; u8 rdma_en; //1:rdma 0:cpu interrupt access reg u8 motion_ctrl; // for frc motion ctrl - u8 rdma_reserved2; - u8 rdma_reserved3; + u8 need_dpe_mix; //t6w badedit + u8 dpe_mix_cnt; //t6w badedit u32 frc_prot_mode;//0:memc prefetch acorrding mode frame 1:memc prefetch 1 frame u32 force_en; // for debug u32 in_out_ratio; @@ -206,12 +209,6 @@ struct dpss_frc_fw_data_s { //extern int frc_kerdrv_ver; #define QUEEN_NUM 60 -struct dpss_queue { - u32 data[QUEEN_NUM]; - u16 front; - u16 rear; -}; - struct Vpu_queue { int data[QUEEN_NUM]; int front;