1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: PC Chen <pc.chen@mediatek.com>
5 * Tiffany Lin <tiffany.lin@mediatek.com>
6 */
7
8 #include <media/v4l2-event.h>
9 #include <media/v4l2-mem2mem.h>
10 #include <media/videobuf2-dma-contig.h>
11
12 #include "mtk_vcodec_drv.h"
13 #include "mtk_vcodec_dec.h"
14 #include "mtk_vcodec_intr.h"
15 #include "mtk_vcodec_util.h"
16 #include "vdec_drv_if.h"
17 #include "mtk_vcodec_dec_pm.h"
18
19 #define DFT_CFG_WIDTH MTK_VDEC_MIN_W
20 #define DFT_CFG_HEIGHT MTK_VDEC_MIN_H
21
22 static const struct mtk_video_fmt *
mtk_vdec_find_format(struct v4l2_format * f,const struct mtk_vcodec_dec_pdata * dec_pdata)23 mtk_vdec_find_format(struct v4l2_format *f,
24 const struct mtk_vcodec_dec_pdata *dec_pdata)
25 {
26 const struct mtk_video_fmt *fmt;
27 unsigned int k;
28
29 for (k = 0; k < *dec_pdata->num_formats; k++) {
30 fmt = &dec_pdata->vdec_formats[k];
31 if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
32 return fmt;
33 }
34
35 return NULL;
36 }
37
mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx * ctx,int format_index)38 static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
39 {
40 const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
41 const struct mtk_video_fmt *fmt;
42 struct mtk_q_data *q_data;
43 int num_frame_count = 0, i;
44 bool ret = true;
45
46 for (i = 0; i < *dec_pdata->num_formats; i++) {
47 if (dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
48 continue;
49
50 num_frame_count++;
51 }
52
53 if (num_frame_count == 1)
54 return true;
55
56 fmt = &dec_pdata->vdec_formats[format_index];
57 q_data = &ctx->q_data[MTK_Q_DATA_SRC];
58 switch (q_data->fmt->fourcc) {
59 case V4L2_PIX_FMT_VP8_FRAME:
60 if (fmt->fourcc == V4L2_PIX_FMT_MM21)
61 ret = true;
62 break;
63 case V4L2_PIX_FMT_H264_SLICE:
64 case V4L2_PIX_FMT_VP9_FRAME:
65 if (fmt->fourcc == V4L2_PIX_FMT_MM21)
66 ret = false;
67 break;
68 default:
69 ret = true;
70 break;
71 }
72
73 return ret;
74 }
75
mtk_vdec_get_q_data(struct mtk_vcodec_ctx * ctx,enum v4l2_buf_type type)76 static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
77 enum v4l2_buf_type type)
78 {
79 if (V4L2_TYPE_IS_OUTPUT(type))
80 return &ctx->q_data[MTK_Q_DATA_SRC];
81
82 return &ctx->q_data[MTK_Q_DATA_DST];
83 }
84
vidioc_try_decoder_cmd(struct file * file,void * priv,struct v4l2_decoder_cmd * cmd)85 static int vidioc_try_decoder_cmd(struct file *file, void *priv,
86 struct v4l2_decoder_cmd *cmd)
87 {
88 return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
89 }
90
91
vidioc_decoder_cmd(struct file * file,void * priv,struct v4l2_decoder_cmd * cmd)92 static int vidioc_decoder_cmd(struct file *file, void *priv,
93 struct v4l2_decoder_cmd *cmd)
94 {
95 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
96 struct vb2_queue *src_vq, *dst_vq;
97 int ret;
98
99 ret = vidioc_try_decoder_cmd(file, priv, cmd);
100 if (ret)
101 return ret;
102
103 mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd);
104 dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
105 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
106 switch (cmd->cmd) {
107 case V4L2_DEC_CMD_STOP:
108 src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
109 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
110 if (!vb2_is_streaming(src_vq)) {
111 mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
112 return 0;
113 }
114 if (!vb2_is_streaming(dst_vq)) {
115 mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
116 return 0;
117 }
118 v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
119 v4l2_m2m_try_schedule(ctx->m2m_ctx);
120 break;
121
122 case V4L2_DEC_CMD_START:
123 vb2_clear_last_buffer_dequeued(dst_vq);
124 break;
125
126 default:
127 return -EINVAL;
128 }
129
130 return 0;
131 }
132
mtk_vdec_unlock(struct mtk_vcodec_ctx * ctx)133 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
134 {
135 mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
136 }
137
mtk_vdec_lock(struct mtk_vcodec_ctx * ctx)138 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
139 {
140 mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
141 }
142
mtk_vcodec_dec_release(struct mtk_vcodec_ctx * ctx)143 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
144 {
145 vdec_if_deinit(ctx);
146 ctx->state = MTK_STATE_FREE;
147 }
148
mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx * ctx)149 void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
150 {
151 struct mtk_q_data *q_data;
152
153 ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
154 ctx->fh.m2m_ctx = ctx->m2m_ctx;
155 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
156 INIT_WORK(&ctx->decode_work, ctx->dev->vdec_pdata->worker);
157 ctx->colorspace = V4L2_COLORSPACE_REC709;
158 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
159 ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
160 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
161
162 q_data = &ctx->q_data[MTK_Q_DATA_SRC];
163 memset(q_data, 0, sizeof(struct mtk_q_data));
164 q_data->visible_width = DFT_CFG_WIDTH;
165 q_data->visible_height = DFT_CFG_HEIGHT;
166 q_data->fmt = ctx->dev->vdec_pdata->default_out_fmt;
167 q_data->field = V4L2_FIELD_NONE;
168
169 q_data->sizeimage[0] = DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
170 q_data->bytesperline[0] = 0;
171
172 q_data = &ctx->q_data[MTK_Q_DATA_DST];
173 memset(q_data, 0, sizeof(struct mtk_q_data));
174 q_data->visible_width = DFT_CFG_WIDTH;
175 q_data->visible_height = DFT_CFG_HEIGHT;
176 q_data->coded_width = DFT_CFG_WIDTH;
177 q_data->coded_height = DFT_CFG_HEIGHT;
178 q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
179 q_data->field = V4L2_FIELD_NONE;
180
181 q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
182 q_data->bytesperline[0] = q_data->coded_width;
183 q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
184 q_data->bytesperline[1] = q_data->coded_width;
185 }
186
vidioc_vdec_qbuf(struct file * file,void * priv,struct v4l2_buffer * buf)187 static int vidioc_vdec_qbuf(struct file *file, void *priv,
188 struct v4l2_buffer *buf)
189 {
190 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
191
192 if (ctx->state == MTK_STATE_ABORT) {
193 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
194 ctx->id);
195 return -EIO;
196 }
197
198 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
199 }
200
vidioc_vdec_dqbuf(struct file * file,void * priv,struct v4l2_buffer * buf)201 static int vidioc_vdec_dqbuf(struct file *file, void *priv,
202 struct v4l2_buffer *buf)
203 {
204 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
205
206 if (ctx->state == MTK_STATE_ABORT) {
207 mtk_v4l2_err("[%d] Call on DQBUF after unrecoverable error",
208 ctx->id);
209 return -EIO;
210 }
211
212 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
213 }
214
mtk_vcodec_dec_get_chip_name(void * priv)215 static int mtk_vcodec_dec_get_chip_name(void *priv)
216 {
217 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
218 struct device *dev = &ctx->dev->plat_dev->dev;
219
220 if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-dec"))
221 return 8173;
222 else if (of_device_is_compatible(dev->of_node, "mediatek,mt8183-vcodec-dec"))
223 return 8183;
224 else if (of_device_is_compatible(dev->of_node, "mediatek,mt8192-vcodec-dec"))
225 return 8192;
226 else if (of_device_is_compatible(dev->of_node, "mediatek,mt8195-vcodec-dec"))
227 return 8195;
228 else if (of_device_is_compatible(dev->of_node, "mediatek,mt8186-vcodec-dec"))
229 return 8186;
230 else if (of_device_is_compatible(dev->of_node, "mediatek,mt8188-vcodec-dec"))
231 return 8188;
232 else
233 return 8173;
234 }
235
vidioc_vdec_querycap(struct file * file,void * priv,struct v4l2_capability * cap)236 static int vidioc_vdec_querycap(struct file *file, void *priv,
237 struct v4l2_capability *cap)
238 {
239 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
240 struct device *dev = &ctx->dev->plat_dev->dev;
241 int platform_name = mtk_vcodec_dec_get_chip_name(priv);
242
243 strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
244 snprintf(cap->card, sizeof(cap->card), "MT%d video decoder", platform_name);
245
246 return 0;
247 }
248
vidioc_vdec_subscribe_evt(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)249 static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
250 const struct v4l2_event_subscription *sub)
251 {
252 struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
253
254 if (ctx->dev->vdec_pdata->uses_stateless_api)
255 return v4l2_ctrl_subscribe_event(fh, sub);
256
257 switch (sub->type) {
258 case V4L2_EVENT_EOS:
259 return v4l2_event_subscribe(fh, sub, 2, NULL);
260 case V4L2_EVENT_SOURCE_CHANGE:
261 return v4l2_src_change_event_subscribe(fh, sub);
262 default:
263 return v4l2_ctrl_subscribe_event(fh, sub);
264 }
265 }
266
vidioc_try_fmt(struct mtk_vcodec_ctx * ctx,struct v4l2_format * f,const struct mtk_video_fmt * fmt)267 static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
268 const struct mtk_video_fmt *fmt)
269 {
270 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
271 const struct v4l2_frmsize_stepwise *frmsize;
272
273 pix_fmt_mp->field = V4L2_FIELD_NONE;
274
275 /* Always apply frame size constraints from the coded side */
276 if (V4L2_TYPE_IS_OUTPUT(f->type))
277 frmsize = &fmt->frmsize;
278 else
279 frmsize = &ctx->q_data[MTK_Q_DATA_SRC].fmt->frmsize;
280
281 pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, frmsize->max_width);
282 pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, frmsize->max_height);
283
284 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
285 pix_fmt_mp->num_planes = 1;
286 pix_fmt_mp->plane_fmt[0].bytesperline = 0;
287 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
288 int tmp_w, tmp_h;
289
290 /*
291 * Find next closer width align 64, heign align 64, size align
292 * 64 rectangle
293 * Note: This only get default value, the real HW needed value
294 * only available when ctx in MTK_STATE_HEADER state
295 */
296 tmp_w = pix_fmt_mp->width;
297 tmp_h = pix_fmt_mp->height;
298 v4l_bound_align_image(&pix_fmt_mp->width, MTK_VDEC_MIN_W, frmsize->max_width, 6,
299 &pix_fmt_mp->height, MTK_VDEC_MIN_H, frmsize->max_height, 6,
300 9);
301
302 if (pix_fmt_mp->width < tmp_w &&
303 (pix_fmt_mp->width + 64) <= frmsize->max_width)
304 pix_fmt_mp->width += 64;
305 if (pix_fmt_mp->height < tmp_h &&
306 (pix_fmt_mp->height + 64) <= frmsize->max_height)
307 pix_fmt_mp->height += 64;
308
309 mtk_v4l2_debug(0,
310 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d",
311 tmp_w, tmp_h, pix_fmt_mp->width,
312 pix_fmt_mp->height,
313 pix_fmt_mp->width * pix_fmt_mp->height);
314
315 pix_fmt_mp->num_planes = fmt->num_planes;
316 pix_fmt_mp->plane_fmt[0].sizeimage =
317 pix_fmt_mp->width * pix_fmt_mp->height;
318 pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
319
320 if (pix_fmt_mp->num_planes == 2) {
321 pix_fmt_mp->plane_fmt[1].sizeimage =
322 (pix_fmt_mp->width * pix_fmt_mp->height) / 2;
323 pix_fmt_mp->plane_fmt[1].bytesperline =
324 pix_fmt_mp->width;
325 }
326 }
327
328 pix_fmt_mp->flags = 0;
329 return 0;
330 }
331
vidioc_try_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)332 static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
333 struct v4l2_format *f)
334 {
335 const struct mtk_video_fmt *fmt;
336 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
337 const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
338
339 fmt = mtk_vdec_find_format(f, dec_pdata);
340 if (!fmt) {
341 f->fmt.pix.pixelformat =
342 ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
343 fmt = mtk_vdec_find_format(f, dec_pdata);
344 }
345
346 return vidioc_try_fmt(ctx, f, fmt);
347 }
348
vidioc_try_fmt_vid_out_mplane(struct file * file,void * priv,struct v4l2_format * f)349 static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
350 struct v4l2_format *f)
351 {
352 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
353 const struct mtk_video_fmt *fmt;
354 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
355 const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
356
357 fmt = mtk_vdec_find_format(f, dec_pdata);
358 if (!fmt) {
359 f->fmt.pix.pixelformat =
360 ctx->q_data[MTK_Q_DATA_SRC].fmt->fourcc;
361 fmt = mtk_vdec_find_format(f, dec_pdata);
362 }
363
364 if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
365 mtk_v4l2_err("sizeimage of output format must be given");
366 return -EINVAL;
367 }
368
369 return vidioc_try_fmt(ctx, f, fmt);
370 }
371
vidioc_vdec_g_selection(struct file * file,void * priv,struct v4l2_selection * s)372 static int vidioc_vdec_g_selection(struct file *file, void *priv,
373 struct v4l2_selection *s)
374 {
375 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
376 struct mtk_q_data *q_data;
377
378 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
379 return -EINVAL;
380
381 q_data = &ctx->q_data[MTK_Q_DATA_DST];
382
383 switch (s->target) {
384 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
385 s->r.left = 0;
386 s->r.top = 0;
387 s->r.width = ctx->picinfo.pic_w;
388 s->r.height = ctx->picinfo.pic_h;
389 break;
390 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
391 s->r.left = 0;
392 s->r.top = 0;
393 s->r.width = ctx->picinfo.buf_w;
394 s->r.height = ctx->picinfo.buf_h;
395 break;
396 case V4L2_SEL_TGT_COMPOSE:
397 if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
398 /* set to default value if header info not ready yet*/
399 s->r.left = 0;
400 s->r.top = 0;
401 s->r.width = q_data->visible_width;
402 s->r.height = q_data->visible_height;
403 }
404 break;
405 default:
406 return -EINVAL;
407 }
408
409 if (ctx->state < MTK_STATE_HEADER) {
410 /* set to default value if header info not ready yet*/
411 s->r.left = 0;
412 s->r.top = 0;
413 s->r.width = q_data->visible_width;
414 s->r.height = q_data->visible_height;
415 return 0;
416 }
417
418 return 0;
419 }
420
vidioc_vdec_s_selection(struct file * file,void * priv,struct v4l2_selection * s)421 static int vidioc_vdec_s_selection(struct file *file, void *priv,
422 struct v4l2_selection *s)
423 {
424 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
425
426 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
427 return -EINVAL;
428
429 switch (s->target) {
430 case V4L2_SEL_TGT_COMPOSE:
431 s->r.left = 0;
432 s->r.top = 0;
433 s->r.width = ctx->picinfo.pic_w;
434 s->r.height = ctx->picinfo.pic_h;
435 break;
436 default:
437 return -EINVAL;
438 }
439
440 return 0;
441 }
442
vidioc_vdec_s_fmt(struct file * file,void * priv,struct v4l2_format * f)443 static int vidioc_vdec_s_fmt(struct file *file, void *priv,
444 struct v4l2_format *f)
445 {
446 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
447 struct v4l2_pix_format_mplane *pix_mp;
448 struct mtk_q_data *q_data;
449 int ret = 0;
450 const struct mtk_video_fmt *fmt;
451 const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
452
453 mtk_v4l2_debug(3, "[%d]", ctx->id);
454
455 q_data = mtk_vdec_get_q_data(ctx, f->type);
456 if (!q_data)
457 return -EINVAL;
458
459 pix_mp = &f->fmt.pix_mp;
460 /*
461 * Setting OUTPUT format after OUTPUT buffers are allocated is invalid
462 * if using the stateful API.
463 */
464 if (!dec_pdata->uses_stateless_api &&
465 f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
466 vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
467 mtk_v4l2_err("out_q_ctx buffers already requested");
468 ret = -EBUSY;
469 }
470
471 /*
472 * Setting CAPTURE format after CAPTURE buffers are allocated is
473 * invalid.
474 */
475 if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
476 vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
477 mtk_v4l2_err("cap_q_ctx buffers already requested");
478 ret = -EBUSY;
479 }
480
481 fmt = mtk_vdec_find_format(f, dec_pdata);
482 if (fmt == NULL) {
483 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
484 f->fmt.pix.pixelformat =
485 dec_pdata->default_out_fmt->fourcc;
486 fmt = mtk_vdec_find_format(f, dec_pdata);
487 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
488 f->fmt.pix.pixelformat =
489 dec_pdata->default_cap_fmt->fourcc;
490 fmt = mtk_vdec_find_format(f, dec_pdata);
491 }
492 }
493 if (fmt == NULL)
494 return -EINVAL;
495
496 q_data->fmt = fmt;
497 vidioc_try_fmt(ctx, f, q_data->fmt);
498 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
499 q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
500 q_data->coded_width = pix_mp->width;
501 q_data->coded_height = pix_mp->height;
502
503 ctx->colorspace = pix_mp->colorspace;
504 ctx->ycbcr_enc = pix_mp->ycbcr_enc;
505 ctx->quantization = pix_mp->quantization;
506 ctx->xfer_func = pix_mp->xfer_func;
507
508 ctx->current_codec = fmt->fourcc;
509 if (ctx->state == MTK_STATE_FREE) {
510 ret = vdec_if_init(ctx, q_data->fmt->fourcc);
511 if (ret) {
512 mtk_v4l2_err("[%d]: vdec_if_init() fail ret=%d",
513 ctx->id, ret);
514 return -EINVAL;
515 }
516 ctx->state = MTK_STATE_INIT;
517 }
518 } else {
519 ctx->capture_fourcc = fmt->fourcc;
520 }
521
522 /*
523 * If using the stateless API, S_FMT should have the effect of setting
524 * the CAPTURE queue resolution no matter which queue it was called on.
525 */
526 if (dec_pdata->uses_stateless_api) {
527 ctx->picinfo.pic_w = pix_mp->width;
528 ctx->picinfo.pic_h = pix_mp->height;
529
530 /*
531 * If get pic info fail, need to use the default pic info params, or
532 * v4l2-compliance will fail
533 */
534 ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
535 if (ret) {
536 mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
537 ctx->id);
538 }
539
540 ctx->last_decoded_picinfo = ctx->picinfo;
541
542 if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) {
543 ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
544 ctx->picinfo.fb_sz[0] +
545 ctx->picinfo.fb_sz[1];
546 ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
547 ctx->picinfo.buf_w;
548 } else {
549 ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
550 ctx->picinfo.fb_sz[0];
551 ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
552 ctx->picinfo.buf_w;
553 ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
554 ctx->picinfo.fb_sz[1];
555 ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] =
556 ctx->picinfo.buf_w;
557 }
558
559 ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w;
560 ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h;
561 mtk_v4l2_debug(2, "[%d] vdec_if_init() num_plane = %d wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
562 ctx->id, pix_mp->num_planes, ctx->picinfo.buf_w, ctx->picinfo.buf_h,
563 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
564 ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
565 ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
566 }
567 return 0;
568 }
569
vidioc_enum_framesizes(struct file * file,void * priv,struct v4l2_frmsizeenum * fsize)570 static int vidioc_enum_framesizes(struct file *file, void *priv,
571 struct v4l2_frmsizeenum *fsize)
572 {
573 int i = 0;
574 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
575 const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
576
577 if (fsize->index != 0)
578 return -EINVAL;
579
580 for (i = 0; i < *dec_pdata->num_formats; i++) {
581 if (fsize->pixel_format != dec_pdata->vdec_formats[i].fourcc)
582 continue;
583
584 /* Only coded formats have frame sizes set */
585 if (!dec_pdata->vdec_formats[i].frmsize.max_width)
586 return -ENOTTY;
587
588 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
589 fsize->stepwise = dec_pdata->vdec_formats[i].frmsize;
590
591 mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d",
592 ctx->dev->dec_capability,
593 fsize->stepwise.min_width,
594 fsize->stepwise.max_width,
595 fsize->stepwise.step_width,
596 fsize->stepwise.min_height,
597 fsize->stepwise.max_height,
598 fsize->stepwise.step_height);
599
600 return 0;
601 }
602
603 return -EINVAL;
604 }
605
vidioc_enum_fmt(struct v4l2_fmtdesc * f,void * priv,bool output_queue)606 static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
607 bool output_queue)
608 {
609 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
610 const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
611 const struct mtk_video_fmt *fmt;
612 int i, j = 0;
613
614 for (i = 0; i < *dec_pdata->num_formats; i++) {
615 if (output_queue &&
616 dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
617 continue;
618 if (!output_queue &&
619 dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
620 continue;
621
622 if (!output_queue && !mtk_vdec_get_cap_fmt(ctx, i))
623 continue;
624
625 if (j == f->index)
626 break;
627 ++j;
628 }
629
630 if (i == *dec_pdata->num_formats)
631 return -EINVAL;
632
633 fmt = &dec_pdata->vdec_formats[i];
634 f->pixelformat = fmt->fourcc;
635 f->flags = fmt->flags;
636
637 return 0;
638 }
639
vidioc_vdec_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)640 static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv,
641 struct v4l2_fmtdesc *f)
642 {
643 return vidioc_enum_fmt(f, priv, false);
644 }
645
vidioc_vdec_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)646 static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
647 struct v4l2_fmtdesc *f)
648 {
649 return vidioc_enum_fmt(f, priv, true);
650 }
651
vidioc_vdec_g_fmt(struct file * file,void * priv,struct v4l2_format * f)652 static int vidioc_vdec_g_fmt(struct file *file, void *priv,
653 struct v4l2_format *f)
654 {
655 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
656 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
657 struct vb2_queue *vq;
658 struct mtk_q_data *q_data;
659
660 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
661 if (!vq) {
662 mtk_v4l2_err("no vb2 queue for type=%d", f->type);
663 return -EINVAL;
664 }
665
666 q_data = mtk_vdec_get_q_data(ctx, f->type);
667
668 pix_mp->field = V4L2_FIELD_NONE;
669 pix_mp->colorspace = ctx->colorspace;
670 pix_mp->ycbcr_enc = ctx->ycbcr_enc;
671 pix_mp->quantization = ctx->quantization;
672 pix_mp->xfer_func = ctx->xfer_func;
673
674 if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
675 (ctx->state >= MTK_STATE_HEADER)) {
676 /* Until STREAMOFF is called on the CAPTURE queue
677 * (acknowledging the event), the driver operates as if
678 * the resolution hasn't changed yet.
679 * So we just return picinfo yet, and update picinfo in
680 * stop_streaming hook function
681 */
682 q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
683 q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
684 q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
685 q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
686 q_data->coded_width = ctx->picinfo.buf_w;
687 q_data->coded_height = ctx->picinfo.buf_h;
688 ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc;
689
690 /*
691 * Width and height are set to the dimensions
692 * of the movie, the buffer is bigger and
693 * further processing stages should crop to this
694 * rectangle.
695 */
696 pix_mp->width = q_data->coded_width;
697 pix_mp->height = q_data->coded_height;
698
699 /*
700 * Set pixelformat to the format in which mt vcodec
701 * outputs the decoded frame
702 */
703 pix_mp->num_planes = q_data->fmt->num_planes;
704 pix_mp->pixelformat = q_data->fmt->fourcc;
705 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
706 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
707 pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
708 pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
709
710 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
711 /*
712 * This is run on OUTPUT
713 * The buffer contains compressed image
714 * so width and height have no meaning.
715 * Assign value here to pass v4l2-compliance test
716 */
717 pix_mp->width = q_data->visible_width;
718 pix_mp->height = q_data->visible_height;
719 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
720 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
721 pix_mp->pixelformat = q_data->fmt->fourcc;
722 pix_mp->num_planes = q_data->fmt->num_planes;
723 } else {
724 pix_mp->width = q_data->coded_width;
725 pix_mp->height = q_data->coded_height;
726 pix_mp->num_planes = q_data->fmt->num_planes;
727 pix_mp->pixelformat = q_data->fmt->fourcc;
728 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
729 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
730 pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
731 pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
732
733 mtk_v4l2_debug(1, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
734 ctx->id, f->type, ctx->state);
735 }
736
737 return 0;
738 }
739
vb2ops_vdec_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])740 int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
741 unsigned int *nplanes, unsigned int sizes[],
742 struct device *alloc_devs[])
743 {
744 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
745 struct mtk_q_data *q_data;
746 unsigned int i;
747
748 q_data = mtk_vdec_get_q_data(ctx, vq->type);
749
750 if (q_data == NULL) {
751 mtk_v4l2_err("vq->type=%d err\n", vq->type);
752 return -EINVAL;
753 }
754
755 if (*nplanes) {
756 for (i = 0; i < *nplanes; i++) {
757 if (sizes[i] < q_data->sizeimage[i])
758 return -EINVAL;
759 }
760 } else {
761 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
762 *nplanes = q_data->fmt->num_planes;
763 else
764 *nplanes = 1;
765
766 for (i = 0; i < *nplanes; i++)
767 sizes[i] = q_data->sizeimage[i];
768 }
769
770 mtk_v4l2_debug(1,
771 "[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ",
772 ctx->id, vq->type, *nplanes, *nbuffers,
773 sizes[0], sizes[1]);
774
775 return 0;
776 }
777
vb2ops_vdec_buf_prepare(struct vb2_buffer * vb)778 int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
779 {
780 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
781 struct mtk_q_data *q_data;
782 int i;
783
784 mtk_v4l2_debug(3, "[%d] (%d) id=%d",
785 ctx->id, vb->vb2_queue->type, vb->index);
786
787 q_data = mtk_vdec_get_q_data(ctx, vb->vb2_queue->type);
788
789 for (i = 0; i < q_data->fmt->num_planes; i++) {
790 if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
791 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
792 i, vb2_plane_size(vb, i),
793 q_data->sizeimage[i]);
794 return -EINVAL;
795 }
796 if (!V4L2_TYPE_IS_OUTPUT(vb->type))
797 vb2_set_plane_payload(vb, i, q_data->sizeimage[i]);
798 }
799
800 return 0;
801 }
802
vb2ops_vdec_buf_finish(struct vb2_buffer * vb)803 void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
804 {
805 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
806 struct vb2_v4l2_buffer *vb2_v4l2;
807 struct mtk_video_dec_buf *buf;
808 bool buf_error;
809
810 vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
811 buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
812 mutex_lock(&ctx->lock);
813 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
814 buf->queued_in_v4l2 = false;
815 buf->queued_in_vb2 = false;
816 }
817 buf_error = buf->error;
818 mutex_unlock(&ctx->lock);
819
820 if (buf_error) {
821 mtk_v4l2_err("Unrecoverable error on buffer.");
822 ctx->state = MTK_STATE_ABORT;
823 }
824 }
825
vb2ops_vdec_buf_init(struct vb2_buffer * vb)826 int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
827 {
828 struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
829 struct vb2_v4l2_buffer, vb2_buf);
830 struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
831 struct mtk_video_dec_buf, m2m_buf.vb);
832
833 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
834 buf->used = false;
835 buf->queued_in_v4l2 = false;
836 }
837
838 return 0;
839 }
840
vb2ops_vdec_start_streaming(struct vb2_queue * q,unsigned int count)841 int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
842 {
843 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
844
845 if (ctx->state == MTK_STATE_FLUSH)
846 ctx->state = MTK_STATE_HEADER;
847
848 return 0;
849 }
850
vb2ops_vdec_stop_streaming(struct vb2_queue * q)851 void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
852 {
853 struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
854 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
855 int ret;
856
857 mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
858 ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
859
860 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
861 while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
862 if (src_buf != &ctx->empty_flush_buf.vb) {
863 struct media_request *req =
864 src_buf->vb2_buf.req_obj.req;
865 v4l2_m2m_buf_done(src_buf,
866 VB2_BUF_STATE_ERROR);
867 if (req)
868 v4l2_ctrl_request_complete(req, &ctx->ctrl_hdl);
869 }
870 }
871 return;
872 }
873
874 if (ctx->state >= MTK_STATE_HEADER) {
875
876 /* Until STREAMOFF is called on the CAPTURE queue
877 * (acknowledging the event), the driver operates
878 * as if the resolution hasn't changed yet, i.e.
879 * VIDIOC_G_FMT< etc. return previous resolution.
880 * So we update picinfo here
881 */
882 ctx->picinfo = ctx->last_decoded_picinfo;
883
884 mtk_v4l2_debug(2,
885 "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
886 ctx->id, ctx->last_decoded_picinfo.pic_w,
887 ctx->last_decoded_picinfo.pic_h,
888 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
889 ctx->last_decoded_picinfo.buf_w,
890 ctx->last_decoded_picinfo.buf_h);
891
892 ret = ctx->dev->vdec_pdata->flush_decoder(ctx);
893 if (ret)
894 mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
895 }
896 ctx->state = MTK_STATE_FLUSH;
897
898 while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
899 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
900 if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
901 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
902 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
903 }
904
905 }
906
m2mops_vdec_device_run(void * priv)907 static void m2mops_vdec_device_run(void *priv)
908 {
909 struct mtk_vcodec_ctx *ctx = priv;
910 struct mtk_vcodec_dev *dev = ctx->dev;
911
912 queue_work(dev->decode_workqueue, &ctx->decode_work);
913 }
914
m2mops_vdec_job_ready(void * m2m_priv)915 static int m2mops_vdec_job_ready(void *m2m_priv)
916 {
917 struct mtk_vcodec_ctx *ctx = m2m_priv;
918
919 mtk_v4l2_debug(3, "[%d]", ctx->id);
920
921 if (ctx->state == MTK_STATE_ABORT)
922 return 0;
923
924 if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) ||
925 (ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h))
926 return 0;
927
928 if (ctx->state != MTK_STATE_HEADER)
929 return 0;
930
931 return 1;
932 }
933
m2mops_vdec_job_abort(void * priv)934 static void m2mops_vdec_job_abort(void *priv)
935 {
936 struct mtk_vcodec_ctx *ctx = priv;
937
938 ctx->state = MTK_STATE_ABORT;
939 }
940
941 const struct v4l2_m2m_ops mtk_vdec_m2m_ops = {
942 .device_run = m2mops_vdec_device_run,
943 .job_ready = m2mops_vdec_job_ready,
944 .job_abort = m2mops_vdec_job_abort,
945 };
946
947 const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
948 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
949 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
950 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
951 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
952 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
953
954 .vidioc_qbuf = vidioc_vdec_qbuf,
955 .vidioc_dqbuf = vidioc_vdec_dqbuf,
956
957 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
958 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
959
960 .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt,
961 .vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt,
962 .vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt,
963 .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt,
964
965 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
966
967 .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap,
968 .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out,
969 .vidioc_enum_framesizes = vidioc_enum_framesizes,
970
971 .vidioc_querycap = vidioc_vdec_querycap,
972 .vidioc_subscribe_event = vidioc_vdec_subscribe_evt,
973 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
974 .vidioc_g_selection = vidioc_vdec_g_selection,
975 .vidioc_s_selection = vidioc_vdec_s_selection,
976
977 .vidioc_decoder_cmd = vidioc_decoder_cmd,
978 .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
979 };
980
mtk_vcodec_dec_queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)981 int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
982 struct vb2_queue *dst_vq)
983 {
984 struct mtk_vcodec_ctx *ctx = priv;
985 int ret = 0;
986
987 mtk_v4l2_debug(3, "[%d]", ctx->id);
988
989 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
990 src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
991 src_vq->drv_priv = ctx;
992 src_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
993 src_vq->ops = ctx->dev->vdec_pdata->vdec_vb2_ops;
994 src_vq->mem_ops = &vb2_dma_contig_memops;
995 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
996 src_vq->lock = &ctx->dev->dev_mutex;
997 src_vq->dev = &ctx->dev->plat_dev->dev;
998 src_vq->allow_cache_hints = 1;
999
1000 ret = vb2_queue_init(src_vq);
1001 if (ret) {
1002 mtk_v4l2_err("Failed to initialize videobuf2 queue(output)");
1003 return ret;
1004 }
1005 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1006 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1007 dst_vq->drv_priv = ctx;
1008 dst_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
1009 dst_vq->ops = ctx->dev->vdec_pdata->vdec_vb2_ops;
1010 dst_vq->mem_ops = &vb2_dma_contig_memops;
1011 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1012 dst_vq->lock = &ctx->dev->dev_mutex;
1013 dst_vq->dev = &ctx->dev->plat_dev->dev;
1014 dst_vq->allow_cache_hints = 1;
1015
1016 ret = vb2_queue_init(dst_vq);
1017 if (ret)
1018 mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)");
1019
1020 return ret;
1021 }
1022