diff --git a/mpp/hal/rkdec/CMakeLists.txt b/mpp/hal/rkdec/CMakeLists.txt index 03f1fcc3..65127eb2 100644 --- a/mpp/hal/rkdec/CMakeLists.txt +++ b/mpp/hal/rkdec/CMakeLists.txt @@ -1,9 +1,10 @@ # vim: syntax=cmake include_directories(inc) -add_library(vdpu34x_com STATIC vdpu34x_com.c vdpu382_com.c) -add_library(vdpu383_com STATIC vdpu383_com.c) -add_library(vdpu384a_com STATIC vdpu384a_com.c) +add_library(vdpu34x_com OBJECT vdpu34x_com.c vdpu382_com.c) +add_library(vdpu383_com OBJECT vdpu383_com.c) +add_library(vdpu384a_com OBJECT vdpu384a_com.c) +add_library(vdpu38x_com OBJECT vdpu38x_com.c) if( HAVE_AVSD ) add_subdirectory(avsd) @@ -27,4 +28,4 @@ endif() if( HAVE_AV1D ) add_subdirectory(av1d) -endif() \ No newline at end of file +endif() diff --git a/mpp/hal/rkdec/inc/vdpu38x_com.h b/mpp/hal/rkdec/inc/vdpu38x_com.h new file mode 100644 index 00000000..08fc6778 --- /dev/null +++ b/mpp/hal/rkdec/inc/vdpu38x_com.h @@ -0,0 +1,942 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + */ + +#ifndef VDPU38X_COM_H +#define VDPU38X_COM_H + +#include + +#include "mpp_device.h" +#include "mpp_buf_slot.h" + +// #define DUMP_VDPU38X_DATAS + +#define OFFSET_CTRL_REGS (8 * sizeof(RK_U32)) +#define OFFSET_INTERRUPT_REGS (15 * sizeof(RK_U32)) +#define OFFSET_CODEC_PARAS_REGS (64 * sizeof(RK_U32)) +#define OFFSET_COMMON_ADDR_REGS (128 * sizeof(RK_U32)) +#define OFFSET_COM_STATISTIC_REGS (256 * sizeof(RK_U32)) + +typedef enum Vdpu38xFmt_e { + MPP_HAL_FMT_YUV400 = 0, + MPP_HAL_FMT_YUV420, + MPP_HAL_FMT_YUV422, + MPP_HAL_FMT_YUV444, + MPP_HAL_FMT_BUTT, +} Vdpu38xFmt; + +/* IN/ON_TILE */ +typedef enum Vdpu383RcbType_e { + RCB_STRMD_IN_ROW, + RCB_STRMD_ON_ROW, + RCB_INTER_IN_ROW, + RCB_INTER_ON_ROW, + RCB_INTRA_IN_ROW, + RCB_INTRA_ON_ROW, + RCB_FLTD_IN_ROW, + RCB_FLTD_PROT_IN_ROW, + RCB_FLTD_ON_ROW, + RCB_FLTD_ON_COL, + RCB_FLTD_UPSC_ON_COL, + RCB_BUF_CNT, +} Vdpu38xRcbType; + +extern RK_U32 vdpu38x_rcb_type2loc_map[RCB_BUF_CNT]; +extern RK_U32 vdpu38x_intra_uv_coef_map[MPP_HAL_FMT_BUTT]; +extern RK_U32 vdpu38x_filter_row_uv_coef_map[MPP_HAL_FMT_BUTT]; +extern RK_U32 vdpu38x_filter_col_uv_coef_map[MPP_HAL_FMT_BUTT]; + +typedef struct RcbTileInfo_t { + RK_U32 idx; + RK_U32 lt_x; + RK_U32 lt_y; + RK_U32 w; + RK_U32 h; +} RcbTileInfo; + +typedef struct Vdpu38xRcbBufInfo_t { + RK_U32 reg_idx; + RK_S32 size; + RK_S32 offset; +} Vdpu38xRcbBufInfo; + +#define RCB_ALLINE_SIZE (64) +#define MPP_RCB_BYTES(bits) ((RK_U32)(MPP_ALIGN(((RK_U32)ceilf(bits) + 7) / 8, RCB_ALLINE_SIZE))) + +typedef MPP_RET (*Vdpu38xRcbCalc_f)(void *ctx, RK_U32 *total_sz); + +typedef struct Vdpu38xRcbCtx_t { + RK_U32 pic_w; + RK_U32 pic_h; + + /* tile info */ + RcbTileInfo *tile_infos; + RK_U32 tile_num; + RK_U32 tile_info_cap; + RK_U32 tile_dir; /* 0: left to right, 1: top to bottom */ + + /* general */ + Vdpu38xFmt fmt; + RK_U32 bit_depth; + RK_U32 buf_sz; + /* h264 */ + RK_U32 mbaff_flag; + /* avs2 */ + RK_U32 alf_en; + /* av1 */ + RK_U32 lr_en; + RK_U32 upsc_en; + + Vdpu38xRcbBufInfo buf_info[RCB_BUF_CNT]; + Vdpu38xRcbCalc_f calc_func; +} Vdpu38xRcbCtx; + +typedef enum Vdpu38x_RCB_SET_MODE_e { + RCB_SET_BY_SIZE_SORT_MODE, + RCB_SET_BY_PRIORITY_MODE, +} Vdpu38xRcbSetMode; + +typedef struct Vdpu38xRegVersion_t { + struct SWREG0_ID { + RK_U32 minor_ver : 8; + RK_U32 major_ver : 8; + RK_U32 prod_num : 16; + } reg0; +} Vdpu38xRegVersion; + +typedef struct Vdpu38xCtrlReg_t { + /* SWREG8_DEC_MODE */ + RK_U32 reg8_dec_mode; + + struct SWREG9_IMPORTANT_EN { + RK_U32 secure_access : 1; + RK_U32 reserve0 : 3; + RK_U32 low_latency_en : 1; + RK_U32 scale_down_en : 1; + RK_U32 collect_info_dis : 1; + RK_U32 pix_range_det_e : 1; + RK_U32 av1_fgs_en : 1; + RK_U32 reserve2 : 3; + RK_U32 scale_down_ratio : 1; + RK_U32 scale_down_10bitto8bit_en : 1; + RK_U32 line_irq_en : 2; + RK_U32 reserve3 : 1; + RK_U32 out_cbcr_swap : 1; + RK_U32 fbc_force_uncompress : 1; + RK_U32 fbc_sparse_mode : 1; + RK_U32 reserve4 : 3; + /* + * vdpu384b is unused + * refer to collect_info_dis for its + * original functionality. + */ + RK_U32 inter_max_mv_detect_en : 1; + /* + * 0:pp output raster. + * 1:pp output tile4x4. + * 2:pp output rkfbc64x4. + * 3:pp output afbc32x8. + */ + RK_U32 pp_output_mode : 2; + RK_U32 reserve5 : 6; + } reg9; + + struct SWREG10_BLOCK_GATING_DIS { + RK_U32 strmd_auto_gating_dis : 1; + RK_U32 inter_auto_gating_dis : 1; + RK_U32 intra_auto_gating_dis : 1; + RK_U32 transd_auto_gating_dis : 1; + RK_U32 recon_auto_gating_dis : 1; + RK_U32 filterd_auto_gating_dis : 1; + RK_U32 bus_auto_gating_dis : 1; + RK_U32 ctrl_auto_gating_dis : 1; + RK_U32 rcb_auto_gating_dis : 1; + RK_U32 err_prc_auto_gating_dis : 1; + RK_U32 cache_auto_gating_dis : 1; + RK_U32 reserve0 : 21; + } reg10; + + struct SWREG11_CFG_PARA { + RK_U32 frame_irq_dis : 1; + RK_U32 recon_ahead_release_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 cache_perf_opt_disable : 1; + RK_U32 cache_dis : 1; + RK_U32 cache_pu_parse_opt_dis : 1; + RK_U32 cache_multi_id_dis : 1; + RK_U32 cache_grp_dis : 1; + RK_U32 dec_timeout_dis : 1; + RK_U32 reserve1 : 3; + RK_U32 coord_rpt_mode : 1; + RK_U32 reserve2 : 2; + RK_U32 rd_outstanding : 8; + RK_U32 wr_outstanding : 8; + } reg11; + + RK_U32 reserve_reg12; + + /* SWREG13_CORE_TIMEOUT_THRESHOLD */ + RK_U32 reg13_core_timeout_threshold; + + struct SWREG14_LINE_IRQ_CTRL { + RK_U32 dec_line_irq_step : 16; + RK_U32 dec_line_offset_y_st : 16; + } reg14; + + struct SWREG15_STA { + RK_U32 rkvdec_frame_rdy_sta : 1; + RK_U32 rkvdec_strm_error_sta : 1; + RK_U32 rkvdec_core_timeout_sta : 1; + RK_U32 rkvdec_ip_timeout_sta : 1; + RK_U32 rkvdec_bus_error_sta : 1; + RK_U32 rkvdec_buffer_empty_sta : 1; + RK_U32 rkvdec_colmv_ref_error_sta : 1; + RK_U32 rkvdec_error_spread_sta : 1; + RK_U32 create_core_timeout_sta : 1; + RK_U32 wlast_miss_match_sta : 1; + RK_U32 rkvdec_core_rst_rdy_sta : 1; + RK_U32 rkvdec_ip_rst_rdy_sta : 1; + RK_U32 force_busidle_rdy_sta : 1; + RK_U32 ltb_pause_rdy_sta : 1; + RK_U32 ltb_end_flag : 1; + RK_U32 unsupport_decmode_error_sta : 1; + RK_U32 wmask_bits : 15; + RK_U32 reserve0 : 1; + } reg15; + + struct SWREG16_ERROR_CTRL_SET { + RK_U32 error_proc_disable : 1; + RK_U32 error_proc_restart_mode : 1; + RK_U32 error_flush_dis : 1; + RK_U32 roi_error_ctu_cal_en : 1; + RK_U32 nxt_slice_retrieval_dis : 1; + RK_U32 filterd_err_wr_prot_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 error_spread_disable : 1; + RK_U32 error_fill_mode : 1; + RK_U32 error_intra_creat_mode : 1; + RK_U32 reserve1 : 13; + RK_U32 inter_error_gbl_mv_x : 4; + RK_U32 inter_error_gbl_mv_y : 4; + } reg16; + + struct SWREG17_ERR_ROI_CTU_OFFSET_START { + RK_U32 roi_x_ctu_offset_st : 12; + RK_U32 reserve0 : 4; + RK_U32 roi_y_ctu_offset_st : 12; + RK_U32 reserve1 : 4; + } reg17; + + struct SWREG18_ERR_ROI_CTU_OFFSET_END { + RK_U32 roi_x_ctu_offset_end : 12; + RK_U32 reserve0 : 4; + RK_U32 roi_y_ctu_offset_end : 12; + RK_U32 reserve1 : 4; + } reg18; + + struct SWREG19_ERROR_REF_INFO { + RK_U32 avs2_ref_error_field : 1; + RK_U32 avs2_ref_error_topfield : 1; + RK_U32 ref_error_topfield_used : 1; + RK_U32 ref_error_botfield_used : 1; + RK_U32 reserve0 : 28; + } reg19; + + /* SWREG20_CABAC_ERROR_EN_LOWBITS */ + RK_U32 reg20_cabac_error_en_lowbits; + + /* SWREG21_CABAC_ERROR_EN_HIGHBITS */ + RK_U32 reg21_cabac_error_en_highbits; + + RK_U32 reserve_reg22; + + struct SWREG23_INVALID_PIXEL_FILL { + RK_U32 fill_y : 10; + RK_U32 fill_u : 10; + RK_U32 fill_v : 10; + RK_U32 reserve0 : 2; + } reg23; + + RK_U32 reserve_reg24_27[4]; + + struct SWREG28_DEBUG_PERF_LATENCY_CTRL0 { + RK_U32 axi_perf_work_e : 1; + RK_U32 reserve0 : 2; + RK_U32 axi_cnt_type : 1; + RK_U32 rd_latency_id : 8; + RK_U32 reserve1 : 4; + RK_U32 rd_latency_thr : 12; + RK_U32 reserve2 : 4; + } reg28; + + struct SWREG29_DEBUG_PERF_LATENCY_CTRL1 { + RK_U32 addr_align_type : 2; + RK_U32 ar_cnt_id_type : 1; + RK_U32 aw_cnt_id_type : 1; + RK_U32 ar_count_id : 8; + RK_U32 reserve0 : 4; + RK_U32 aw_count_id : 8; + RK_U32 rd_band_width_mode : 1; + RK_U32 reserve1 : 7; + } reg29; + + struct SWREG30_QOS_CTRL { + RK_U32 axi_wr_qos_level : 4; + RK_U32 reserve0 : 4; + RK_U32 axi_wr_qos : 4; + RK_U32 reserve1 : 4; + RK_U32 axi_rd_qos_level : 4; + RK_U32 reserve2 : 4; + RK_U32 axi_rd_qos : 4; + RK_U32 axi_mmu_rd_qos : 4; + } reg30; + +} Vdpu38xCtrlReg; + +typedef struct Vdpu38xRegCommParas_t { + /* SWREG64_H26X_PARA */ + RK_U32 reg64_unused_bits; + + /* SWREG65_STREAM_PARAM_SET */ + RK_U32 reg65_strm_start_bit; + + /* SWREG66_STREAM_LEN */ + RK_U32 reg66_stream_len; + + /* SWREG67_GLOBAL_LEN */ + RK_U32 reg67_global_len; + + /* SWREG68_HEAD_HOR_STRIDE */ + RK_U32 reg68_pp_m_hor_stride; + + /* SWREG69_PP_M_UV_HOR_STRIDE */ + RK_U32 reg69_pp_m_uv_hor_stride; + + /* SWREG70_PP_M_Y_STRIDE */ + RK_U32 reg70_pp_m_y_virstride; + + /* SWREG71_SCL_Y_HOR_VIRSTRIDE */ + RK_U32 reg71_scl_ref_hor_virstride; + + /* SWREG72_SCL_UV_HOR_VIRSTRIDE */ + RK_U32 reg72_scl_ref_raster_uv_hor_virstride; + + /* SWREG73_SCL_Y_VIRSTRIDE */ + RK_U32 reg73_scl_ref_virstride; + + /* SWREG74_FGS_Y_HOR_VIRSTRIDE */ + RK_U32 reg74_fgs_ref_hor_virstride; + + /* SWREG75_FGS_UV_HOR_VIRSTRIDE */ + RK_U32 reg75_fgs_ref_uv_hor_virstride; + + /* SWREG76_FGS_Y_VIRSTRIDE */ + RK_U32 reg76_fgs_ref_virstride; + + RK_U32 reserve_reg77; + + struct SWREG78_ERROR_REF_PIC { + RK_U32 error_ref_pic_width : 16; + RK_U32 error_ref_pic_height : 16; + } reg78; + + struct SWREG79_ERROR_REF_SCALE { + RK_U32 error_ref_scale_step_x : 16; + RK_U32 error_ref_scale_step_y : 16; + } reg79; + + /* SWREG80_ERROR_REF_Y_HOR_VIRSTRIDE */ + RK_U32 reg80_error_ref_hor_virstride; + + /* SWREG81_ERROR_REF_UV_HOR_VIRSTRIDE */ + RK_U32 reg81_error_ref_raster_uv_hor_virstride; + + /* SWREG82_ERROR_REF_Y_VIRSTRIDE */ + RK_U32 reg82_error_ref_virstride; + + /* SWREG83_REF0_Y_HOR_VIRSTRIDE */ + RK_U32 reg83_ref0_hor_virstride; + + /* SWREG84_REF0_UV_HOR_VIRSTRIDE */ + RK_U32 reg84_ref0_raster_uv_hor_virstride; + + /* SWREG85_REF0_Y_VIRSTRIDE */ + RK_U32 reg85_ref0_virstride; + + /* SWREG86_REF1_Y_HOR_VIRSTRIDE */ + RK_U32 reg86_ref1_hor_virstride; + + /* SWREG87_REF1_UV_HOR_VIRSTRIDE */ + RK_U32 reg87_ref1_raster_uv_hor_virstride; + + /* SWREG88_REF1_Y_VIRSTRIDE */ + RK_U32 reg88_ref1_virstride; + + /* SWREG89_REF2_Y_HOR_VIRSTRIDE */ + RK_U32 reg89_ref2_hor_virstride; + + /* SWREG90_REF2_UV_HOR_VIRSTRIDE */ + RK_U32 reg90_ref2_raster_uv_hor_virstride; + + /* SWREG91_REF2_Y_VIRSTRIDE */ + RK_U32 reg91_ref2_virstride; + + /* SWREG92_REF3_Y_HOR_VIRSTRIDE */ + RK_U32 reg92_ref3_hor_virstride; + + /* SWREG93_REF3_UV_HOR_VIRSTRIDE */ + RK_U32 reg93_ref3_raster_uv_hor_virstride; + + /* SWREG94_REF3_Y_VIRSTRIDE */ + RK_U32 reg94_ref3_virstride; + + /* SWREG95_REF4_Y_HOR_VIRSTRIDE */ + RK_U32 reg95_ref4_hor_virstride; + + /* SWREG96_REF4_UV_HOR_VIRSTRIDE */ + RK_U32 reg96_ref4_raster_uv_hor_virstride; + + /* SWREG97_REF4_Y_VIRSTRIDE */ + RK_U32 reg97_ref4_virstride; + + /* SWREG98_REF5_Y_HOR_VIRSTRIDE */ + RK_U32 reg98_ref5_hor_virstride; + + /* SWREG99_REF5_UV_HOR_VIRSTRIDE */ + RK_U32 reg99_ref5_raster_uv_hor_virstride; + + /* SWREG100_REF5_Y_VIRSTRIDE */ + RK_U32 reg100_ref5_virstride; + + /* SWREG101_REF6_Y_HOR_VIRSTRIDE */ + RK_U32 reg101_ref6_hor_virstride; + + /* SWREG102_REF6_UV_HOR_VIRSTRIDE */ + RK_U32 reg102_ref6_raster_uv_hor_virstride; + + /* SWREG103_REF6_Y_VIRSTRIDE */ + RK_U32 reg103_ref6_virstride; + + /* SWREG104_REF7_Y_HOR_VIRSTRIDE */ + RK_U32 reg104_ref7_hor_virstride; + + /* SWREG105_REF7_UV_HOR_VIRSTRIDE */ + RK_U32 reg105_ref7_raster_uv_hor_virstride; + + /* SWREG106_REF7_Y_VIRSTRIDE */ + RK_U32 reg106_ref7_virstride; + +} Vdpu38xRegCommParas; + +typedef struct Vdpu38xRegCommonAddr_t { + /* SWREG128_STRM_BASE */ + RK_U32 reg128_strm_base; + + /* SWREG129_STREAM_BUF_ST_BASE */ + RK_U32 reg129_stream_buf_st_base; + + /* SWREG130_STREAM_BUF_END_BASE */ + RK_U32 reg130_stream_buf_end_base; + + /* SWREG131_GBL_BASE */ + RK_U32 reg131_gbl_base; + + /* SWREG132_SCANLIST_ADDR */ + RK_U32 reg132_scanlist_addr; + + /* SWREG133_SCL_BASE */ + RK_U32 reg133_scale_down_base; + + /* SWREG134_FGS_BASE */ + RK_U32 reg134_fgs_base; + + RK_U32 reserve_reg135_139[5]; + + /* SWREG140_RCB_STRMD_ROW_OFFSET */ + RK_U32 reg140_rcb_strmd_row_offset; + + /* SWREG141_RCB_STRMD_ROW_LEN */ + RK_U32 reg141_rcb_strmd_row_len; + + /* SWREG142_RCB_STRMD_TILE_ROW_OFFSET */ + RK_U32 reg142_rcb_strmd_tile_row_offset; + + /* SWREG143_RCB_STRMD_TILE_ROW_LEN */ + RK_U32 reg143_rcb_strmd_tile_row_len; + + /* SWREG144_RCB_INTER_ROW_OFFSET */ + RK_U32 reg144_rcb_inter_row_offset; + + /* SWREG145_RCB_INTER_ROW_LEN */ + RK_U32 reg145_rcb_inter_row_len; + + /* SWREG146_RCB_INTER_TILE_ROW_OFFSET */ + RK_U32 reg146_rcb_inter_tile_row_offset; + + /* SWREG147_RCB_INTER_TILE_ROW_LEN */ + RK_U32 reg147_rcb_inter_tile_row_len; + + /* SWREG148_RCB_INTRA_ROW_OFFSET */ + RK_U32 reg148_rcb_intra_row_offset; + + /* SWREG149_RCB_INTRA_ROW_LEN */ + RK_U32 reg149_rcb_intra_row_len; + + /* SWREG150_RCB_INTRA_TILE_ROW_OFFSET */ + RK_U32 reg150_rcb_intra_tile_row_offset; + + /* SWREG151_RCB_INTRA_TILE_ROW_LEN */ + RK_U32 reg151_rcb_intra_tile_row_len; + + /* SWREG152_RCB_FILTERD_ROW_OFFSET */ + RK_U32 reg152_rcb_filterd_row_offset; + + /* SWREG153_RCB_FILTERD_ROW_LEN */ + RK_U32 reg153_rcb_filterd_row_len; + + /* SWREG154_RCB_FILTERD_PROTECT_ROW_OFFSET */ + RK_U32 reg154_rcb_filterd_protect_row_offset; + + /* SWREG155_RCB_FILTERD_PROTECT_ROW_LEN */ + RK_U32 reg155_rcb_filterd_protect_row_len; + + /* SWREG156_RCB_FILTERD_TILE_ROW_OFFSET */ + RK_U32 reg156_rcb_filterd_tile_row_offset; + + /* SWREG157_RCB_FILTERD_TILE_ROW_LEN */ + RK_U32 reg157_rcb_filterd_tile_row_len; + + /* SWREG158_RCB_FILTERD_TILE_COL_OFFSET */ + RK_U32 reg158_rcb_filterd_tile_col_offset; + + /* SWREG159_RCB_FILTERD_TILE_COL_LEN */ + RK_U32 reg159_rcb_filterd_tile_col_len; + + /* SWREG160_RCB_FILTERD_AV1_UPSCALE_TILE_COL_OFFSET */ + RK_U32 reg160_rcb_filterd_av1_upscale_tile_col_offset; + + /* SWREG161_RCB_FILTERD_AV1_UPSCALE_TILE_COL_LEN */ + RK_U32 reg161_rcb_filterd_av1_upscale_tile_col_len; + + RK_U32 reserve_reg162_167[6]; + + /* SWREG168_DECOUT_BASE */ + RK_U32 reg168_decout_base; + + /* SWREG169_ERROR_REF_BASE */ + RK_U32 reg169_error_ref_base; + + union { + /* h264 / h265 / avs2 */ + RK_U32 reg170_185_ref_base[16]; + /* vp9 */ + struct { + RK_U32 reg170_180[11]; + RK_U32 reg181_segidlast_base; + RK_U32 reg182_segidcur_base; + RK_U32 reg183_reserve; + RK_U32 reg184_lastprob_base; + RK_U32 reg185_updateprob_base; + }; + /* av1 */ + struct { + RK_U32 reg170_av1_last_base; + RK_U32 reg171_av1golden_base; + RK_U32 reg172_av1alfter_base; + RK_U32 reserve_reg173_177[5]; + RK_U32 reg178_av1_coef_rd_base; + RK_U32 reg179_av1_coef_wr_base; + RK_U32 reserve_reg180; + RK_U32 reg181_av1_segid_last_base; + RK_U32 reg182_av1_segid_cur_base; + RK_U32 reserve_reg183; + RK_U32 reg184_av1_noncoef_rd_base; + RK_U32 reg185_av1_noncoef_wr_base; + }; + }; + + + RK_U32 reserve_reg186_190[5]; + + /* SWREG191_FGS_FBC_PAYLOAD_ST */ + RK_U32 reg191_fgs_fbc_payload_st_base; + + /* SWREG192_PAYLOAD_ST_CUR_BASE */ + RK_U32 reg192_payload_st_cur_base; + + /* SWREG193_FBC_PAYLOAD_OFFSET */ + RK_U32 reg193_fbc_payload_offset; + + /* SWREG194_PAYLOAD_ST_ERROR_REF_BASE */ + RK_U32 reg194_payload_st_error_ref_base; + + /* SWREG195_PAYLOAD_ST_REF0_BASE */ + RK_U32 reg195_210_payload_st_ref_base[16]; + + RK_U32 reserve_reg211_215[5]; + + /* SWREG216_COLMV_CUR_BASE */ + RK_U32 reg216_colmv_cur_base; + + /* SWREG217_232_COLMV_REF0_BASE */ + RK_U32 reg217_232_colmv_ref_base[16]; + +} Vdpu38xRegCommonAddr; + + +typedef struct Vdpu38xRegStatistic_t { + struct SWREG256_CTRL_RESP { + RK_U32 reserve0 : 24; + RK_U32 rkvdec_bus_idle_flag : 1; + RK_U32 reserve1 : 7; + } reg256; + + RK_U32 reserve_reg257; + + /* SWREG258_BUS_RESP */ + RK_U32 reg258_perf_rd_max_latency_num; + + /* SWREG259_BUS_RESP */ + RK_U32 reg259_perf_rd_latency_samp_num; + + /* SWREG260_BUS_RESP */ + RK_U32 reg260_perf_rd_latency_acc_sum; + + /* SWREG261_BUS_RESP */ + RK_U32 reg261_perf_rd_axi_total_byte; + + /* SWREG262_BUS_RESP */ + RK_U32 reg262_perf_wr_axi_total_bytes; + + /* SWREG263_BUS_RESP */ + RK_U32 reg263_perf_working_cnt; + + RK_U32 reserve_reg264_272[9]; + + struct SWREG273_CABAC_RESP { + RK_U32 qp_max : 9; + RK_U32 reserve0 : 3; + RK_U32 qp_min : 9; + RK_U32 reserve1 : 3; + RK_U32 qp_sum_low8bit : 8; + } reg273; + + /* SWREG274_CABAC_RESP */ + RK_U32 reg274_qp_sum_high; + + /* SWREG275_CABAC_RESP */ + RK_U32 reg275_tu_need_iq_sum; + + /* SWREG276_INTER_RESP */ + RK_U32 reg276_inter_sw_reflst_idx_use; + + /* SWREG277_INTER_RESP */ + RK_U32 reg277_sw_mv_x_out_sum_31_0; + + struct SWREG278_INTER_RESP { + RK_U32 inter_sw_mv_x_out_sum_43_32 : 12; + RK_U32 inter_sw_mv_y_out_sum_19_0 : 20; + } reg278; + + struct SWREG279_INTER_RESP { + RK_U32 inter_sw_mv_y_out_sum_43_20 : 24; + RK_U32 dbg_inter_min_mv_x : 4; + RK_U32 dbg_inter_min_mv_y : 4; + } reg279; + + struct SWREG280_INTER_RESP { + RK_U32 inter_sw_mv_x_max_out : 16; + RK_U32 inter_sw_mv_y_max_out : 16; + } reg280; + + struct SWREG281_INTER_RESP { + RK_U32 inter_sw_mv_x_min_out : 16; + RK_U32 inter_sw_mv_y_min_out : 16; + } reg281; + + struct SWREG282_INTER_RESP { + RK_U32 inter_sw_skip_pu_cnt_sum : 28; + RK_U32 inter_sw_pu_cnt_sum_3_0 : 4; + } reg282; + + struct SWREG283_INTER_RESP { + RK_U32 inter_sw_pu_cnt_sum_27_4 : 24; + RK_U32 inter_sw_min_pu_cnt_sum_7_0 : 8; + } reg283; + + /* SWREG284_INTER_RESP */ + RK_U32 reg284_sw_min_pu_cnt_sum_27_8; + + RK_U32 reserve_reg285_286[2]; + + /* SWREG287_INTER_RESP */ + RK_U32 reg287_inter_cache_info_reserve0; + + /* SWREG288_INTER_RESP */ + RK_U32 reg288_inter_cache_info_reserve1; + + /* SWREG289_INTER_RESP */ + RK_U32 reg289_inter_cache_info_reserve2; + + /* SWREG290_INTER_RESP */ + RK_U32 reg290_inter_dbg_info_reserve; + + RK_U32 reserve_reg291_298[8]; + + /* SWREG299_FILTERD_RESP */ + RK_U32 reg299_filterd_payload_total_cnt; + + struct SWREG300_FILTERD_RESP { + RK_U32 fdbg_filterd_report_offsety : 16; + RK_U32 fdbg_filterd_report_offsetx : 16; + } reg300; + + struct SWREG301_FILTERD_RESP { + RK_U32 fdbg_filterd_max_y : 10; + RK_U32 fdbg_filterd_max_u : 10; + RK_U32 fdbg_filterd_max_v : 10; + RK_U32 reserve0 : 2; + } reg301; + + struct SWREG302_FILTERD_RESP { + RK_U32 fdbg_filterd_min_y : 10; + RK_U32 fdbg_filterd_min_u : 10; + RK_U32 fdbg_filterd_min_v : 10; + RK_U32 reserve0 : 2; + } reg302; + + struct SWREG303_FILTERD_RESP { + RK_U32 fdbg_filterd_ppm_line_irq_offsety : 16; + RK_U32 fdbg_filterd_scl_line_irq_offsety : 16; + } reg303; + + /* SWREG304_FILTERD_RESP */ + RK_U32 reg304_filterd_err_ctu_num; + + RK_U32 reserve_reg305_311[7]; + + struct SWREG312_RCB_RESP { + RK_U32 rcb_rd_sum_chk : 8; + RK_U32 rcb_wr_sum_chk : 8; + RK_U32 reserve0 : 16; + } reg312; + +} Vdpu38xRegStatistic; + +typedef struct Vdpu38xRegLlp_t { + struct SWREG0_LINK_MODE { + RK_U32 llp_mmu_zap_cache_dis : 1; + RK_U32 reserve0 : 15; + RK_U32 core_work_mode : 1; + RK_U32 ccu_core_work_mode : 1; + RK_U32 reserve1 : 3; + RK_U32 ltb_pause_flag : 1; + RK_U32 reserve2 : 10; + } reg0; + + struct SWREG1_CFG_START_ADDR { + RK_U32 reserve0 : 4; + RK_U32 reg_cfg_addr : 28; + } reg1; + + struct SWREG2_LINK_MODE { + RK_U32 pre_frame_num : 30; + RK_U32 reserve0 : 1; + RK_U32 link_mode : 1; + } reg2; + + /* SWREG3_CONFIG_DONE */ + RK_U32 reg3_done; + + /* SWREG4_DECODERED_NUM */ + RK_U32 reg4_num; + + /* SWREG5_DEC_TOTAL_NUM */ + RK_U32 reg5_total_num; + + /* SWREG6_LINK_MODE_EN */ + RK_U32 reg6_mode_en; + + /* SWREG7_SKIP_NUM */ + RK_U32 reg7_num; + + struct SWREG8_CUR_LTB_IDX { + RK_U32 reserve0 : 4; + RK_U32 ltb_idx : 28; + } reg8; + + RK_U32 reserve_reg9_15[7]; + + /* SWREG16_DEC_E */ + RK_U32 reg16_dec_e; + + /* SWREG17_SOFT_RST */ + RK_U32 reg17_rkvdec_ip_rst_p; + + struct SWREG18_IRQ { + RK_U32 rkvdec_irq : 1; + RK_U32 rkvdec_line_irq : 1; + RK_U32 reserve0 : 14; + RK_U32 wmask : 2; + RK_U32 reserve1 : 14; + } reg18; + + struct SWREG19_STA { + RK_U32 rkvdec_frame_rdy_sta : 1; + RK_U32 rkvdec_strm_error_sta : 1; + RK_U32 rkvdec_core_timeout_sta : 1; + RK_U32 rkvdec_ip_timeout_sta : 1; + RK_U32 rkvdec_bus_error_sta : 1; + RK_U32 rkvdec_buffer_empty_sta : 1; + RK_U32 rkvdec_colmv_ref_error_sta : 1; + RK_U32 rkvdec_error_spread_sta : 1; + RK_U32 create_core_timeout_sta : 1; + RK_U32 wlast_miss_match_sta : 1; + RK_U32 rkvdec_core_rst_rdy_sta : 1; + RK_U32 rkvdec_ip_rst_rdy_sta : 1; + RK_U32 force_busidle_rdy_sta : 1; + RK_U32 ltb_pause_rdy_sta : 1; + RK_U32 ltb_end_flag : 1; + RK_U32 unsupport_decmode_error_sta : 1; + RK_U32 wmask_bits : 15; + RK_U32 reserve0 : 1; + } reg19; + + RK_U32 reserve_reg20; + + /* SWREG21_IP_TIMEOUT_THRESHOD */ + RK_U32 reg21_ip_timeout_threshold; + + struct SWREG22_IP_EN { + RK_U32 ip_timeout_pause_flag : 1; + RK_U32 reserve0 : 3; + RK_U32 abnormal_auto_reset_dis : 1; + RK_U32 reserve1 : 3; + RK_U32 force_busidle_req_flag : 1; + RK_U32 reserve2 : 3; + RK_U32 bus_clkgate_dis : 1; + RK_U32 ctrl_clkgate_dis : 1; + RK_U32 reserve3 : 1; + RK_U32 irq_dis : 1; + RK_U32 wid_reorder_dis : 1; + RK_U32 reserve4 : 7; + RK_U32 clk_cru_mode : 2; + RK_U32 reserve5 : 4; + RK_U32 rkmmu_rd_mode : 1; + RK_U32 mmu_sel : 1; + } reg22; + + struct SWREG23_IN_OUT { + RK_U32 endian : 1; + RK_U32 swap32_e : 1; + RK_U32 swap64_e : 1; + RK_U32 str_endian : 1; + RK_U32 str_swap32_e : 1; + RK_U32 str_swap64_e : 1; + RK_U32 reserve0 : 26; + } reg23; + + struct SWREG24_EXTRA_STRM_BASE { + RK_U32 reserve0 : 4; + RK_U32 extra_stream_base : 28; + } reg24; + + /* SWREG25_EXTRA_STRM_LEN */ + RK_U32 reg25_extra_stream_len; + + /* SWREG26_EXTRA_STRM_PARA_SET */ + RK_U32 reg26_extra_strm_start_bit; + + struct SWREG27_BUF_EMPTY_RESTART { + RK_U32 buf_emtpy_restart_p : 1; + RK_U32 extra_strm_last_packet_flag : 1; + RK_U32 reserve0 : 30; + } reg27; + + struct SWREG28_RCB_BASE { + RK_U32 reserve0 : 4; + RK_U32 rcb_base : 28; + } reg28; + + /* SWREG29_STRMD_LEN_USED */ + RK_U32 reg29_strm_len_used_bytes; + +} Vdpu38xRegLlp; + +typedef struct Vdpu38xdRegSet_t { + Vdpu38xRegVersion reg_version; + Vdpu38xCtrlReg ctrl_regs; /* 8-30 */ + Vdpu38xRegCommParas comm_paras; /* 64-106 */ + Vdpu38xRegCommonAddr comm_addrs; /* 128-134, 140-161 168-185, 192-210, 216-232 */ + Vdpu38xRegStatistic statistic_regs; /* 256-312 */ +} Vdpu38xRegSet; + +typedef enum Vdpu38xTileLoc_e { + VDPU38X_RCB_IN_TILE_ROW = 0, + VDPU38X_RCB_IN_TILE_COL, + VDPU38X_RCB_ON_TILE_ROW, + VDPU38X_RCB_ON_TILE_COL, +} Vdpu38xTileLoc ; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET vdpu38x_rcb_calc_init(Vdpu38xRcbCtx **ctx); +MPP_RET vdpu38x_rcb_calc_deinit(Vdpu38xRcbCtx *ctx); +MPP_RET vdpu38x_rcb_reset(Vdpu38xRcbCtx *ctx); +MPP_RET vdpu38x_rcb_add_tile_info(Vdpu38xRcbCtx *ctx, RcbTileInfo *tile_info); +MPP_RET vdpu38x_rcb_dump_tile_info(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_pic_w(Vdpu38xRcbCtx *ctx, RK_U32 pic_w); +Vdpu38xFmt vdpu38x_fmt_mpp2hal(MppFrameFormat mpp_fmt); +RK_U32 vdpu38x_rcb_get_pic_w(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_pic_h(Vdpu38xRcbCtx *ctx, RK_U32 pic_h); +RK_U32 vdpu38x_rcb_get_pic_h(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_tile_dir(Vdpu38xRcbCtx *ctx, RK_U32 tile_dir); +RK_U32 vdpu38x_rcb_get_tile_dir(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_fmt(Vdpu38xRcbCtx *ctx, RK_U32 fmt); +Vdpu38xFmt vdpu38x_rcb_get_fmt(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_bit_depth(Vdpu38xRcbCtx *ctx, RK_U32 bit_depth); +RK_U32 vdpu38x_rcb_get_bit_depth(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_mbaff_flag(Vdpu38xRcbCtx *ctx, RK_U32 mbaff_flag); +RK_U32 vdpu38x_rcb_get_mbaff_flag(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_alf_en(Vdpu38xRcbCtx *ctx, RK_U32 alf_en); +RK_U32 vdpu38x_rcb_get_alf_en(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_lr_en(Vdpu38xRcbCtx *ctx, RK_U32 lr_en); +RK_U32 vdpu38x_rcb_get_lr_en(Vdpu38xRcbCtx *ctx); +void vdpu38x_rcb_set_upsc_en(Vdpu38xRcbCtx *ctx, RK_U32 upsc_en); +RK_U32 vdpu38x_rcb_get_upsc_en(Vdpu38xRcbCtx *ctx); +MPP_RET vdpu38x_rcb_get_len(Vdpu38xRcbCtx *ctx, Vdpu38xTileLoc loc, RK_U32 *len); +MPP_RET vdpu38x_rcb_get_extra_size(Vdpu38xRcbCtx *ctx, Vdpu38xTileLoc loc, RK_U32 *extra_sz); +RK_U32 vdpu38x_rcb_reg_info_update(Vdpu38xRcbCtx *ctx, Vdpu38xRcbType type, RK_U32 idx, + RK_FLOAT sz); +RK_U32 vdpu38x_rcb_get_total_size(Vdpu38xRcbCtx *ctx); +MPP_RET vdpu38x_rcb_register_calc_handle(Vdpu38xRcbCtx *ctx, Vdpu38xRcbCalc_f func); +MPP_RET vdpu38x_rcb_calc_exec(Vdpu38xRcbCtx *ctx, RK_U32 *total_sz); +RK_S32 vdpu38x_set_rcbinfo(MppDev dev, Vdpu38xRcbBufInfo *rcb_info); +MPP_RET vdpu38x_rcb_dump_rcb_result(Vdpu38xRcbCtx *ctx); +MPP_RET vdpu38x_get_fbc_off(MppFrame mframe, RK_U32 *head_stride, RK_U32 *pld_stride, RK_U32 *pld_offset); +MPP_RET vdpu38x_get_tile4x4_h_stride_coeff(MppFrameFormat fmt, RK_U32 *coeff); +void vdpu38x_setup_rcb(Vdpu38xRcbCtx *ctx, Vdpu38xRegCommonAddr *reg, MppDev dev, MppBuffer buf); +void vdpu38x_setup_statistic(Vdpu38xCtrlReg *com); +void vdpu38x_afbc_align_calc(MppBufSlots slots, MppFrame frame, RK_U32 expand); +void vdpu38x_setup_down_scale(MppFrame frame, MppDev dev, Vdpu38xCtrlReg *com, void* comParas); +void vdpu38x_update_thumbnail_frame_info(MppFrame frame); + +#ifdef DUMP_VDPU38X_DATAS +extern RK_U32 vdpu38x_dump_cur_frm; +extern char vdpu38x_dump_cur_dir[128]; +extern char vdpu38x_dump_cur_fname_path[512]; + +MPP_RET vdpu38x_flip_string(char *str); +MPP_RET vdpu38x_dump_data_to_file(char *fname_path, void *data, RK_U32 data_bit_size, + RK_U32 line_bits, RK_U32 big_end, RK_U32 append); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* VDPU38X_COM_H */ diff --git a/mpp/hal/rkdec/vdpu38x_com.c b/mpp/hal/rkdec/vdpu38x_com.c new file mode 100644 index 00000000..c85d43f0 --- /dev/null +++ b/mpp/hal/rkdec/vdpu38x_com.c @@ -0,0 +1,740 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + */ + +#define MODULE_TAG "vdpu38x_com" + +#include + +#include "mpp_log.h" +#include "mpp_buffer.h" +#include "mpp_common.h" +#include "mpp_compat_impl.h" +#include "mpp_frame_impl.h" + +#include "vdpu38x_com.h" + +RK_U32 vdpu38x_rcb_type2loc_map[RCB_BUF_CNT] = { + [RCB_STRMD_IN_ROW] = VDPU38X_RCB_IN_TILE_ROW, + [RCB_STRMD_ON_ROW] = VDPU38X_RCB_ON_TILE_ROW, + [RCB_INTER_IN_ROW] = VDPU38X_RCB_IN_TILE_ROW, + [RCB_INTER_ON_ROW] = VDPU38X_RCB_ON_TILE_ROW, + [RCB_INTRA_IN_ROW] = VDPU38X_RCB_IN_TILE_ROW, + [RCB_INTRA_ON_ROW] = VDPU38X_RCB_ON_TILE_ROW, + [RCB_FLTD_IN_ROW] = VDPU38X_RCB_IN_TILE_ROW, + [RCB_FLTD_PROT_IN_ROW] = VDPU38X_RCB_IN_TILE_ROW, + [RCB_FLTD_ON_ROW] = VDPU38X_RCB_ON_TILE_ROW, + [RCB_FLTD_ON_COL] = VDPU38X_RCB_ON_TILE_COL, + [RCB_FLTD_UPSC_ON_COL] = VDPU38X_RCB_ON_TILE_COL, +}; + +RK_U32 vdpu38x_intra_uv_coef_map[MPP_HAL_FMT_BUTT] = { + [MPP_HAL_FMT_YUV400] = 1, + [MPP_HAL_FMT_YUV420] = 2, + [MPP_HAL_FMT_YUV422] = 2, + [MPP_HAL_FMT_YUV444] = 3, +}; + +RK_U32 vdpu38x_filter_row_uv_coef_map[MPP_HAL_FMT_BUTT] = { + [MPP_HAL_FMT_YUV400] = 0, + [MPP_HAL_FMT_YUV420] = 1, + [MPP_HAL_FMT_YUV422] = 1, + [MPP_HAL_FMT_YUV444] = 3, +}; + +RK_U32 vdpu38x_filter_col_uv_coef_map[MPP_HAL_FMT_BUTT] = { + [MPP_HAL_FMT_YUV400] = 0, + [MPP_HAL_FMT_YUV420] = 1, + [MPP_HAL_FMT_YUV422] = 3, + [MPP_HAL_FMT_YUV444] = 3, +}; + +MPP_RET vdpu38x_rcb_calc_init(Vdpu38xRcbCtx **ctx) +{ + Vdpu38xRcbCtx *p = NULL; + + p = (Vdpu38xRcbCtx *)mpp_calloc(Vdpu38xRcbCtx, 1); + if (!p) { + mpp_loge_f("malloc rcb ctx failed\n"); + return MPP_ERR_MALLOC; + } + p->tile_infos = (RcbTileInfo *)mpp_calloc(RcbTileInfo, 1); + if (!p) { + mpp_loge_f("malloc tile infos failed\n"); + return MPP_ERR_MALLOC; + } + p->tile_info_cap = 1; + p->fmt = MPP_HAL_FMT_BUTT; + *ctx = p; + + return MPP_OK; +} + +MPP_RET vdpu38x_rcb_calc_deinit(Vdpu38xRcbCtx *ctx) +{ + if (NULL != ctx) { + MPP_FREE(ctx->tile_infos); + MPP_FREE(ctx); + } + + return MPP_OK; +} + +MPP_RET vdpu38x_rcb_reset(Vdpu38xRcbCtx *ctx) +{ + ctx->pic_w = 0; + ctx->pic_h = 0; + /* tile info */ + ctx->tile_num = 0; + ctx->tile_dir = 0; + /* general */ + ctx->fmt = MPP_HAL_FMT_BUTT; + ctx->bit_depth = 0; + ctx->buf_sz = 0; + /* h264 */ + ctx->mbaff_flag = 0; + /* avs2 */ + ctx->alf_en = 0; + /* av1 */ + ctx->lr_en = 0; + ctx->upsc_en = 0; + + memset(ctx->buf_info, 0, sizeof(Vdpu38xRcbBufInfo) * RCB_BUF_CNT); + + return MPP_OK; +} + +MPP_RET vdpu38x_rcb_add_tile_info(Vdpu38xRcbCtx *ctx, RcbTileInfo *tile_info) +{ + RcbTileInfo *tl_infos = NULL; + RcbTileInfo *p = NULL; + + tl_infos = ctx->tile_infos; + if (ctx->tile_num >= ctx->tile_info_cap) { + ctx->tile_info_cap += 4; + tl_infos = (RcbTileInfo *)mpp_realloc(tl_infos, RcbTileInfo, ctx->tile_info_cap); + if (!tl_infos) { + mpp_loge_f("realloc failed\n"); + return MPP_ERR_NOMEM; + } + ctx->tile_infos = tl_infos; + } + p = &tl_infos[ctx->tile_num++]; + memcpy(p, tile_info, sizeof(RcbTileInfo)); + + return MPP_OK; +} + +MPP_RET vdpu38x_rcb_dump_tile_info(Vdpu38xRcbCtx *ctx) +{ + RcbTileInfo *p = ctx->tile_infos; + RK_U32 i; + + for (i = 0; i < ctx->tile_num; i++) { + mpp_logi("tile %d: idx %d lt(%d,%d) w %d h %d\n", + i, p[i].idx, p[i].lt_x, p[i].lt_y, p[i].w, p[i].h); + } + + return MPP_OK; +} + +Vdpu38xFmt vdpu38x_fmt_mpp2hal(MppFrameFormat mpp_fmt) +{ + switch (mpp_fmt & MPP_FRAME_FMT_MASK) { + case MPP_FMT_YUV400 : { + return MPP_HAL_FMT_YUV400; + } break; + case MPP_FMT_YUV420SP : + case MPP_FMT_YUV420SP_10BIT : + case MPP_FMT_YUV420P : + case MPP_FMT_YUV420SP_VU : { + return MPP_HAL_FMT_YUV420; + } break; + case MPP_FMT_YUV422SP : + case MPP_FMT_YUV422SP_10BIT : + case MPP_FMT_YUV422P : + case MPP_FMT_YUV422SP_VU : + case MPP_FMT_YUV422_YUYV : + case MPP_FMT_YUV422_YVYU : + case MPP_FMT_YUV422_UYVY : + case MPP_FMT_YUV422_VYUY : { + return MPP_HAL_FMT_YUV444; + } break; + case MPP_FMT_YUV444SP : + case MPP_FMT_YUV444P : + case MPP_FMT_YUV444SP_10BIT : { + return MPP_HAL_FMT_YUV444; + } break; + default : { + mpp_loge_f("hal format not support %d\n", mpp_fmt); + } break; + } + + return MPP_HAL_FMT_BUTT; +} + +#define VDPU38X_RCB_ACCESSORS(type, field) \ + type vdpu38x_rcb_get_##field(Vdpu38xRcbCtx *ctx) \ + { \ + return ((Vdpu38xRcbCtx*)ctx)->field; \ + } \ + void vdpu38x_rcb_set_##field(Vdpu38xRcbCtx *ctx, type v) \ + { \ + ((Vdpu38xRcbCtx*)ctx)->field = v; \ + } + +VDPU38X_RCB_ACCESSORS(RK_U32, pic_w) +VDPU38X_RCB_ACCESSORS(RK_U32, pic_h) +VDPU38X_RCB_ACCESSORS(RK_U32, tile_dir) +VDPU38X_RCB_ACCESSORS(Vdpu38xFmt, fmt) +VDPU38X_RCB_ACCESSORS(RK_U32, bit_depth) +VDPU38X_RCB_ACCESSORS(RK_U32, mbaff_flag) +VDPU38X_RCB_ACCESSORS(RK_U32, alf_en) +VDPU38X_RCB_ACCESSORS(RK_U32, lr_en) +VDPU38X_RCB_ACCESSORS(RK_U32, upsc_en) + +MPP_RET vdpu38x_rcb_get_len(Vdpu38xRcbCtx *ctx, Vdpu38xTileLoc loc, RK_U32 *len) +{ + RcbTileInfo *tile_p = NULL; + RK_U32 i = 0; + RK_U32 res = 0; + RK_U32 ret = MPP_OK; + + tile_p = ctx->tile_infos; + + if (loc == VDPU38X_RCB_IN_TILE_ROW) { + for (i = 0, res = 0; i < ctx->tile_num; i++) + res = res < tile_p[i].w ? tile_p[i].w : res; + } else if (loc == VDPU38X_RCB_IN_TILE_COL) { + mpp_loge_f("invalid tile loc %d\n", loc); + ret = MPP_NOK; + } else if (loc == VDPU38X_RCB_ON_TILE_ROW) { + res = ctx->pic_w; + } else if (loc == VDPU38X_RCB_ON_TILE_COL) { + if (ctx->tile_dir == 0) { /* left to right */ + for (i = 0, res = 0; i < ctx->tile_num; i++) + res = res < tile_p[i].h ? tile_p[i].h : res; + } else { /* top to bottom */ + res = ctx->pic_h; + } + } else { + mpp_loge_f("invalid tile loc %d\n", loc); + ret = MPP_NOK; + } + *len = res; + + return ret; +} + +MPP_RET vdpu38x_rcb_get_extra_size(Vdpu38xRcbCtx *ctx, Vdpu38xTileLoc loc, RK_U32 *extra_sz) +{ + RK_U32 tl_row_num = 0; + RK_U32 tl_col_num = 0; + RK_U32 buf_size = 0; + RK_U32 i; + + for (i = 0; i < ctx->tile_num; i++) { + if (ctx->tile_infos[i].lt_y == 0) + tl_row_num++; + if (ctx->tile_infos[i].lt_x == 0) + tl_col_num++; + } + + if (loc == VDPU38X_RCB_ON_TILE_ROW) + buf_size = (tl_row_num - 1) * 64; + else if (loc == VDPU38X_RCB_ON_TILE_COL) + buf_size = (tl_col_num - 1) * 64; + else + buf_size = 0; + + *extra_sz = buf_size; + + return MPP_OK; +} + +RK_U32 vdpu38x_rcb_reg_info_update(Vdpu38xRcbCtx *ctx, Vdpu38xRcbType type, RK_U32 idx, + RK_FLOAT sz) +{ + RK_U32 extra_sz = 0; + RK_U32 result = 0; + Vdpu38xTileLoc loc = vdpu38x_rcb_type2loc_map[type]; + + vdpu38x_rcb_get_extra_size(ctx, loc, &extra_sz); + result = MPP_RCB_BYTES(sz) + extra_sz; + ctx->buf_info[type].reg_idx = idx; + ctx->buf_info[type].offset = ctx->buf_sz; + ctx->buf_info[type].size = result; + ctx->buf_sz += result; + + return result; +} + +RK_U32 vdpu38x_rcb_get_total_size(Vdpu38xRcbCtx *ctx) +{ + return ctx->buf_sz; +} + +MPP_RET vdpu38x_rcb_register_calc_handle(Vdpu38xRcbCtx *ctx, Vdpu38xRcbCalc_f func) +{ + ctx->calc_func = func; + + return MPP_OK; +} + +MPP_RET vdpu38x_rcb_calc_exec(Vdpu38xRcbCtx *ctx, RK_U32 *total_sz) +{ + if (ctx->calc_func) { + mpp_logi("error: The compute function is not registered\n"); + return MPP_NOK; + } + + return ctx->calc_func(ctx, total_sz); +} + +void vdpu38x_setup_rcb(Vdpu38xRcbCtx *ctx, Vdpu38xRegCommonAddr *reg, MppDev dev, + MppBuffer buf) +{ + Vdpu38xRcbBufInfo *info = ctx->buf_info; + RK_U32 i; + + reg->reg140_rcb_strmd_row_offset = mpp_buffer_get_fd(buf); + reg->reg142_rcb_strmd_tile_row_offset = mpp_buffer_get_fd(buf); + reg->reg144_rcb_inter_row_offset = mpp_buffer_get_fd(buf); + reg->reg146_rcb_inter_tile_row_offset = mpp_buffer_get_fd(buf); + reg->reg148_rcb_intra_row_offset = mpp_buffer_get_fd(buf); + reg->reg150_rcb_intra_tile_row_offset = mpp_buffer_get_fd(buf); + reg->reg152_rcb_filterd_row_offset = mpp_buffer_get_fd(buf); + reg->reg154_rcb_filterd_protect_row_offset = mpp_buffer_get_fd(buf); + reg->reg156_rcb_filterd_tile_row_offset = mpp_buffer_get_fd(buf); + reg->reg158_rcb_filterd_tile_col_offset = mpp_buffer_get_fd(buf); + reg->reg160_rcb_filterd_av1_upscale_tile_col_offset = mpp_buffer_get_fd(buf); + + reg->reg141_rcb_strmd_row_len = info[RCB_STRMD_IN_ROW].size; + reg->reg143_rcb_strmd_tile_row_len = info[RCB_STRMD_ON_ROW].size; + reg->reg145_rcb_inter_row_len = info[RCB_INTER_IN_ROW].size; + reg->reg147_rcb_inter_tile_row_len = info[RCB_INTER_ON_ROW].size; + reg->reg149_rcb_intra_row_len = info[RCB_INTRA_IN_ROW].size; + reg->reg151_rcb_intra_tile_row_len = info[RCB_INTRA_ON_ROW].size; + reg->reg153_rcb_filterd_row_len = info[RCB_FLTD_IN_ROW].size; + reg->reg155_rcb_filterd_protect_row_len = info[RCB_FLTD_PROT_IN_ROW].size; + reg->reg157_rcb_filterd_tile_row_len = info[RCB_FLTD_ON_ROW].size; + reg->reg159_rcb_filterd_tile_col_len = info[RCB_FLTD_ON_COL].size; + reg->reg161_rcb_filterd_av1_upscale_tile_col_len = info[RCB_FLTD_UPSC_ON_COL].size; + + for (i = 0; i < RCB_BUF_CNT; i++) { + if (info[i].offset) + mpp_dev_set_reg_offset(dev, info[i].reg_idx, info[i].offset); + } +} + +static RK_S32 vdpu38x_compare_rcb_size(const void *a, const void *b) +{ + Vdpu38xRcbBufInfo *p0 = (Vdpu38xRcbBufInfo *)a; + Vdpu38xRcbBufInfo *p1 = (Vdpu38xRcbBufInfo *)b; + + return (p0->size > p1->size) ? -1 : 1; +} + +RK_S32 vdpu38x_set_rcbinfo(MppDev dev, Vdpu38xRcbBufInfo *rcb_info) +{ + MppDevRcbInfoCfg rcb_cfg; + Vdpu38xRcbSetMode set_rcb_mode = RCB_SET_BY_PRIORITY_MODE; + RK_U32 rcb_priority[RCB_BUF_CNT] = { + RCB_FLTD_IN_ROW, + RCB_INTER_IN_ROW, + RCB_INTRA_IN_ROW, + RCB_STRMD_IN_ROW, + RCB_INTER_ON_ROW, + RCB_INTRA_ON_ROW, + RCB_STRMD_ON_ROW, + RCB_FLTD_ON_ROW, + RCB_FLTD_ON_COL, + RCB_FLTD_UPSC_ON_COL, + RCB_FLTD_PROT_IN_ROW, + }; + RK_U32 i; + /* + * RCB_SET_BY_SIZE_SORT_MODE: by size sort + * RCB_SET_BY_PRIORITY_MODE: by priority + */ + + switch (set_rcb_mode) { + case RCB_SET_BY_SIZE_SORT_MODE : { + Vdpu38xRcbBufInfo info[RCB_BUF_CNT]; + + memcpy(info, rcb_info, sizeof(info)); + qsort(info, MPP_ARRAY_ELEMS(info), + sizeof(info[0]), vdpu38x_compare_rcb_size); + + for (i = 0; i < MPP_ARRAY_ELEMS(info); i++) { + rcb_cfg.reg_idx = info[i].reg_idx; + rcb_cfg.size = info[i].size; + if (rcb_cfg.size > 0) { + mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg); + } else + break; + } + } break; + case RCB_SET_BY_PRIORITY_MODE : { + Vdpu38xRcbBufInfo *info = rcb_info; + RK_U32 index = 0; + + for (i = 0; i < MPP_ARRAY_ELEMS(rcb_priority); i ++) { + index = rcb_priority[i]; + + rcb_cfg.reg_idx = info[index].reg_idx; + rcb_cfg.size = info[index].size; + if (rcb_cfg.size > 0) { + mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg); + } + } + } break; + default: + break; + } + + return 0; +} + +MPP_RET vdpu38x_rcb_dump_rcb_result(Vdpu38xRcbCtx *ctx) +{ + Vdpu38xRcbBufInfo *info = ctx->buf_info; + static const char rcb_descs[RCB_BUF_CNT][32] = { + "RCB_STRMD_IN_ROW", + "RCB_STRMD_ON_ROW", + "RCB_INTER_IN_ROW", + "RCB_INTER_ON_ROW", + "RCB_INTRA_IN_ROW", + "RCB_INTRA_ON_ROW", + "RCB_FLTD_IN_ROW", + "RCB_FLTD_PROT_IN_ROW", + "RCB_FLTD_ON_ROW", + "RCB_FLTD_ON_COL", + "RCB_FLTD_UPSC_ON_COL", + }; + RK_U32 i; + + for (i = 0; i < RCB_BUF_CNT; i++) { + mpp_logi("rcb buf %2d: desc %-24s reg_idx %3d size %-8d offset %-4d\n", + i, rcb_descs[i], info[i].reg_idx, info[i].size, info[i].offset); + } + + return MPP_OK; +} + +MPP_RET vdpu38x_get_fbc_off(MppFrame mframe, RK_U32 *head_stride, RK_U32 *pld_stride, RK_U32 *pld_offset) +{ + MppFrameFormat fmt; + RK_U32 fbc_unit_w; + RK_U32 fbc_unit_h; + RK_U32 bit_depth; + Vdpu38xFmt fmt_type; + static const RK_FLOAT fmt_coeff[MPP_HAL_FMT_BUTT] = {1, 1.5, 2, 3}; + RK_U32 hor_virstride = 0; + RK_U32 ver_virstride = 0; + RK_U32 fbc_hdr_stride = mpp_frame_get_fbc_hdr_stride(mframe); + RK_U32 h = MPP_ALIGN(mpp_frame_get_height(mframe), 64); + RK_U32 fbc_unit_bit_sz; + RK_U32 head_vir_w; // byte + RK_U32 pld_real_w; // byte + RK_U32 pld_vir_w; // byte + + hor_virstride = mpp_frame_get_hor_stride(mframe); + ver_virstride = mpp_frame_get_ver_stride(mframe); + fmt = mpp_frame_get_fmt(mframe); + + if (MPP_FRAME_FMT_IS_AFBC(fmt)) { + fbc_unit_w = 32; + fbc_unit_h = 8; + } else if (MPP_FRAME_FMT_IS_RKFBC(fmt)) { + fbc_unit_w = 64; + fbc_unit_h = 4; + } + + bit_depth = MPP_FRAME_FMT_IS_YUV_10BIT(fmt) ? 10 : 8; + fmt_type = vdpu38x_fmt_mpp2hal(fmt); + + /* head stride */ + head_vir_w = MPP_ALIGN(fbc_hdr_stride, fbc_unit_w) / fbc_unit_w * 16; + *head_stride = head_vir_w >> 4; + + /* pld stride */ + fbc_unit_bit_sz = MPP_ALIGN((int)ceilf(fbc_unit_w * fbc_unit_h * fmt_coeff[fmt_type] * bit_depth), 128); + pld_real_w = fbc_hdr_stride / fbc_unit_w * fbc_unit_bit_sz >> 3; + pld_vir_w = MPP_ALIGN(pld_real_w, 16); + *pld_stride = pld_vir_w >> 4; + + /* pld offset*/ + *pld_offset = head_vir_w * (MPP_ALIGN(ver_virstride, fbc_unit_h) / fbc_unit_h); + + return MPP_OK; +} + +MPP_RET vdpu38x_get_tile4x4_h_stride_coeff(MppFrameFormat fmt, RK_U32 *coeff) +{ + RK_U32 val = 0; + MPP_RET ret = MPP_OK; + + switch (fmt & MPP_FRAME_FMT_MASK) { + case MPP_FMT_YUV400 : { + val = 4; + } break; + case MPP_FMT_YUV420SP : + case MPP_FMT_YUV420SP_10BIT : + case MPP_FMT_YUV420P : + case MPP_FMT_YUV420SP_VU : { + val = 6; + } break; + case MPP_FMT_YUV422SP: + case MPP_FMT_YUV422SP_10BIT: + case MPP_FMT_YUV422P : + case MPP_FMT_YUV422SP_VU : + case MPP_FMT_YUV422_YUYV : + case MPP_FMT_YUV422_YVYU : + case MPP_FMT_YUV422_UYVY : + case MPP_FMT_YUV422_VYUY : { + val = 8; + } break; + case MPP_FMT_YUV444SP : + case MPP_FMT_YUV444P : + case MPP_FMT_YUV444SP_10BIT : { + val = 12; + } break; + default : { + mpp_err_f("format not support %d\n", fmt); + ret = MPP_NOK; + } break; + } + + *coeff = val; + + return ret; +} + +void vdpu38x_setup_statistic(Vdpu38xCtrlReg *ctrl_regs) +{ + ctrl_regs->reg28.axi_perf_work_e = 1; + ctrl_regs->reg28.axi_cnt_type = 1; + ctrl_regs->reg28.rd_latency_id = 11; + + ctrl_regs->reg29.addr_align_type = 1; + ctrl_regs->reg29.ar_cnt_id_type = 0; + ctrl_regs->reg29.aw_cnt_id_type = 1; + ctrl_regs->reg29.ar_count_id = 17; + ctrl_regs->reg29.aw_count_id = 0; + ctrl_regs->reg29.rd_band_width_mode = 0; + + /* set hurry */ + ctrl_regs->reg30.axi_wr_qos = 0; + ctrl_regs->reg30.axi_rd_qos = 0; +} + +void vdpu38x_afbc_align_calc(MppBufSlots slots, MppFrame frame, RK_U32 expand) +{ + RK_U32 ver_stride = 0; + RK_U32 img_height = mpp_frame_get_height(frame); + RK_U32 img_width = mpp_frame_get_width(frame); + RK_U32 hdr_stride = (*compat_ext_fbc_hdr_256_odd) ? + (MPP_ALIGN(img_width, 256) | 256) : + (MPP_ALIGN(img_width, 64)); + + mpp_slots_set_prop(slots, SLOTS_HOR_ALIGN, mpp_align_64); + mpp_slots_set_prop(slots, SLOTS_VER_ALIGN, mpp_align_16); + + mpp_frame_set_fbc_hdr_stride(frame, hdr_stride); + + ver_stride = mpp_align_16(img_height); + if (*compat_ext_fbc_buf_size) { + ver_stride += expand; + } + mpp_frame_set_ver_stride(frame, ver_stride); +} + +void vdpu38x_update_thumbnail_frame_info(MppFrame frame) +{ + RK_U32 down_scale_height = mpp_frame_get_height(frame) >> 1; + RK_U32 down_scale_width = mpp_frame_get_width(frame) >> 1; + RK_U32 down_scale_ver = MPP_ALIGN(down_scale_height, 16); + RK_U32 down_scale_hor = MPP_ALIGN(down_scale_width, 16); + RK_U32 down_scale_buf_size = 0; + + if (!MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(frame))) { + down_scale_hor = mpp_align_128_odd_plus_64(down_scale_hor); + down_scale_ver = mpp_frame_get_ver_stride(frame) >> 1; + } + + down_scale_buf_size = down_scale_hor * down_scale_ver * 3 / 2; + /* + * no matter what format, scale down image will output as 8bit raster format; + */ + mpp_frame_set_fmt(frame, MPP_FMT_YUV420SP); + mpp_frame_set_width(frame, down_scale_width); + mpp_frame_set_height(frame, down_scale_height); + mpp_frame_set_hor_stride(frame, down_scale_hor); + mpp_frame_set_ver_stride(frame, down_scale_ver); + mpp_frame_set_buf_size(frame, down_scale_buf_size); +} + +void vdpu38x_setup_down_scale(MppFrame frame, MppDev dev, Vdpu38xCtrlReg *com, void* comParas) +{ + RK_U32 down_scale_height = mpp_frame_get_height(frame) >> 1; + RK_U32 down_scale_width = mpp_frame_get_width(frame) >> 1; + RK_U32 down_scale_ver = MPP_ALIGN(down_scale_height, 16); + RK_U32 down_scale_hor = MPP_ALIGN(down_scale_width, 16); + + Vdpu38xRegCommParas* paras = (Vdpu38xRegCommParas*)comParas; + MppFrameFormat fmt = mpp_frame_get_fmt(frame); + MppMeta meta = mpp_frame_get_meta(frame); + RK_U32 down_scale_y_offset = 0; + RK_U32 down_scale_uv_offset = 0; + RK_U32 down_scale_y_virstride = down_scale_ver * down_scale_hor; + RK_U32 downscale_buf_size; + + if (!MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(frame))) { + down_scale_hor = mpp_align_128_odd_plus_64(down_scale_hor); + down_scale_ver = mpp_frame_get_ver_stride(frame) >> 1; + down_scale_y_virstride = down_scale_ver * down_scale_hor; + } + /* + * no matter what format, scale down image will output as 8bit raster format; + * down_scale image buffer size was already added to the buf_size of mpp_frame, + * which was calculated in mpp_buf_slot.cpp: (size = original_size + scaledown_size) + */ + switch ((fmt & MPP_FRAME_FMT_MASK)) { + case MPP_FMT_YUV400 : { + downscale_buf_size = down_scale_y_virstride; + } break; + case MPP_FMT_YUV420SP_10BIT : + case MPP_FMT_YUV420SP : { + downscale_buf_size = down_scale_y_virstride * 3 / 2; + } break; + case MPP_FMT_YUV422SP_10BIT : + case MPP_FMT_YUV422SP : { + downscale_buf_size = down_scale_y_virstride * 2; + } break; + case MPP_FMT_YUV444SP : { + downscale_buf_size = down_scale_y_virstride * 3; + } break; + default : { + downscale_buf_size = down_scale_y_virstride * 3 / 2; + } break; + } + downscale_buf_size = MPP_ALIGN(downscale_buf_size, 16); + + down_scale_y_offset = MPP_ALIGN((mpp_frame_get_buf_size(frame) - downscale_buf_size), 16); + down_scale_uv_offset = down_scale_y_offset + down_scale_y_virstride; + + com->reg9.scale_down_en = 1; + com->reg9.av1_fgs_en = 0; + paras->reg71_scl_ref_hor_virstride = down_scale_hor >> 4; + paras->reg72_scl_ref_raster_uv_hor_virstride = down_scale_hor >> 4; + if ((fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV444SP) + paras->reg72_scl_ref_raster_uv_hor_virstride = down_scale_hor >> 3; + paras->reg73_scl_ref_virstride = down_scale_y_virstride >> 4; + if (mpp_frame_get_thumbnail_en(frame) == MPP_FRAME_THUMBNAIL_MIXED) { + mpp_dev_set_reg_offset(dev, 133, down_scale_y_offset); + mpp_meta_set_s32(meta, KEY_DEC_TBN_Y_OFFSET, down_scale_y_offset); + mpp_meta_set_s32(meta, KEY_DEC_TBN_UV_OFFSET, down_scale_uv_offset); + } +} + +#ifdef DUMP_VDPU38X_DATAS +RK_U32 vdpu38x_dump_cur_frm = 0; +char vdpu38x_dump_cur_dir[128]; +char vdpu38x_dump_cur_fname_path[512]; + +MPP_RET vdpu38x_flip_string(char *str) +{ + RK_U32 len = strlen(str); + RK_U32 i, j; + + for (i = 0, j = len - 1; i <= j; i++, j--) { + // swapping characters + char c = str[i]; + str[i] = str[j]; + str[j] = c; + } + + return MPP_OK; +} + +MPP_RET vdpu38x_dump_data_to_file(char *fname_path, void *data, RK_U32 data_bit_size, + RK_U32 line_bits, RK_U32 big_end, RK_U32 append) +{ + RK_U8 *buf_p = (RK_U8 *)data; + RK_U8 cur_data; + RK_U32 i; + RK_U32 loop_cnt; + FILE *dump_fp = NULL; + char line_tmp[256]; + RK_U32 str_idx = 0; + + if (append) + dump_fp = fopen(fname_path, "aw+"); + else + dump_fp = fopen(fname_path, "w+"); + if (!dump_fp) { + mpp_err_f("open file: %s error!\n", fname_path); + return MPP_NOK; + } + if (append) + fseek(dump_fp, 0, SEEK_END); + + if ((data_bit_size % 4 != 0) || (line_bits % 8 != 0)) { + mpp_err_f("line bits not align to 4! data_bit_size: %d line_bits: %d\n", + data_bit_size, line_bits); + return MPP_NOK; + } + + loop_cnt = data_bit_size / 8; + for (i = 0; i < loop_cnt; i++) { + cur_data = buf_p[i]; + + sprintf(&line_tmp[str_idx++], "%0x", cur_data & 0xf); + if ((i * 8 + 4) % line_bits == 0) { + line_tmp[str_idx++] = '\0'; + str_idx = 0; + if (!big_end) + vdpu38x_flip_string(line_tmp); + fprintf(dump_fp, "%s\n", line_tmp); + } + sprintf(&line_tmp[str_idx++], "%0x", (cur_data >> 4) & 0xf); + if ((i * 8 + 8) % line_bits == 0) { + line_tmp[str_idx++] = '\0'; + str_idx = 0; + if (!big_end) + vdpu38x_flip_string(line_tmp); + fprintf(dump_fp, "%s\n", line_tmp); + } + } + + // last line + if (data_bit_size % 4) { + cur_data = buf_p[i]; + sprintf(&line_tmp[str_idx++], "%0x", cur_data & 0xf); + if ((i * 8 + 8) % line_bits == 0) { + line_tmp[str_idx++] = '\0'; + str_idx = 0; + if (!big_end) + vdpu38x_flip_string(line_tmp); + fprintf(dump_fp, "%s\n", line_tmp); + } + } + if (data_bit_size % line_bits) { + loop_cnt = (line_bits - (data_bit_size % line_bits)) / 4; + for (i = 0; i < loop_cnt; i++) + sprintf(&line_tmp[str_idx++], "%0x", 0); + line_tmp[str_idx++] = '\0'; + str_idx = 0; + if (!big_end) + vdpu38x_flip_string(line_tmp); + fprintf(dump_fp, "%s\n", line_tmp); + } + + fflush(dump_fp); + fclose(dump_fp); + + return MPP_OK; +} +#endif