1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include "iris_instance.h" 7 #include "iris_vpu_buffer.h" 8 9 static u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) 10 { 11 u32 size_yuv, size_bin_hdr, size_bin_res; 12 13 size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ? 14 ((BIN_BUFFER_THRESHOLD * 3) >> 1) : 15 ((frame_width * frame_height * 3) >> 1); 16 size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT; 17 size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT; 18 size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, 19 DMA_ALIGNMENT) * num_vpp_pipes; 20 size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, 21 DMA_ALIGNMENT) * num_vpp_pipes; 22 23 return size_bin_hdr + size_bin_res; 24 } 25 26 static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) 27 { 28 u32 n_aligned_h = ALIGN(frame_height, 16); 29 u32 n_aligned_w = ALIGN(frame_width, 16); 30 31 return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); 32 } 33 34 static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount) 35 { 36 u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16); 37 u32 frame_width_in_mbs = DIV_ROUND_UP(frame_width, 16); 38 u32 col_zero_aligned_width = (frame_width_in_mbs << 2); 39 u32 col_mv_aligned_width = (frame_width_in_mbs << 7); 40 u32 col_zero_size, size_colloc; 41 42 col_mv_aligned_width = ALIGN(col_mv_aligned_width, 16); 43 col_zero_aligned_width = ALIGN(col_zero_aligned_width, 16); 44 col_zero_size = col_zero_aligned_width * 45 ((frame_height_in_mbs + 1) >> 1); 46 col_zero_size = ALIGN(col_zero_size, 64); 47 col_zero_size <<= 1; 48 col_zero_size = ALIGN(col_zero_size, 512); 49 size_colloc = col_mv_aligned_width * ((frame_height_in_mbs + 1) >> 1); 50 size_colloc = ALIGN(size_colloc, 64); 51 size_colloc <<= 1; 52 size_colloc = ALIGN(size_colloc, 512); 53 size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2); 54 55 return (size_colloc * (_comv_bufcount)) + 512; 56 } 57 58 static u32 size_h264d_bse_cmd_buf(u32 frame_height) 59 { 60 u32 height = ALIGN(frame_height, 32); 61 62 return min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) * 63 SIZE_H264D_BSE_CMD_PER_BUF; 64 } 65 66 static u32 size_h264d_vpp_cmd_buf(u32 frame_height) 67 { 68 u32 size, height = ALIGN(frame_height, 32); 69 70 size = min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) * 71 SIZE_H264D_VPP_CMD_PER_BUF; 72 73 return size > VPP_CMD_MAX_SIZE ? VPP_CMD_MAX_SIZE : size; 74 } 75 76 static u32 hfi_buffer_persist_h264d(void) 77 { 78 return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 + 79 H264_DISPLAY_BUF_SIZE * H264_NUM_FRM_INFO + 80 NUM_HW_PIC_BUF * SIZE_SEI_USERDATA, 81 DMA_ALIGNMENT); 82 } 83 84 static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) 85 { 86 u32 size_bse, size_vpp, size; 87 88 size_bse = size_h264d_bse_cmd_buf(frame_height); 89 size_vpp = size_h264d_vpp_cmd_buf(frame_height); 90 size = ALIGN(size_bse, DMA_ALIGNMENT) + 91 ALIGN(size_vpp, DMA_ALIGNMENT) + 92 ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT); 93 94 return ALIGN(size, DMA_ALIGNMENT); 95 } 96 97 static u32 size_vpss_lb(u32 frame_width, u32 frame_height) 98 { 99 u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size; 100 u32 opb_wr_top_line_chroma_buffer_size; 101 u32 opb_wr_top_line_luma_buffer_size; 102 u32 macrotiling_size = 32; 103 104 opb_wr_top_line_luma_buffer_size = 105 ALIGN(frame_width, macrotiling_size) / macrotiling_size * 256; 106 opb_wr_top_line_luma_buffer_size = 107 ALIGN(opb_wr_top_line_luma_buffer_size, DMA_ALIGNMENT) + 108 (MAX_TILE_COLUMNS - 1) * 256; 109 opb_wr_top_line_luma_buffer_size = 110 max_t(u32, opb_wr_top_line_luma_buffer_size, (32 * ALIGN(frame_height, 8))); 111 opb_wr_top_line_chroma_buffer_size = opb_wr_top_line_luma_buffer_size; 112 opb_lb_wr_llb_uv_buffer_size = 113 ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32); 114 opb_lb_wr_llb_y_buffer_size = 115 ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32); 116 return opb_wr_top_line_luma_buffer_size + 117 opb_wr_top_line_chroma_buffer_size + 118 opb_lb_wr_llb_uv_buffer_size + 119 opb_lb_wr_llb_y_buffer_size; 120 } 121 122 static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height, 123 bool is_opb, u32 num_vpp_pipes) 124 { 125 u32 vpss_lb_size = 0; 126 u32 size; 127 128 size = ALIGN(size_h264d_lb_fe_top_data(frame_width), DMA_ALIGNMENT) + 129 ALIGN(size_h264d_lb_fe_top_ctrl(frame_width), DMA_ALIGNMENT) + 130 ALIGN(size_h264d_lb_fe_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes + 131 ALIGN(size_h264d_lb_se_top_ctrl(frame_width), DMA_ALIGNMENT) + 132 ALIGN(size_h264d_lb_se_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes + 133 ALIGN(size_h264d_lb_pe_top_data(frame_width), DMA_ALIGNMENT) + 134 ALIGN(size_h264d_lb_vsp_top(frame_width), DMA_ALIGNMENT) + 135 ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_height), DMA_ALIGNMENT) * 2 + 136 ALIGN(size_h264d_qp(frame_width, frame_height), DMA_ALIGNMENT); 137 size = ALIGN(size, DMA_ALIGNMENT); 138 if (is_opb) 139 vpss_lb_size = size_vpss_lb(frame_width, frame_height); 140 141 return ALIGN((size + vpss_lb_size), DMA_ALIGNMENT); 142 } 143 144 static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) 145 { 146 u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; 147 struct v4l2_format *f = inst->fmt_src; 148 u32 height = f->fmt.pix_mp.height; 149 u32 width = f->fmt.pix_mp.width; 150 151 return hfi_buffer_bin_h264d(width, height, num_vpp_pipes); 152 } 153 154 static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) 155 { 156 u32 num_comv = VIDEO_MAX_FRAME; 157 struct v4l2_format *f = inst->fmt_src; 158 u32 height = f->fmt.pix_mp.height; 159 u32 width = f->fmt.pix_mp.width; 160 161 return hfi_buffer_comv_h264d(width, height, num_comv); 162 } 163 164 static u32 iris_vpu_dec_persist_size(struct iris_inst *inst) 165 { 166 return hfi_buffer_persist_h264d(); 167 } 168 169 static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) 170 { 171 if (iris_split_mode_enabled(inst)) 172 return iris_get_buffer_size(inst, BUF_DPB); 173 else 174 return 0; 175 } 176 177 static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst) 178 { 179 u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; 180 struct v4l2_format *f = inst->fmt_src; 181 u32 height = f->fmt.pix_mp.height; 182 u32 width = f->fmt.pix_mp.width; 183 184 return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes); 185 } 186 187 static u32 iris_vpu_dec_line_size(struct iris_inst *inst) 188 { 189 u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; 190 struct v4l2_format *f = inst->fmt_src; 191 u32 height = f->fmt.pix_mp.height; 192 u32 width = f->fmt.pix_mp.width; 193 bool is_opb = false; 194 195 if (iris_split_mode_enabled(inst)) 196 is_opb = true; 197 198 return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes); 199 } 200 201 static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) 202 { 203 return iris_vpu_dec_comv_size(inst) + 204 iris_vpu_dec_non_comv_size(inst) + 205 iris_vpu_dec_line_size(inst); 206 } 207 208 struct iris_vpu_buf_type_handle { 209 enum iris_buffer_type type; 210 u32 (*handle)(struct iris_inst *inst); 211 }; 212 213 int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) 214 { 215 const struct iris_vpu_buf_type_handle *buf_type_handle_arr; 216 u32 size = 0, buf_type_handle_size, i; 217 218 static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle[] = { 219 {BUF_BIN, iris_vpu_dec_bin_size }, 220 {BUF_COMV, iris_vpu_dec_comv_size }, 221 {BUF_NON_COMV, iris_vpu_dec_non_comv_size }, 222 {BUF_LINE, iris_vpu_dec_line_size }, 223 {BUF_PERSIST, iris_vpu_dec_persist_size }, 224 {BUF_DPB, iris_vpu_dec_dpb_size }, 225 {BUF_SCRATCH_1, iris_vpu_dec_scratch1_size }, 226 }; 227 228 buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle); 229 buf_type_handle_arr = dec_internal_buf_type_handle; 230 231 for (i = 0; i < buf_type_handle_size; i++) { 232 if (buf_type_handle_arr[i].type == buffer_type) { 233 size = buf_type_handle_arr[i].handle(inst); 234 break; 235 } 236 } 237 238 return size; 239 } 240 241 static inline int iris_vpu_dpb_count(struct iris_inst *inst) 242 { 243 if (iris_split_mode_enabled(inst)) { 244 return inst->fw_min_count ? 245 inst->fw_min_count : inst->buffers[BUF_OUTPUT].min_count; 246 } 247 248 return 0; 249 } 250 251 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type) 252 { 253 switch (buffer_type) { 254 case BUF_INPUT: 255 return MIN_BUFFERS; 256 case BUF_OUTPUT: 257 return inst->fw_min_count; 258 case BUF_BIN: 259 case BUF_COMV: 260 case BUF_NON_COMV: 261 case BUF_LINE: 262 case BUF_PERSIST: 263 case BUF_SCRATCH_1: 264 return 1; /* internal buffer count needed by firmware is 1 */ 265 case BUF_DPB: 266 return iris_vpu_dpb_count(inst); 267 default: 268 return 0; 269 } 270 } 271