xref: /linux/drivers/media/platform/qcom/iris/iris_buffer.c (revision f4cdf7ca9a1fdcca413157df19753f388a5a224e)
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 <media/v4l2-event.h>
7 #include <media/v4l2-mem2mem.h>
8 
9 #include "iris_buffer.h"
10 #include "iris_instance.h"
11 #include "iris_power.h"
12 #include "iris_vpu_buffer.h"
13 
14 #define PIXELS_4K 4096
15 #define MAX_WIDTH 4096
16 #define MAX_HEIGHT 2304
17 #define Y_STRIDE_ALIGN 128
18 #define Y_STRIDE_ALIGN_P010 256
19 #define UV_STRIDE_ALIGN 128
20 #define UV_STRIDE_ALIGN_P010 256
21 #define Y_SCANLINE_ALIGN 32
22 #define Y_SCANLINE_ALIGN_QC10C 16
23 #define UV_SCANLINE_ALIGN 16
24 #define UV_SCANLINE_ALIGN_QC08C 32
25 #define META_STRIDE_ALIGNED 64
26 #define META_SCANLINE_ALIGNED 16
27 #define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT, 16))
28 
29 /*
30  * NV12:
31  * YUV 4:2:0 image with a plane of 8 bit Y samples followed
32  * by an interleaved U/V plane containing 8 bit 2x2 subsampled
33  * colour difference samples.
34  *
35  * <-Y/UV_Stride (aligned to 128)->
36  * <------- Width ------->
37  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^
38  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
39  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |
40  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          y_scanlines (aligned to 32)
41  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
42  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
43  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
44  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |
45  * . . . . . . . . . . . . . . . .              |
46  * . . . . . . . . . . . . . . . .              |
47  * . . . . . . . . . . . . . . . .              |
48  * . . . . . . . . . . . . . . . .              V
49  * U V U V U V U V U V U V . . . .  ^
50  * U V U V U V U V U V U V . . . .  |
51  * U V U V U V U V U V U V . . . .  |
52  * U V U V U V U V U V U V . . . .  uv_scanlines (aligned to 16)
53  * . . . . . . . . . . . . . . . .  |
54  * . . . . . . . . . . . . . . . .  V
55  * . . . . . . . . . . . . . . . .  --> Buffer size aligned to 4K
56  *
57  * y_stride : Width aligned to 128
58  * uv_stride : Width aligned to 128
59  * y_scanlines: Height aligned to 32
60  * uv_scanlines: Height/2 aligned to 16
61  * Total size = align((y_stride * y_scanlines
62  *          + uv_stride * uv_scanlines , 4096)
63  *
64  * Note: All the alignments are hardware requirements.
65  */
66 static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst)
67 {
68 	u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines;
69 	struct v4l2_format *f;
70 
71 	if (inst->domain == DECODER)
72 		f = inst->fmt_dst;
73 	else
74 		f = inst->fmt_src;
75 
76 	y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN);
77 	uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN);
78 	y_scanlines = ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN);
79 	uv_scanlines = ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN);
80 	y_plane = y_stride * y_scanlines;
81 	uv_plane = uv_stride * uv_scanlines;
82 
83 	return ALIGN(y_plane + uv_plane, PIXELS_4K);
84 }
85 
86 /*
87  * P010:
88  * YUV 4:2:0 image with a plane of 10 bit Y samples followed
89  * by an interleaved U/V plane containing 10 bit 2x2 subsampled
90  * colour difference samples.
91  *
92  * <-Y/UV_Stride (aligned to 256)->
93  * <----- Width*2 ------->
94  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^
95  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
96  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |
97  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          y_scanlines (aligned to 32)
98  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
99  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
100  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
101  * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |
102  * . . . . . . . . . . . . . . . .              |
103  * . . . . . . . . . . . . . . . .              |
104  * . . . . . . . . . . . . . . . .              |
105  * . . . . . . . . . . . . . . . .              V
106  * U V U V U V U V U V U V . . . .  ^
107  * U V U V U V U V U V U V . . . .  |
108  * U V U V U V U V U V U V . . . .  |
109  * U V U V U V U V U V U V . . . .  uv_scanlines (aligned to 16)
110  * . . . . . . . . . . . . . . . .  |
111  * . . . . . . . . . . . . . . . .  V
112  * . . . . . . . . . . . . . . . .  --> Buffer size aligned to 4K
113  *
114  * y_stride : Width*2 aligned to 256
115  * uv_stride : Width*2 aligned to 256
116  * y_scanlines: Height aligned to 32
117  * uv_scanlines: Height/2 aligned to 16
118  * Total size = align((y_stride * y_scanlines
119  *          + uv_stride * uv_scanlines , 4096)
120  *
121  * Note: All the alignments are hardware requirements.
122  */
123 static u32 iris_yuv_buffer_size_p010(struct iris_inst *inst)
124 {
125 	u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines;
126 	struct v4l2_format *f;
127 
128 	if (inst->domain == DECODER)
129 		f = inst->fmt_dst;
130 	else
131 		f = inst->fmt_src;
132 
133 	y_stride = ALIGN(f->fmt.pix_mp.width * 2, Y_STRIDE_ALIGN_P010);
134 	uv_stride = ALIGN(f->fmt.pix_mp.width * 2, UV_STRIDE_ALIGN_P010);
135 	y_scanlines = ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN);
136 	uv_scanlines = ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN);
137 	y_plane = y_stride * y_scanlines;
138 	uv_plane = uv_stride * uv_scanlines;
139 
140 	return ALIGN(y_plane + uv_plane, PIXELS_4K);
141 }
142 
143 /*
144  * QC08C:
145  * Compressed Macro-tile format for NV12.
146  * Contains 4 planes in the following order -
147  * (A) Y_Meta_Plane
148  * (B) Y_UBWC_Plane
149  * (C) UV_Meta_Plane
150  * (D) UV_UBWC_Plane
151  *
152  * Y_Meta_Plane consists of meta information to decode compressed
153  * tile data in Y_UBWC_Plane.
154  * Y_UBWC_Plane consists of Y data in compressed macro-tile format.
155  * UBWC decoder block will use the Y_Meta_Plane data together with
156  * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples.
157  *
158  * UV_Meta_Plane consists of meta information to decode compressed
159  * tile data in UV_UBWC_Plane.
160  * UV_UBWC_Plane consists of UV data in compressed macro-tile format.
161  * UBWC decoder block will use UV_Meta_Plane data together with
162  * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2
163  * subsampled color difference samples.
164  *
165  * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
166  * and randomly accessible. There is no dependency between tiles.
167  *
168  * <----- y_meta_stride ----> (aligned to 64)
169  * <-------- Width ------>
170  * M M M M M M M M M M M M . .      ^           ^
171  * M M M M M M M M M M M M . .      |           |
172  * M M M M M M M M M M M M . .      Height      |
173  * M M M M M M M M M M M M . .      |         y_meta_scanlines  (aligned to 16)
174  * M M M M M M M M M M M M . .      |           |
175  * M M M M M M M M M M M M . .      |           |
176  * M M M M M M M M M M M M . .      |           |
177  * M M M M M M M M M M M M . .      V           |
178  * . . . . . . . . . . . . . .                  |
179  * . . . . . . . . . . . . . .                  |
180  * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
181  * . . . . . . . . . . . . . .                  V
182  * <--Compressed tile y_stride---> (aligned to 128)
183  * <------- Width ------->
184  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
185  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
186  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  Height      |
187  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile y_scanlines (aligned to 32)
188  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
189  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
190  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
191  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
192  * . . . . . . . . . . . . . . . .              |
193  * . . . . . . . . . . . . . . . .              |
194  * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
195  * . . . . . . . . . . . . . . . .              V
196  * <----- uv_meta_stride ---->  (aligned to 64)
197  * M M M M M M M M M M M M . .      ^
198  * M M M M M M M M M M M M . .      |
199  * M M M M M M M M M M M M . .      |
200  * M M M M M M M M M M M M . .      uv_meta_scanlines (aligned to 16)
201  * . . . . . . . . . . . . . .      |
202  * . . . . . . . . . . . . . .      V
203  * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
204  * <--Compressed tile uv_stride---> (aligned to 128)
205  * U* V* U* V* U* V* U* V* . . . .  ^
206  * U* V* U* V* U* V* U* V* . . . .  |
207  * U* V* U* V* U* V* U* V* . . . .  |
208  * U* V* U* V* U* V* U* V* . . . .  uv_scanlines (aligned to 32)
209  * . . . . . . . . . . . . . . . .  |
210  * . . . . . . . . . . . . . . . .  V
211  * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
212  *
213  * y_stride: width aligned to 128
214  * uv_stride: width aligned to 128
215  * y_scanlines: height aligned to 32
216  * uv_scanlines: height aligned to 32
217  * y_plane: buffer size aligned to 4096
218  * uv_plane: buffer size aligned to 4096
219  * y_meta_stride: width aligned to 64
220  * y_meta_scanlines: height aligned to 16
221  * y_meta_plane: buffer size aligned to 4096
222  * uv_meta_stride: width aligned to 64
223  * uv_meta_scanlines: height aligned to 16
224  * uv_meta_plane: buffer size aligned to 4096
225  *
226  * Total size = align( y_plane + uv_plane +
227  *           y_meta_plane + uv_meta_plane, 4096)
228  *
229  * Note: All the alignments are hardware requirements.
230  */
231 static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst)
232 {
233 	u32 y_plane, uv_plane, y_stride, uv_stride;
234 	u32 uv_meta_stride, uv_meta_plane;
235 	u32 y_meta_stride, y_meta_plane;
236 	struct v4l2_format *f = NULL;
237 
238 	if (inst->domain == DECODER)
239 		f = inst->fmt_dst;
240 	else
241 		f = inst->fmt_src;
242 
243 	y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALIGNED >> 1),
244 			      META_STRIDE_ALIGNED);
245 	y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height,
246 							  META_SCANLINE_ALIGNED >> 1),
247 					     META_SCANLINE_ALIGNED);
248 	y_meta_plane = ALIGN(y_meta_plane, PIXELS_4K);
249 
250 	y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN);
251 	y_plane = ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN), PIXELS_4K);
252 
253 	uv_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width / 2, META_STRIDE_ALIGNED >> 2),
254 			       META_STRIDE_ALIGNED);
255 	uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height / 2,
256 							    META_SCANLINE_ALIGNED >> 1),
257 					       META_SCANLINE_ALIGNED);
258 	uv_meta_plane = ALIGN(uv_meta_plane, PIXELS_4K);
259 
260 	uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN);
261 	uv_plane = ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLINE_ALIGN_QC08C),
262 			 PIXELS_4K);
263 
264 	return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K);
265 }
266 
267 /*
268  * QC10C:
269  * UBWC-compressed format for P010.
270  * Contains 4 planes in the following order -
271  * (A) Y_Meta_Plane
272  * (B) Y_UBWC_Plane
273  * (C) UV_Meta_Plane
274  * (D) UV_UBWC_Plane
275  *
276  * Y_Meta_Plane consists of meta information to decode compressed
277  * tile data in Y_UBWC_Plane.
278  * Y_UBWC_Plane consists of Y data in compressed macro-tile format.
279  * UBWC decoder block will use the Y_Meta_Plane data together with
280  * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples.
281  *
282  * UV_Meta_Plane consists of meta information to decode compressed
283  * tile data in UV_UBWC_Plane.
284  * UV_UBWC_Plane consists of UV data in compressed macro-tile format.
285  * UBWC decoder block will use UV_Meta_Plane data together with
286  * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2
287  * subsampled color difference samples.
288  *
289  * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
290  * and randomly accessible. There is no dependency between tiles.
291  *
292  * <----- Y Meta stride -----> (aligned to 64)
293  * <-------- Width ----------> (aligned to 48)
294  * M M M M M M M M M M M M . .      ^           ^
295  * M M M M M M M M M M M M . .      |           |
296  * M M M M M M M M M M M M . .      Height      |
297  * M M M M M M M M M M M M . .      |         Meta_Y_Scanlines (aligned to 16)
298  * M M M M M M M M M M M M . .      |           |
299  * M M M M M M M M M M M M . .      |           |
300  * M M M M M M M M M M M M . .      |           |
301  * M M M M M M M M M M M M . .      V           |
302  * . . . . . . . . . . . . . .                  |
303  * . . . . . . . . . . . . . .                  |
304  * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
305  * . . . . . . . . . . . . . .                  V
306  * <--Compressed tile Y stride --> (aligned to 256)
307  * <------- Width * 4/3 ---------> (aligned to 48)
308  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
309  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
310  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  Height      |
311  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile_Y_Scanlines (aligned to 16)
312  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
313  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
314  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
315  * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
316  * . . . . . . . . . . . . . . . .              |
317  * . . . . . . . . . . . . . . . .              |
318  * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
319  * . . . . . . . . . . . . . . . .              V
320  * <---- UV Meta stride ----> (aligned to 64)
321  * <----- Width / 2 --------> (aligned to 24)
322  * M M M M M M M M M M M M . .    ^           ^
323  * M M M M M M M M M M M M . .    |           |
324  * M M M M M M M M M M M M . .    Height/2    |
325  * M M M M M M M M M M M M . .    V           M_UV_Scanlines (aligned to 16)
326  * . . . . . . . . . . . . . .                |
327  * . . . . . . . . . . . . . .                V
328  * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
329  * <--Compressed tile UV stride--> (aligned to 256)
330  * <------- Width * 4/3 ---------> (aligned to 48)
331  * U* V* U* V* U* V* U* V* . . . .  ^
332  * U* V* U* V* U* V* U* V* . . . .  |
333  * U* V* U* V* U* V* U* V* . . . .  |
334  * U* V* U* V* U* V* U* V* . . . .  UV_Scanlines (aligned to 16)
335  * . . . . . . . . . . . . . . . .  |
336  * . . . . . . . . . . . . . . . .  V
337  * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
338  *
339  * y_stride: width aligned to 256
340  * uv_stride: width aligned to 256
341  * y_scanlines: height aligned to 16
342  * uv_scanlines: height aligned to 16
343  * y_plane: buffer size aligned to 4096
344  * uv_plane: buffer size aligned to 4096
345  * y_meta_stride: width aligned to 64
346  * y_meta_scanlines: height aligned to 16
347  * y_meta_plane: buffer size aligned to 4096
348  * uv_meta_stride: width aligned to 64
349  * uv_meta_scanlines: height aligned to 16
350  * uv_meta_plane: buffer size aligned to 4096
351  *
352  * Total size = align( y_plane + uv_plane +
353  *           y_meta_plane + uv_meta_plane, 4096)
354  *
355  * Note: All the alignments are hardware requirements.
356  */
357 static u32 iris_yuv_buffer_size_qc10c(struct iris_inst *inst)
358 {
359 	u32 y_plane, uv_plane, y_stride, uv_stride;
360 	u32 uv_meta_stride, uv_meta_plane;
361 	u32 y_meta_stride, y_meta_plane;
362 	struct v4l2_format *f;
363 
364 	if (inst->domain == DECODER)
365 		f = inst->fmt_dst;
366 	else
367 		f = inst->fmt_src;
368 
369 	y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, 48),
370 			      META_STRIDE_ALIGNED);
371 	y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height, 4),
372 					     META_SCANLINE_ALIGNED);
373 	y_meta_plane = ALIGN(y_meta_plane, PIXELS_4K);
374 
375 	y_stride = ALIGN(f->fmt.pix_mp.width * 4 / 3, Y_STRIDE_ALIGN_P010);
376 	y_plane = ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN_QC10C),
377 			PIXELS_4K);
378 
379 	uv_meta_stride = ALIGN(DIV_ROUND_UP((f->fmt.pix_mp.width + 1) >> 1, 24),
380 			       META_STRIDE_ALIGNED);
381 	uv_meta_plane = uv_meta_stride *
382 			ALIGN(DIV_ROUND_UP((f->fmt.pix_mp.height + 1) >> 1, 4),
383 			      META_SCANLINE_ALIGNED);
384 	uv_meta_plane = ALIGN(uv_meta_plane, PIXELS_4K);
385 
386 	uv_stride = ALIGN(f->fmt.pix_mp.width * 4 / 3, UV_STRIDE_ALIGN_P010);
387 	uv_plane = ALIGN(uv_stride * ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN),
388 			 PIXELS_4K);
389 
390 	return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K);
391 }
392 
393 static u32 iris_dec_bitstream_buffer_size(struct iris_inst *inst)
394 {
395 	struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
396 	u32 base_res_mbs = NUM_MBS_4K;
397 	u32 frame_size, num_mbs;
398 	u32 div_factor = 2;
399 
400 	num_mbs = iris_get_mbpf(inst);
401 	if (num_mbs > NUM_MBS_4K) {
402 		div_factor = 4;
403 		base_res_mbs = caps->max_mbpf;
404 	} else {
405 		if (inst->codec == V4L2_PIX_FMT_VP9)
406 			div_factor = 1;
407 	}
408 
409 	/*
410 	 * frame_size = YUVsize / div_factor
411 	 * where YUVsize = resolution_in_MBs * MBs_in_pixel * 3 / 2
412 	 */
413 	frame_size = base_res_mbs * (16 * 16) * 3 / 2 / div_factor;
414 
415 	return ALIGN(frame_size, PIXELS_4K);
416 }
417 
418 static u32 iris_enc_bitstream_buffer_size(struct iris_inst *inst)
419 {
420 	u32 aligned_width, aligned_height, bitstream_size, yuv_size;
421 	int bitrate_mode, frame_rc;
422 	struct v4l2_format *f;
423 
424 	f = inst->fmt_dst;
425 
426 	bitrate_mode = inst->fw_caps[BITRATE_MODE].value;
427 	frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value;
428 
429 	aligned_width = ALIGN(f->fmt.pix_mp.width, 32);
430 	aligned_height = ALIGN(f->fmt.pix_mp.height, 32);
431 	bitstream_size = aligned_width * aligned_height * 3;
432 	yuv_size = (aligned_width * aligned_height * 3) >> 1;
433 	if (aligned_width * aligned_height > (4096 * 2176))
434 		/* bitstream_size = 0.25 * yuv_size; */
435 		bitstream_size = (bitstream_size >> 3);
436 	else if (aligned_width * aligned_height > (1280 * 720))
437 		/* bitstream_size = 0.5 * yuv_size; */
438 		bitstream_size = (bitstream_size >> 2);
439 
440 	if ((!frame_rc || bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) &&
441 	    bitstream_size < yuv_size)
442 		bitstream_size = (bitstream_size << 1);
443 
444 	return ALIGN(bitstream_size, 4096);
445 }
446 
447 int iris_get_buffer_size(struct iris_inst *inst,
448 			 enum iris_buffer_type buffer_type)
449 {
450 	if (inst->domain == DECODER) {
451 		switch (buffer_type) {
452 		case BUF_INPUT:
453 			return iris_dec_bitstream_buffer_size(inst);
454 		case BUF_OUTPUT:
455 			if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C)
456 				return iris_yuv_buffer_size_qc08c(inst);
457 			else if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C)
458 				return iris_yuv_buffer_size_qc10c(inst);
459 			else if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_P010)
460 				return iris_yuv_buffer_size_p010(inst);
461 			else
462 				return iris_yuv_buffer_size_nv12(inst);
463 		case BUF_DPB:
464 			if (iris_fmt_is_10bit(inst->fmt_dst->fmt.pix_mp.pixelformat))
465 				return iris_yuv_buffer_size_qc10c(inst);
466 			else
467 				return iris_yuv_buffer_size_qc08c(inst);
468 		default:
469 			return 0;
470 		}
471 	} else {
472 		switch (buffer_type) {
473 		case BUF_INPUT:
474 			if (inst->fmt_src->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C)
475 				return iris_yuv_buffer_size_qc08c(inst);
476 			else
477 				return iris_yuv_buffer_size_nv12(inst);
478 		case BUF_OUTPUT:
479 			return iris_enc_bitstream_buffer_size(inst);
480 		default:
481 			return 0;
482 		}
483 	}
484 }
485 
486 static void iris_fill_internal_buf_info(struct iris_inst *inst,
487 					enum iris_buffer_type buffer_type)
488 {
489 	struct iris_buffers *buffers = &inst->buffers[buffer_type];
490 
491 	buffers->size = inst->core->iris_firmware_desc->get_vpu_buffer_size(inst, buffer_type);
492 	buffers->min_count = iris_vpu_buf_count(inst, buffer_type);
493 }
494 
495 static void iris_get_int_buf_tbl(struct iris_inst *inst, u32 plane,
496 				 const u32 **internal_buf_type, u32 *internal_buffer_count)
497 {
498 	const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data;
499 
500 	if (inst->domain == DECODER) {
501 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
502 			*internal_buf_type = firmware_data->dec_ip_int_buf_tbl;
503 			*internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size;
504 		} else {
505 			*internal_buf_type = firmware_data->dec_op_int_buf_tbl;
506 			*internal_buffer_count = firmware_data->dec_op_int_buf_tbl_size;
507 		}
508 	} else {
509 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
510 			*internal_buf_type = firmware_data->enc_ip_int_buf_tbl;
511 			*internal_buffer_count = firmware_data->enc_ip_int_buf_tbl_size;
512 		} else {
513 			*internal_buf_type = firmware_data->enc_op_int_buf_tbl;
514 			*internal_buffer_count = firmware_data->enc_op_int_buf_tbl_size;
515 		}
516 	}
517 }
518 
519 void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
520 {
521 	const u32 *internal_buf_type;
522 	u32 internal_buffer_count, i;
523 
524 	iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &internal_buffer_count);
525 
526 	for (i = 0; i < internal_buffer_count; i++)
527 		iris_fill_internal_buf_info(inst, internal_buf_type[i]);
528 }
529 
530 static int iris_create_internal_buffer(struct iris_inst *inst,
531 				       enum iris_buffer_type buffer_type, u32 index)
532 {
533 	struct iris_buffers *buffers = &inst->buffers[buffer_type];
534 	struct iris_core *core = inst->core;
535 	struct iris_buffer *buffer;
536 
537 	if (!buffers->size)
538 		return 0;
539 
540 	buffer = kzalloc_obj(*buffer);
541 	if (!buffer)
542 		return -ENOMEM;
543 
544 	INIT_LIST_HEAD(&buffer->list);
545 	buffer->type = buffer_type;
546 	buffer->index = index;
547 	buffer->buffer_size = buffers->size;
548 	buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING;
549 
550 	buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size,
551 					 &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs);
552 	if (!buffer->kvaddr) {
553 		kfree(buffer);
554 		return -ENOMEM;
555 	}
556 
557 	list_add_tail(&buffer->list, &buffers->list);
558 
559 	return 0;
560 }
561 
562 int iris_create_internal_buffers(struct iris_inst *inst, u32 plane)
563 {
564 	u32 internal_buffer_count, i, j;
565 	struct iris_buffers *buffers;
566 	const u32 *internal_buf_type;
567 	int ret;
568 
569 	iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &internal_buffer_count);
570 
571 	for (i = 0; i < internal_buffer_count; i++) {
572 		buffers = &inst->buffers[internal_buf_type[i]];
573 		for (j = 0; j < buffers->min_count; j++) {
574 			ret = iris_create_internal_buffer(inst, internal_buf_type[i], j);
575 			if (ret)
576 				return ret;
577 		}
578 	}
579 
580 	return 0;
581 }
582 
583 int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
584 {
585 	const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
586 	int ret;
587 
588 	ret = hfi_ops->session_queue_buf(inst, buf);
589 	if (ret)
590 		return ret;
591 
592 	buf->attr &= ~BUF_ATTR_DEFERRED;
593 	buf->attr |= BUF_ATTR_QUEUED;
594 
595 	return 0;
596 }
597 
598 int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type)
599 {
600 	struct iris_buffer *buffer, *next;
601 	struct iris_buffers *buffers;
602 	int ret = 0;
603 
604 	buffers = &inst->buffers[buffer_type];
605 	list_for_each_entry_safe(buffer, next, &buffers->list, list) {
606 		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
607 			continue;
608 		if (buffer->attr & BUF_ATTR_QUEUED)
609 			continue;
610 
611 		if (buffer->attr & BUF_ATTR_DEFERRED) {
612 			ret = iris_queue_buffer(inst, buffer);
613 			if (ret)
614 				return ret;
615 		}
616 	}
617 
618 	return ret;
619 }
620 
621 int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
622 {
623 	struct iris_buffer *buffer, *next;
624 	struct iris_buffers *buffers;
625 	const u32 *internal_buf_type;
626 	u32 internal_buffer_count, i;
627 	int ret;
628 
629 	iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &internal_buffer_count);
630 
631 	for (i = 0; i < internal_buffer_count; i++) {
632 		buffers = &inst->buffers[internal_buf_type[i]];
633 		list_for_each_entry_safe(buffer, next, &buffers->list, list) {
634 			if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
635 				continue;
636 			if (buffer->attr & BUF_ATTR_QUEUED)
637 				continue;
638 			if (buffer->type == BUF_DPB && inst->state != IRIS_INST_STREAMING) {
639 				buffer->attr |= BUF_ATTR_DEFERRED;
640 				continue;
641 			}
642 			ret = iris_queue_buffer(inst, buffer);
643 			if (ret)
644 				return ret;
645 		}
646 	}
647 
648 	return 0;
649 }
650 
651 void iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
652 {
653 	struct iris_core *core = inst->core;
654 
655 	list_del(&buffer->list);
656 	dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr,
657 		       buffer->device_addr, buffer->dma_attrs);
658 	kfree(buffer);
659 }
660 
661 static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool force)
662 {
663 	struct iris_buffer *buf, *next;
664 	struct iris_buffers *buffers;
665 	const u32 *internal_buf_type;
666 	u32 i, len;
667 
668 	iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &len);
669 
670 	for (i = 0; i < len; i++) {
671 		buffers = &inst->buffers[internal_buf_type[i]];
672 		list_for_each_entry_safe(buf, next, &buffers->list, list) {
673 			/*
674 			 * during stream on, skip destroying internal(DPB) buffer
675 			 * if firmware did not return it.
676 			 * during close, destroy all buffers irrespectively.
677 			 */
678 			if (!force && buf->attr & BUF_ATTR_QUEUED)
679 				continue;
680 
681 			iris_destroy_internal_buffer(inst, buf);
682 		}
683 	}
684 
685 	if (force) {
686 		if (inst->domain == DECODER)
687 			buffers = &inst->buffers[BUF_PERSIST];
688 		else
689 			buffers = &inst->buffers[BUF_ARP];
690 
691 		list_for_each_entry_safe(buf, next, &buffers->list, list)
692 			iris_destroy_internal_buffer(inst, buf);
693 	}
694 
695 	return 0;
696 }
697 
698 int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane)
699 {
700 	return iris_destroy_internal_buffers(inst, plane, true);
701 }
702 
703 int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane)
704 {
705 	return iris_destroy_internal_buffers(inst, plane, false);
706 }
707 
708 static int iris_release_internal_buffers(struct iris_inst *inst,
709 					 enum iris_buffer_type buffer_type)
710 {
711 	const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
712 	struct iris_buffers *buffers = &inst->buffers[buffer_type];
713 	struct iris_buffer *buffer, *next;
714 	int ret;
715 
716 	list_for_each_entry_safe(buffer, next, &buffers->list, list) {
717 		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
718 			continue;
719 		if (!(buffer->attr & BUF_ATTR_QUEUED))
720 			continue;
721 		buffer->attr |= BUF_ATTR_PENDING_RELEASE;
722 		ret = hfi_ops->session_release_buf(inst, buffer);
723 		if (ret) {
724 			buffer->attr &= ~BUF_ATTR_PENDING_RELEASE;
725 			return ret;
726 		}
727 	}
728 
729 	return 0;
730 }
731 
732 static int iris_release_input_internal_buffers(struct iris_inst *inst)
733 {
734 	const u32 *internal_buf_type;
735 	u32 internal_buffer_count, i;
736 	int ret;
737 
738 	iris_get_int_buf_tbl(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
739 			     &internal_buf_type, &internal_buffer_count);
740 
741 	for (i = 0; i < internal_buffer_count; i++) {
742 		ret = iris_release_internal_buffers(inst, internal_buf_type[i]);
743 		if (ret)
744 			return ret;
745 	}
746 
747 	return 0;
748 }
749 
750 int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst, enum iris_buffer_type buffer_type)
751 {
752 	struct iris_buffers *buffers = &inst->buffers[buffer_type];
753 	struct iris_buffer *buffer, *next;
754 	int ret;
755 	u32 i;
756 
757 	if (!list_empty(&buffers->list))
758 		return 0;
759 
760 	iris_fill_internal_buf_info(inst, buffer_type);
761 
762 	for (i = 0; i < buffers->min_count; i++) {
763 		ret = iris_create_internal_buffer(inst, buffer_type, i);
764 		if (ret)
765 			return ret;
766 	}
767 
768 	list_for_each_entry_safe(buffer, next, &buffers->list, list) {
769 		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
770 			continue;
771 		if (buffer->attr & BUF_ATTR_QUEUED)
772 			continue;
773 		ret = iris_queue_buffer(inst, buffer);
774 		if (ret)
775 			return ret;
776 	}
777 
778 	return 0;
779 }
780 
781 int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst)
782 {
783 	int ret;
784 
785 	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
786 
787 	ret = iris_release_input_internal_buffers(inst);
788 	if (ret)
789 		return ret;
790 
791 	ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
792 	if (ret)
793 		return ret;
794 
795 	return iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
796 }
797 
798 int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type)
799 {
800 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
801 	struct v4l2_m2m_buffer *buffer, *n;
802 	struct iris_buffer *buf;
803 	int ret;
804 
805 	iris_scale_power(inst);
806 
807 	if (buf_type == BUF_INPUT) {
808 		v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
809 			buf = to_iris_buffer(&buffer->vb);
810 			if (!(buf->attr & BUF_ATTR_DEFERRED))
811 				continue;
812 			ret = iris_queue_buffer(inst, buf);
813 			if (ret)
814 				return ret;
815 		}
816 	} else {
817 		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
818 			buf = to_iris_buffer(&buffer->vb);
819 			if (!(buf->attr & BUF_ATTR_DEFERRED))
820 				continue;
821 			ret = iris_queue_buffer(inst, buf);
822 			if (ret)
823 				return ret;
824 		}
825 	}
826 
827 	return 0;
828 }
829 
830 void iris_vb2_queue_error(struct iris_inst *inst)
831 {
832 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
833 	struct vb2_queue *q;
834 
835 	q = v4l2_m2m_get_src_vq(m2m_ctx);
836 	vb2_queue_error(q);
837 	q = v4l2_m2m_get_dst_vq(m2m_ctx);
838 	vb2_queue_error(q);
839 }
840 
841 static struct vb2_v4l2_buffer *
842 iris_helper_find_buf(struct iris_inst *inst, u32 type, u32 idx)
843 {
844 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
845 
846 	if (V4L2_TYPE_IS_OUTPUT(type))
847 		return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx);
848 	else
849 		return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx);
850 }
851 
852 static void iris_get_ts_metadata(struct iris_inst *inst, u64 timestamp_ns,
853 				 struct vb2_v4l2_buffer *vbuf)
854 {
855 	u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
856 	u32 i;
857 
858 	for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) {
859 		if (inst->tss[i].ts_ns != timestamp_ns)
860 			continue;
861 
862 		vbuf->flags &= ~mask;
863 		vbuf->flags |= inst->tss[i].flags;
864 		vbuf->timecode = inst->tss[i].tc;
865 		return;
866 	}
867 
868 	vbuf->flags &= ~mask;
869 	vbuf->flags |= inst->tss[inst->metadata_idx].flags;
870 	vbuf->timecode = inst->tss[inst->metadata_idx].tc;
871 }
872 
873 int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf)
874 {
875 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
876 	struct vb2_v4l2_buffer *vbuf;
877 	struct vb2_buffer *vb2;
878 	u32 type, state;
879 
880 	switch (buf->type) {
881 	case BUF_INPUT:
882 		type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
883 		break;
884 	case BUF_OUTPUT:
885 		type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
886 		break;
887 	default:
888 		return 0; /* Internal DPB Buffers */
889 	}
890 
891 	vbuf = iris_helper_find_buf(inst, type, buf->index);
892 	if (!vbuf)
893 		return -EINVAL;
894 
895 	vb2 = &vbuf->vb2_buf;
896 
897 	vbuf->flags |= buf->flags;
898 
899 	if (buf->flags & V4L2_BUF_FLAG_ERROR) {
900 		state = VB2_BUF_STATE_ERROR;
901 		vb2_set_plane_payload(vb2, 0, 0);
902 		vb2->timestamp = 0;
903 		v4l2_m2m_buf_done(vbuf, state);
904 		return 0;
905 	}
906 
907 	if (V4L2_TYPE_IS_CAPTURE(type)) {
908 		vb2_set_plane_payload(vb2, 0, buf->data_size);
909 		vbuf->sequence = inst->sequence_cap++;
910 		iris_get_ts_metadata(inst, buf->timestamp, vbuf);
911 	} else {
912 		vbuf->sequence = inst->sequence_out++;
913 	}
914 
915 	if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
916 		if (!v4l2_m2m_has_stopped(m2m_ctx)) {
917 			const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
918 
919 			v4l2_event_queue_fh(&inst->fh, &ev);
920 			v4l2_m2m_mark_stopped(m2m_ctx);
921 		}
922 		inst->last_buffer_dequeued = true;
923 	}
924 
925 	state = VB2_BUF_STATE_DONE;
926 	vb2->timestamp = buf->timestamp;
927 	v4l2_m2m_buf_done(vbuf, state);
928 
929 	return 0;
930 }
931