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