projects/linux·blob master · refs

930 lines · 28.7 KiB

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 */
66static 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 */
123static 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 */
231static 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 */
357static 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
393static 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
418static 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
447int 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
486static 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
495static 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
519void 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
530static 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
562int 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
583int 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
598int 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
621int 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
651void 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
661static 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
698int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane)
699{
700 return iris_destroy_internal_buffers(inst, plane, true);
701}
702
703int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane)
704{
705 return iris_destroy_internal_buffers(inst, plane, false);
706}
707
708static 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
732static 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
750int 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
781int 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
798int 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
830void 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
841static struct vb2_v4l2_buffer *
842iris_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
852static 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
873int 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}