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
size_h264d_hw_bin_buffer(u32 frame_width,u32 frame_height,u32 num_vpp_pipes)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
hfi_buffer_bin_h264d(u32 frame_width,u32 frame_height,u32 num_vpp_pipes)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
hfi_buffer_comv_h264d(u32 frame_width,u32 frame_height,u32 _comv_bufcount)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
size_h264d_bse_cmd_buf(u32 frame_height)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
size_h264d_vpp_cmd_buf(u32 frame_height)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
hfi_buffer_persist_h264d(void)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
hfi_buffer_non_comv_h264d(u32 frame_width,u32 frame_height,u32 num_vpp_pipes)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
size_vpss_lb(u32 frame_width,u32 frame_height)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
hfi_buffer_line_h264d(u32 frame_width,u32 frame_height,bool is_opb,u32 num_vpp_pipes)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
iris_vpu_dec_bin_size(struct iris_inst * inst)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
iris_vpu_dec_comv_size(struct iris_inst * inst)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
iris_vpu_dec_persist_size(struct iris_inst * inst)164 static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
165 {
166 return hfi_buffer_persist_h264d();
167 }
168
iris_vpu_dec_dpb_size(struct iris_inst * inst)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
iris_vpu_dec_non_comv_size(struct iris_inst * inst)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
iris_vpu_dec_line_size(struct iris_inst * inst)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
iris_vpu_dec_scratch1_size(struct iris_inst * inst)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
iris_vpu_buf_size(struct iris_inst * inst,enum iris_buffer_type buffer_type)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
iris_vpu_dpb_count(struct iris_inst * inst)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
iris_vpu_buf_count(struct iris_inst * inst,enum iris_buffer_type buffer_type)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