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_common.h"
11 #include "iris_ctrls.h"
12 #include "iris_instance.h"
13 #include "iris_power.h"
14 #include "iris_vdec.h"
15 #include "iris_vpu_buffer.h"
16
17 #define DEFAULT_CODEC_ALIGNMENT 16
18
iris_vdec_inst_init(struct iris_inst * inst)19 int iris_vdec_inst_init(struct iris_inst *inst)
20 {
21 struct iris_core *core = inst->core;
22 struct v4l2_format *f;
23
24 inst->fmt_src = kzalloc_obj(*inst->fmt_src);
25 inst->fmt_dst = kzalloc_obj(*inst->fmt_dst);
26
27 inst->fw_min_count = MIN_BUFFERS;
28
29 f = inst->fmt_src;
30 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
31 f->fmt.pix_mp.width = DEFAULT_WIDTH;
32 f->fmt.pix_mp.height = DEFAULT_HEIGHT;
33 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
34 inst->codec = f->fmt.pix_mp.pixelformat;
35 f->fmt.pix_mp.num_planes = 1;
36 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
37 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
38 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
39 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
40 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
41
42 f = inst->fmt_dst;
43 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
44 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
45 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128);
46 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
47 f->fmt.pix_mp.num_planes = 1;
48 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
49 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
50 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
51 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
52 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
53 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
54 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
55 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
56 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
57
58 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0],
59 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
60
61 return iris_ctrls_init(inst);
62 }
63
iris_vdec_inst_deinit(struct iris_inst * inst)64 void iris_vdec_inst_deinit(struct iris_inst *inst)
65 {
66 kfree(inst->fmt_dst);
67 kfree(inst->fmt_src);
68 }
69
70 static const struct iris_fmt iris_vdec_formats_cap[] = {
71 [IRIS_FMT_NV12] = {
72 .pixfmt = V4L2_PIX_FMT_NV12,
73 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
74 },
75 [IRIS_FMT_QC08C] = {
76 .pixfmt = V4L2_PIX_FMT_QC08C,
77 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
78 },
79 };
80
81 static const struct iris_fmt *
find_format(struct iris_inst * inst,u32 pixfmt,u32 type)82 find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
83 {
84 const struct iris_fmt *fmt = NULL;
85 unsigned int size = 0;
86 unsigned int i;
87 switch (type) {
88 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
89 fmt = inst->core->iris_platform_data->inst_iris_fmts;
90 size = inst->core->iris_platform_data->inst_iris_fmts_size;
91 break;
92 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
93 fmt = iris_vdec_formats_cap;
94 size = ARRAY_SIZE(iris_vdec_formats_cap);
95 break;
96 default:
97 return NULL;
98 }
99
100 for (i = 0; i < size; i++) {
101 if (fmt[i].pixfmt == pixfmt)
102 break;
103 }
104
105 if (i == size || fmt[i].type != type)
106 return NULL;
107
108 return &fmt[i];
109 }
110
111 static const struct iris_fmt *
find_format_by_index(struct iris_inst * inst,u32 index,u32 type)112 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
113 {
114 const struct iris_fmt *fmt = NULL;
115 unsigned int size = 0;
116
117 switch (type) {
118 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
119 fmt = inst->core->iris_platform_data->inst_iris_fmts;
120 size = inst->core->iris_platform_data->inst_iris_fmts_size;
121 break;
122 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
123 fmt = iris_vdec_formats_cap;
124 size = ARRAY_SIZE(iris_vdec_formats_cap);
125 break;
126 default:
127 return NULL;
128 }
129
130 if (index >= size || fmt[index].type != type)
131 return NULL;
132
133 return &fmt[index];
134 }
135
iris_vdec_enum_fmt(struct iris_inst * inst,struct v4l2_fmtdesc * f)136 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
137 {
138 const struct iris_fmt *fmt;
139
140 switch (f->type) {
141 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
142 fmt = find_format_by_index(inst, f->index, f->type);
143 if (!fmt)
144 return -EINVAL;
145
146 f->pixelformat = fmt->pixfmt;
147 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
148 break;
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
150 fmt = find_format_by_index(inst, f->index, f->type);
151 if (!fmt)
152 return -EINVAL;
153 f->pixelformat = fmt->pixfmt;
154 break;
155 default:
156 return -EINVAL;
157 }
158
159 return 0;
160 }
161
iris_vdec_try_fmt(struct iris_inst * inst,struct v4l2_format * f)162 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
163 {
164 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
165 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
166 const struct iris_fmt *fmt;
167 struct v4l2_format *f_inst;
168 struct vb2_queue *src_q;
169
170 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
171 fmt = find_format(inst, pixmp->pixelformat, f->type);
172 switch (f->type) {
173 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
174 if (!fmt) {
175 f_inst = inst->fmt_src;
176 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
177 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
178 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
179 }
180 break;
181 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
182 if (!fmt) {
183 f_inst = inst->fmt_dst;
184 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
185 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
186 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
187 }
188
189 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
190 if (vb2_is_streaming(src_q)) {
191 f_inst = inst->fmt_src;
192 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
193 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
194 }
195 break;
196 default:
197 return -EINVAL;
198 }
199
200 if (pixmp->field == V4L2_FIELD_ANY)
201 pixmp->field = V4L2_FIELD_NONE;
202
203 pixmp->num_planes = 1;
204
205 return 0;
206 }
207
iris_vdec_s_fmt(struct iris_inst * inst,struct v4l2_format * f)208 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
209 {
210 struct v4l2_format *fmt, *output_fmt;
211 struct vb2_queue *q;
212 u32 codec_align;
213
214 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
215
216 if (vb2_is_busy(q))
217 return -EBUSY;
218
219 /* Width and height are optional, so fall back to a valid placeholder
220 * resolution until the real one is decoded from the bitstream.
221 */
222 if (f->fmt.pix_mp.width == 0 && f->fmt.pix_mp.height == 0) {
223 f->fmt.pix_mp.width = DEFAULT_WIDTH;
224 f->fmt.pix_mp.height = DEFAULT_HEIGHT;
225 }
226
227 iris_vdec_try_fmt(inst, f);
228
229 switch (f->type) {
230 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
231 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
232 return -EINVAL;
233
234 fmt = inst->fmt_src;
235 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
236 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
237 inst->codec = fmt->fmt.pix_mp.pixelformat;
238 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
239 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
240 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
241 fmt->fmt.pix_mp.num_planes = 1;
242 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
243 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
244 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
245 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
246
247 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
248 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
249 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
250 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
251
252 output_fmt = inst->fmt_dst;
253 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
254 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
255 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
256 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
257
258 /* Update capture format based on new ip w/h */
259 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
260 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
261 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT);
262
263 inst->crop.left = 0;
264 inst->crop.top = 0;
265 inst->crop.width = f->fmt.pix_mp.width;
266 inst->crop.height = f->fmt.pix_mp.height;
267 break;
268 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
269 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
270 return -EINVAL;
271
272 fmt = inst->fmt_dst;
273 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
274 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
275 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
276 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
277 fmt->fmt.pix_mp.num_planes = 1;
278 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128);
279 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
280 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
281 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
282
283 inst->crop.top = 0;
284 inst->crop.left = 0;
285 inst->crop.width = f->fmt.pix_mp.width;
286 inst->crop.height = f->fmt.pix_mp.height;
287 break;
288 default:
289 return -EINVAL;
290 }
291 memcpy(f, fmt, sizeof(*fmt));
292
293 return 0;
294 }
295
iris_vdec_validate_format(struct iris_inst * inst,u32 pixelformat)296 int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat)
297 {
298 const struct iris_fmt *fmt = NULL;
299
300 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
301 if (!fmt) {
302 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
303 if (!fmt)
304 return -EINVAL;
305 }
306
307 return 0;
308 }
309
iris_vdec_subscribe_event(struct iris_inst * inst,const struct v4l2_event_subscription * sub)310 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
311 {
312 int ret = 0;
313
314 switch (sub->type) {
315 case V4L2_EVENT_EOS:
316 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL);
317 break;
318 case V4L2_EVENT_SOURCE_CHANGE:
319 ret = v4l2_src_change_event_subscribe(&inst->fh, sub);
320 break;
321 case V4L2_EVENT_CTRL:
322 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub);
323 break;
324 default:
325 return -EINVAL;
326 }
327
328 return ret;
329 }
330
iris_vdec_src_change(struct iris_inst * inst)331 void iris_vdec_src_change(struct iris_inst *inst)
332 {
333 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
334 struct v4l2_event event = {0};
335 struct vb2_queue *src_q;
336
337 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
338 if (!vb2_is_streaming(src_q))
339 return;
340
341 event.type = V4L2_EVENT_SOURCE_CHANGE;
342 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
343 v4l2_event_queue_fh(&inst->fh, &event);
344 }
345
iris_vdec_streamon_input(struct iris_inst * inst)346 int iris_vdec_streamon_input(struct iris_inst *inst)
347 {
348 int ret;
349
350 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
351 if (ret)
352 return ret;
353
354 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST);
355 if (ret)
356 return ret;
357
358 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
359
360 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
361 if (ret)
362 return ret;
363
364 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
365 if (ret)
366 return ret;
367
368 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
369 if (ret)
370 return ret;
371
372 return iris_process_streamon_input(inst);
373 }
374
iris_vdec_streamon_output(struct iris_inst * inst)375 int iris_vdec_streamon_output(struct iris_inst *inst)
376 {
377 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
378 int ret;
379
380 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
381 if (ret)
382 return ret;
383
384 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
385
386 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
387 if (ret)
388 return ret;
389
390 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
391 if (ret)
392 return ret;
393
394 ret = iris_process_streamon_output(inst);
395 if (ret)
396 goto error;
397
398 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
399 if (ret)
400 goto error;
401
402 return ret;
403
404 error:
405 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
406
407 return ret;
408 }
409
iris_vdec_qbuf(struct iris_inst * inst,struct vb2_v4l2_buffer * vbuf)410 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
411 {
412 struct iris_buffer *buf = to_iris_buffer(vbuf);
413 struct vb2_buffer *vb2 = &vbuf->vb2_buf;
414 struct vb2_queue *q;
415 int ret;
416
417 ret = iris_vb2_buffer_to_driver(vb2, buf);
418 if (ret)
419 return ret;
420
421 if (buf->type == BUF_INPUT)
422 iris_set_ts_metadata(inst, vbuf);
423
424 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type);
425 if (!vb2_is_streaming(q)) {
426 buf->attr |= BUF_ATTR_DEFERRED;
427 return 0;
428 }
429
430 iris_scale_power(inst);
431
432 return iris_queue_buffer(inst, buf);
433 }
434
iris_vdec_start_cmd(struct iris_inst * inst)435 int iris_vdec_start_cmd(struct iris_inst *inst)
436 {
437 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
438 enum iris_inst_sub_state clear_sub_state = 0;
439 struct vb2_queue *dst_vq;
440 int ret;
441
442 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
443
444 if (inst->sub_state & IRIS_INST_SUB_DRC &&
445 inst->sub_state & IRIS_INST_SUB_DRC_LAST) {
446 vb2_clear_last_buffer_dequeued(dst_vq);
447 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
448
449 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
450 ret = hfi_ops->session_resume_drc(inst,
451 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
452 if (ret)
453 return ret;
454 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
455 }
456 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
457 ret = hfi_ops->session_resume_drc(inst,
458 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
459 if (ret)
460 return ret;
461 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
462 }
463 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
464 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
465 vb2_clear_last_buffer_dequeued(dst_vq);
466 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
467 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
468 if (hfi_ops->session_resume_drain) {
469 ret =
470 hfi_ops->session_resume_drain(inst,
471 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
472 if (ret)
473 return ret;
474 }
475
476 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
477 }
478 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
479 if (hfi_ops->session_resume_drain) {
480 ret =
481 hfi_ops->session_resume_drain(inst,
482 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
483 if (ret)
484 return ret;
485 }
486
487 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
488 }
489 } else {
490 dev_err(inst->core->dev, "start called before receiving last_flag\n");
491 iris_inst_change_state(inst, IRIS_INST_ERROR);
492 return -EBUSY;
493 }
494
495 return iris_inst_change_sub_state(inst, clear_sub_state, 0);
496 }
497
iris_vdec_stop_cmd(struct iris_inst * inst)498 int iris_vdec_stop_cmd(struct iris_inst *inst)
499 {
500 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
501 int ret;
502
503 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
504 if (ret)
505 return ret;
506
507 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
508 }
509