summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/aml_vcodec_dec.c (plain)
blob: a2a1b982c40bf86bc4e62018ff5bb39fc254153f
1/*
2* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12* more details.
13*
14* You should have received a copy of the GNU General Public License along
15* with this program; if not, write to the Free Software Foundation, Inc.,
16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*
18* Description:
19*/
20#include <media/v4l2-event.h>
21#include <media/v4l2-mem2mem.h>
22#include <media/videobuf2-dma-contig.h>
23
24#include "aml_vcodec_drv.h"
25#include "aml_vcodec_dec.h"
26//#include "aml_vcodec_intr.h"
27#include "aml_vcodec_util.h"
28#include "vdec_drv_if.h"
29#include "aml_vcodec_dec_pm.h"
30#include <linux/delay.h>
31#include <linux/atomic.h>
32#include <linux/crc32.h>
33#include "aml_vcodec_adapt.h"
34
35#include "aml_vcodec_vfm.h"
36
37#define OUT_FMT_IDX 0 //default h264
38#define CAP_FMT_IDX 3 //capture nv21
39
40#define AML_VDEC_MIN_W 64U
41#define AML_VDEC_MIN_H 64U
42#define DFT_CFG_WIDTH AML_VDEC_MIN_W
43#define DFT_CFG_HEIGHT AML_VDEC_MIN_H
44
45#define V4L2_CID_USER_AMLOGIC_BASE (V4L2_CID_USER_BASE + 0x1100)
46#define AML_V4L2_SET_DECMODE (V4L2_CID_USER_AMLOGIC_BASE + 0)
47
48#define WORK_ITEMS_MAX (32)
49
50//#define USEC_PER_SEC 1000000
51
52#define call_void_memop(vb, op, args...) \
53 do { \
54 if ((vb)->vb2_queue->mem_ops->op) \
55 (vb)->vb2_queue->mem_ops->op(args); \
56 } while (0)
57
58static struct aml_video_fmt aml_video_formats[] = {
59 {
60 .fourcc = V4L2_PIX_FMT_H264,
61 .type = AML_FMT_DEC,
62 .num_planes = 1,
63 },
64 {
65 .fourcc = V4L2_PIX_FMT_HEVC,
66 .type = AML_FMT_DEC,
67 .num_planes = 1,
68 },
69 {
70 .fourcc = V4L2_PIX_FMT_VP9,
71 .type = AML_FMT_DEC,
72 .num_planes = 1,
73 },
74 {
75 .fourcc = V4L2_PIX_FMT_NV12,
76 .type = AML_FMT_FRAME,
77 .num_planes = 2,
78 },
79};
80
81static const struct aml_codec_framesizes aml_vdec_framesizes[] = {
82 {
83 .fourcc = V4L2_PIX_FMT_H264,
84 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
85 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
86 },
87 {
88 .fourcc = V4L2_PIX_FMT_HEVC,
89 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
90 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
91 },
92 {
93 .fourcc = V4L2_PIX_FMT_VP9,
94 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
95 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
96 },
97};
98
99#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(aml_vdec_framesizes)
100#define NUM_FORMATS ARRAY_SIZE(aml_video_formats)
101
102static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f)
103{
104 struct aml_video_fmt *fmt;
105 unsigned int k;
106
107 for (k = 0; k < NUM_FORMATS; k++) {
108 fmt = &aml_video_formats[k];
109 if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
110 return fmt;
111 }
112
113 return NULL;
114}
115
116static struct aml_q_data *aml_vdec_get_q_data(struct aml_vcodec_ctx *ctx,
117 enum v4l2_buf_type type)
118{
119 if (V4L2_TYPE_IS_OUTPUT(type))
120 return &ctx->q_data[AML_Q_DATA_SRC];
121
122 return &ctx->q_data[AML_Q_DATA_DST];
123}
124
125static void aml_vdec_queue_res_chg_event(struct aml_vcodec_ctx *ctx)
126{
127 static const struct v4l2_event ev_src_ch = {
128 .type = V4L2_EVENT_SOURCE_CHANGE,
129 .u.src_change.changes =
130 V4L2_EVENT_SRC_CH_RESOLUTION,
131 };
132
133 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
134 v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
135}
136
137static void aml_vdec_flush_decoder(struct aml_vcodec_ctx *ctx)
138{
139 aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
140
141 aml_decoder_flush(ctx->ada_ctx);
142}
143
144static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
145{
146 unsigned int dpbsize = 0;
147 int ret;
148
149 if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
150 aml_v4l2_err("[%d] Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id);
151 return;
152 }
153
154 if (ctx->last_decoded_picinfo.visible_width == 0 ||
155 ctx->last_decoded_picinfo.visible_height == 0 ||
156 ctx->last_decoded_picinfo.coded_width == 0 ||
157 ctx->last_decoded_picinfo.coded_height == 0) {
158 aml_v4l2_err("Cannot get correct pic info");
159 return;
160 }
161
162 if ((ctx->last_decoded_picinfo.visible_width == ctx->picinfo.visible_width) ||
163 (ctx->last_decoded_picinfo.visible_height == ctx->picinfo.visible_height))
164 return;
165
166 aml_v4l2_debug(4, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
167 ctx->id, ctx->last_decoded_picinfo.visible_width,
168 ctx->last_decoded_picinfo.visible_height,
169 ctx->picinfo.visible_width, ctx->picinfo.visible_height,
170 ctx->last_decoded_picinfo.coded_width,
171 ctx->last_decoded_picinfo.coded_width);
172
173 ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
174 if (dpbsize == 0)
175 aml_v4l2_err("[%d] Incorrect dpb size, ret=%d", ctx->id, ret);
176
177 /* update picture information */
178 ctx->dpb_size = dpbsize;
179 ctx->picinfo = ctx->last_decoded_picinfo;
180}
181
182int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_fb **out_fb)
183{
184 struct vb2_buffer *dst_buf = NULL;
185 struct vdec_fb *pfb;
186 struct aml_video_dec_buf *dst_buf_info, *info;
187 struct vb2_v4l2_buffer *dst_vb2_v4l2;
188 int try_cnt = 100;
189
190 aml_v4l2_debug(4, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
191
192 do {
193 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
194 if (dst_buf)
195 break;
196 aml_v4l2_debug(3, "[%d] waitting enough dst buffers.", ctx->id);
197 msleep(30);
198 } while (try_cnt--);
199
200 if (!dst_buf)
201 return -1;
202
203 dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
204 dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb);
205
206 pfb = &dst_buf_info->frame_buffer;
207 //pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
208 pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
209 pfb->base_y.va = phys_to_virt(dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->base_y.dma_addr));
210 pfb->base_y.size = ctx->picinfo.y_len_sz;
211
212 //pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
213 pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
214 pfb->base_c.va = phys_to_virt(dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->base_c.dma_addr));
215 pfb->base_c.size = ctx->picinfo.c_len_sz;
216 pfb->status = FB_ST_NORMAL;
217
218 aml_v4l2_debug(4, "[%d] id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad y_size=%zx, c_size: %zx",
219 ctx->id, dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr,
220 &pfb->base_c.dma_addr, pfb->base_y.size, pfb->base_c.size);
221
222 dst_buf_info->used = true;
223
224 v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
225
226 *out_fb = pfb;
227
228 info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
229
230 return 0;
231}
232EXPORT_SYMBOL(get_fb_from_queue);
233
234int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_fb *in_fb)
235{
236 struct aml_video_dec_buf *dstbuf;
237
238 pr_info("[%d] %s() [%d]\n", ctx->id, __func__, __LINE__);
239
240 if (in_fb == NULL) {
241 aml_v4l2_debug(4, "[%d] No free frame buffer", ctx->id);
242 return -1;
243 }
244
245 aml_v4l2_debug(4, "[%d] tmp_frame_addr = 0x%p", ctx->id, in_fb);
246
247 dstbuf = container_of(in_fb, struct aml_video_dec_buf, frame_buffer);
248
249 mutex_lock(&ctx->lock);
250
251 if (!dstbuf->used)
252 goto out;
253
254 aml_v4l2_debug(4,
255 "[%d] status=%x queue id=%d to rdy_queue",
256 ctx->id, in_fb->status,
257 dstbuf->vb.vb2_buf.index);
258
259 v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
260
261 dstbuf->used = false;
262out:
263 mutex_unlock(&ctx->lock);
264
265 return 0;
266
267}
268EXPORT_SYMBOL(put_fb_to_queue);
269
270void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_fb *fb)
271{
272 struct aml_video_dec_buf *dstbuf = NULL;
273 struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
274
275 aml_v4l2_debug(2, "[%d] FROM (%s %s) vf: %p, ts: %llx, idx: %d",
276 ctx->id, vf_get_provider(ctx->ada_ctx->recv_name)->name,
277 ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO",
278 vf, vf->timestamp, vf->index);
279
280 dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
281 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->base_y.bytes_used);
282 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->base_c.bytes_used);
283 dstbuf->vb.vb2_buf.timestamp = vf->timestamp;
284 dstbuf->ready_to_display = true;
285
286 if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
287 dstbuf->lastframe = true;
288 dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
289 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
290 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0);
291 ctx->has_receive_eos = true;
292 pr_info("[%d] recevie a empty frame.\n", ctx->id);
293 }
294
295 v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
296
297 mutex_lock(&ctx->state_lock);
298 if (ctx->state == AML_STATE_FLUSHING &&
299 ctx->has_receive_eos) {
300 ctx->state = AML_STATE_FLUSHED;
301 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHED)",
302 ctx->id, __func__);
303 }
304 mutex_unlock(&ctx->state_lock);
305
306 if (dstbuf->lastframe &&
307 ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
308 /*
309 * After all buffers containing decoded frames from
310 * before the resolution change point ready to be
311 * dequeued on the CAPTURE queue, the driver sends a
312 * V4L2_EVENT_SOURCE_CHANGE event for source change
313 * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper
314 * layer will get new information from cts->picinfo.
315 */
316 aml_vdec_queue_res_chg_event(ctx);
317 }
318
319 ctx->decoded_frame_cnt++;
320}
321
322static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_fb **out)
323{
324 int ret = -1;
325
326 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
327
328 ret = vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, out);
329 if (ret) {
330 aml_v4l2_err("[%d] Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", ctx->id);
331 return -1;
332 }
333
334 if (!*out) {
335 aml_v4l2_debug(4, "[%d] No display frame buffer", ctx->id);
336 return -1;
337 }
338
339 return ret;
340}
341
342static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
343{
344 struct aml_vcodec_dev *dev = ctx->dev;
345
346 if (!is_input_ready(ctx->ada_ctx)) {
347 pr_err("[%d] %s() the decoder intput has not ready.\n",
348 ctx->id, __func__);
349 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
350 return 0;
351 }
352
353 if (ctx->state == AML_STATE_PROBE) {
354 int buf_ready_num;
355
356 /* is there enough dst bufs for decoding? */
357 buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
358 if (buf_ready_num < ctx->dpb_size) {
359 aml_v4l2_debug(4, "[%d] Not enough dst bufs, num: %d.\n",
360 ctx->id, buf_ready_num);
361 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
362 v4l2_m2m_try_schedule(ctx->m2m_ctx);
363 msleep(60);
364 return 0;
365 }
366
367 mutex_lock(&ctx->state_lock);
368 if (ctx->state == AML_STATE_PROBE) {
369 ctx->state = AML_STATE_READY;
370 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_READY)",
371 ctx->id, __func__);
372 }
373 mutex_unlock(&ctx->state_lock);
374 }
375
376 mutex_lock(&ctx->state_lock);
377 if (ctx->state == AML_STATE_READY) {
378 ctx->state = AML_STATE_ACTIVE;
379 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ACTIVE)",
380 ctx->id, __func__);
381 }
382 mutex_unlock(&ctx->state_lock);
383
384 return 1;
385}
386
387static bool is_enough_work_items(struct aml_vcodec_ctx *ctx)
388{
389 struct aml_vcodec_dev *dev = ctx->dev;
390
391 if (vdec_frame_number(ctx->ada_ctx) >= WORK_ITEMS_MAX) {
392 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
393 return false;
394 }
395
396 return true;
397}
398
399static void aml_vdec_worker(struct work_struct *work)
400{
401 struct aml_vcodec_ctx *ctx =
402 container_of(work, struct aml_vcodec_ctx, decode_work);
403 struct aml_vcodec_dev *dev = ctx->dev;
404 struct vb2_buffer *src_buf;
405 struct aml_vcodec_mem buf;
406 bool res_chg = false;
407 int ret;
408 struct aml_video_dec_buf *src_buf_info;
409 struct vb2_v4l2_buffer *src_vb2_v4l2;
410
411 aml_v4l2_debug(4, "[%d] entry [%d] [%s]", ctx->id, __LINE__, __func__);
412
413 aml_vdec_lock(ctx);
414
415 if (ctx->state < AML_STATE_INIT ||
416 ctx->state > AML_STATE_FLUSHED) {
417 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
418 goto out;
419 }
420
421 if (!is_vdec_ready(ctx)) {
422 pr_err("[%d] %s() the decoder has not ready.\n",
423 ctx->id, __func__);
424 goto out;
425 }
426
427 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
428 if (src_buf == NULL) {
429 pr_err("[%d] src_buf empty!\n", ctx->id);
430 goto out;
431 }
432
433 /*this case for google, but some frames are droped on ffmpeg, so disabled temp.*/
434 if (0 && !is_enough_work_items(ctx))
435 goto out;
436
437 src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf);
438 src_buf_info = container_of(src_vb2_v4l2, struct aml_video_dec_buf, vb);
439
440 if (src_buf_info->lastframe) {
441 /*the empty data use to flushed the decoder.*/
442 aml_v4l2_debug(3, "[%d] Got empty flush input buffer.", ctx->id);
443
444 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
445 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
446
447 /* sets eos data for vdec input. */
448 aml_vdec_flush_decoder(ctx);
449
450 mutex_lock(&ctx->state_lock);
451 if (ctx->state == AML_STATE_ACTIVE) {
452 ctx->state = AML_STATE_FLUSHING;// prepare flushing
453 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING)",
454 ctx->id, __func__);
455 }
456 mutex_unlock(&ctx->state_lock);
457
458 goto out;
459 }
460
461 buf.va = vb2_plane_vaddr(src_buf, 0);
462 buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
463 //buf.va = phys_to_virt(dma_to_phys(v4l_get_dev_from_codec_mm(), buf.dma_addr));
464
465 buf.size = (size_t)src_buf->planes[0].bytesused;
466 if (!buf.va) {
467 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
468 aml_v4l2_err("[%d] id=%d src_addr is NULL!!",
469 ctx->id, src_buf->index);
470 goto out;
471 }
472 aml_v4l2_debug(4, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
473 ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
474
475 src_buf_info->used = true;
476
477 /* pr_err("%s() [%d], size: 0x%zx, crc: 0x%x\n",
478 __func__, __LINE__, buf.size, crc32(0, buf.va, buf.size));*/
479
480 /* pts = (time / 10e6) * (90k / fps) */
481 aml_v4l2_debug(4, "[%d] %s() timestamp: 0x%llx", ctx->id , __func__,
482 src_buf->timestamp);
483
484 ret = vdec_if_decode(ctx, &buf, src_buf->timestamp, &res_chg);
485 if (ret > 0) {
486 /*
487 * we only return src buffer with VB2_BUF_STATE_DONE
488 * when decode success without resolution change.
489 */
490 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
491 v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
492 } else if (ret && ret != -EAGAIN) {
493 src_buf_info->error = (ret == -EIO ? true : false);
494 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
495 v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
496 aml_v4l2_err("[%d] %s() error processing src data. %d.",
497 ctx->id, __func__, ret);
498 } else if (res_chg) {
499 src_buf_info->used = false;
500 aml_vdec_pic_info_update(ctx);
501 /*
502 * On encountering a resolution change in the stream.
503 * The driver must first process and decode all
504 * remaining buffers from before the resolution change
505 * point, so call flush decode here
506 */
507 aml_vdec_flush_decoder(ctx);
508 mutex_lock(&ctx->state_lock);
509 if (ctx->state == AML_STATE_ACTIVE) {
510 ctx->state = AML_STATE_FLUSHING;// prepare flushing
511 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING)",
512 ctx->id, __func__);
513 }
514 mutex_unlock(&ctx->state_lock);
515
516 ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true;
517 v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
518
519 goto out;
520 }
521
522 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
523out:
524 aml_vdec_unlock(ctx);
525}
526
527static void aml_reset_worker(struct work_struct *work)
528{
529 struct aml_vcodec_ctx *ctx =
530 container_of(work, struct aml_vcodec_ctx, reset_work);
531 //struct aml_video_dec_buf *buf = NULL;
532 int try_cnt = 10;
533
534 aml_vdec_lock(ctx);
535
536 if (ctx->state == AML_STATE_ABORT) {
537 pr_err("[%d] %s() the decoder will be exited.\n",
538 ctx->id, __func__);
539 goto out;
540 }
541
542 while (!v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx)) {
543 pr_err("[%d] %s() src data is not ready.\n",
544 ctx->id, __func__);
545
546 if (try_cnt--) {
547 msleep(30);
548 continue;
549 }
550
551 ctx->state = AML_STATE_ABORT;
552 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
553 ctx->id, __func__);
554 goto out;
555 }
556
557#if 0
558 /*
559 *fast enque capture buffers, but need to realloc
560 *bufs if the resolution change event was hanped.
561 */
562 if (!ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
563 list_for_each_entry(buf, &ctx->capture_list, node) {
564 buf->que_in_m2m = true;
565 buf->queued_in_vb2 = true;
566 buf->queued_in_v4l2 = true;
567 buf->ready_to_display = false;
568 buf->frame_buffer.status = FB_ST_NORMAL;
569 v4l2_m2m_buf_queue(ctx->m2m_ctx, &buf->vb);
570 pr_err("que buf idx: %d\n", buf->vb.vb2_buf.index);
571 }
572 }
573#endif
574 if (aml_codec_reset(ctx->ada_ctx)) {
575 ctx->state = AML_STATE_ABORT;
576 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
577 ctx->id, __func__);
578 goto out;
579 }
580
581 mutex_lock(&ctx->state_lock);
582 if (ctx->state == AML_STATE_RESET) {
583 ctx->state = AML_STATE_READY;
584 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_READY)",
585 ctx->id, __func__);
586
587 /* vdec has ready to decode subsequence data of new resolution. */
588 ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false;
589 v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
590 }
591 mutex_unlock(&ctx->state_lock);
592out:
593 aml_vdec_unlock(ctx);
594}
595
596void try_to_capture(struct aml_vcodec_ctx *ctx)
597{
598 int ret = 0;
599 struct vdec_fb *fb = NULL;
600
601 ret = get_display_buffer(ctx, &fb);
602 if (ret) {
603 aml_v4l2_debug(4, "[%d] %s() [%d], the que have no disp buf,ret: %d",
604 ctx->id, __func__, __LINE__, ret);
605 return;
606 }
607
608 trans_vframe_to_user(ctx, fb);
609}
610EXPORT_SYMBOL_GPL(try_to_capture);
611
612static int vdec_thread(void *data)
613{
614 struct aml_vdec_thread *thread =
615 (struct aml_vdec_thread *) data;
616 struct aml_vcodec_ctx *ctx =
617 (struct aml_vcodec_ctx *) thread->priv;
618
619 for (;;) {
620 aml_v4l2_debug(3, "[%d] %s() state: %d", ctx->id,
621 __func__, ctx->state);
622
623 if (down_interruptible(&thread->sem))
624 break;
625
626 if (thread->stop)
627 break;
628
629 /* handle event. */
630 thread->func(ctx);
631 }
632
633 while (!kthread_should_stop()) {
634 set_current_state(TASK_INTERRUPTIBLE);
635 schedule();
636 }
637
638 return 0;
639}
640
641void aml_thread_notify(struct aml_vcodec_ctx *ctx,
642 enum aml_thread_type type)
643{
644 struct aml_vdec_thread *thread = NULL;
645
646 list_for_each_entry(thread, &ctx->vdec_thread_list, node) {
647 if (thread->task == NULL)
648 continue;
649
650 if (thread->type == type)
651 up(&thread->sem);
652 }
653}
654EXPORT_SYMBOL_GPL(aml_thread_notify);
655
656int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
657 enum aml_thread_type type, const char *thread_name)
658{
659 struct aml_vdec_thread *thread;
660 int ret = 0;
661
662 thread = kzalloc(sizeof(*thread), GFP_KERNEL);
663 if (thread == NULL)
664 return -ENOMEM;
665
666 thread->type = type;
667 thread->func = func;
668 thread->priv = ctx;
669 sema_init(&thread->sem, 0);
670
671 thread->task = kthread_run(vdec_thread, thread, "aml-%s", thread_name);
672 if (IS_ERR(thread->task)) {
673 ret = PTR_ERR(thread->task);
674 thread->task = NULL;
675 goto err;
676 }
677
678 list_add(&thread->node, &ctx->vdec_thread_list);
679
680 return 0;
681
682err:
683 kfree(thread);
684
685 return ret;
686}
687EXPORT_SYMBOL_GPL(aml_thread_start);
688
689void aml_thread_stop(struct aml_vcodec_ctx *ctx)
690{
691 struct aml_vdec_thread *thread = NULL;
692
693 while (!list_empty(&ctx->vdec_thread_list)) {
694 thread = list_entry(ctx->vdec_thread_list.next,
695 struct aml_vdec_thread, node);
696 list_del(&thread->node);
697 thread->stop = true;
698 up(&thread->sem);
699 kthread_stop(thread->task);
700 thread->task = NULL;
701 kfree(thread);
702 }
703}
704EXPORT_SYMBOL_GPL(aml_thread_stop);
705
706static int vidioc_try_decoder_cmd(struct file *file, void *priv,
707 struct v4l2_decoder_cmd *cmd)
708{
709 switch (cmd->cmd) {
710 case V4L2_DEC_CMD_STOP:
711 case V4L2_DEC_CMD_START:
712 if (cmd->flags != 0) {
713 aml_v4l2_err("cmd->flags=%u", cmd->flags);
714 return -EINVAL;
715 }
716 break;
717 default:
718 return -EINVAL;
719 }
720 return 0;
721}
722
723static int vidioc_decoder_cmd(struct file *file, void *priv,
724 struct v4l2_decoder_cmd *cmd)
725{
726 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
727 struct vb2_queue *src_vq, *dst_vq;
728 int ret;
729
730 ret = vidioc_try_decoder_cmd(file, priv, cmd);
731 if (ret)
732 return ret;
733
734 aml_v4l2_debug(3, "[%d] %s() [%d], cmd: %u",
735 ctx->id, __func__, __LINE__, cmd->cmd);
736 dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
737 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
738 switch (cmd->cmd) {
739 case V4L2_DEC_CMD_STOP:
740
741 if (ctx->state != AML_STATE_ACTIVE)
742 return 0;
743
744 src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
745 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
746 if (!vb2_is_streaming(src_vq)) {
747 pr_err("[%d] Output stream is off. No need to flush.\n", ctx->id);
748 return 0;
749 }
750
751 if (!vb2_is_streaming(dst_vq)) {
752 pr_err("[%d] Capture stream is off. No need to flush.\n", ctx->id);
753 return 0;
754 }
755
756 /* flush src */
757 v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
758 v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
759
760 break;
761
762 case V4L2_DEC_CMD_START:
763 aml_v4l2_debug(4, "[%d] CMD V4L2_DEC_CMD_START ", ctx->id);
764 vb2_clear_last_buffer_dequeued(dst_vq);//pay attention
765 break;
766
767 default:
768 return -EINVAL;
769 }
770
771 return 0;
772}
773
774static int vidioc_decoder_streamon(struct file *file, void *priv,
775 enum v4l2_buf_type i)
776{
777 struct v4l2_fh *fh = file->private_data;
778 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
779 struct aml_vcodec_dev *dev = ctx->dev;
780 struct vb2_queue *q;
781 int ret = 0;
782
783 ret = v4l2_m2m_ioctl_streamon(file, priv, i);
784
785 q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
786
787 mutex_lock(&ctx->state_lock);
788
789 if (ctx->state == AML_STATE_FLUSHED) {
790 if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
791 ctx->state = AML_STATE_RESET;
792 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_RESET)",
793 ctx->id, __func__);
794 queue_work(dev->reset_workqueue, &ctx->reset_work);
795 }
796 }
797 mutex_unlock(&ctx->state_lock);
798
799 return ret;
800}
801
802static int vidioc_decoder_reqbufs(struct file *file, void *priv,
803 struct v4l2_requestbuffers *rb)
804{
805 struct v4l2_fh *fh = file->private_data;
806 struct vb2_queue *q;
807
808 q = v4l2_m2m_get_vq(fh->m2m_ctx, rb->type);
809
810 if (!rb->count)
811 vb2_queue_release(q);
812
813 return v4l2_m2m_ioctl_reqbufs(file, priv, rb);
814}
815
816void aml_vdec_unlock(struct aml_vcodec_ctx *ctx)
817{
818 mutex_unlock(&ctx->dev->dec_mutex);
819}
820
821void aml_vdec_lock(struct aml_vcodec_ctx *ctx)
822{
823 mutex_lock(&ctx->dev->dec_mutex);
824}
825
826void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx)
827{
828 aml_vdec_lock(ctx);
829
830 ctx->state = AML_STATE_ABORT;
831 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
832 ctx->id, __func__);
833
834 vdec_if_deinit(ctx);
835
836 aml_vdec_unlock(ctx);
837}
838
839void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx)
840{
841 struct aml_q_data *q_data;
842
843 ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
844 ctx->fh.m2m_ctx = ctx->m2m_ctx;
845 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
846 INIT_WORK(&ctx->decode_work, aml_vdec_worker);
847 INIT_WORK(&ctx->reset_work, aml_reset_worker);
848 ctx->colorspace = V4L2_COLORSPACE_REC709;
849 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
850 ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
851 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
852 ctx->dev->dec_capability = VCODEC_CAPABILITY_4K_DISABLED;//disable 4k
853
854 q_data = &ctx->q_data[AML_Q_DATA_SRC];
855 memset(q_data, 0, sizeof(struct aml_q_data));
856 q_data->visible_width = DFT_CFG_WIDTH;
857 q_data->visible_height = DFT_CFG_HEIGHT;
858 q_data->fmt = &aml_video_formats[OUT_FMT_IDX];
859 q_data->field = V4L2_FIELD_NONE;
860
861 q_data->sizeimage[0] = (1024 * 1024);//DFT_CFG_WIDTH * DFT_CFG_HEIGHT; //1m
862 q_data->bytesperline[0] = 0;
863
864 q_data = &ctx->q_data[AML_Q_DATA_DST];
865 memset(q_data, 0, sizeof(struct aml_q_data));
866 q_data->visible_width = DFT_CFG_WIDTH;
867 q_data->visible_height = DFT_CFG_HEIGHT;
868 q_data->coded_width = DFT_CFG_WIDTH;
869 q_data->coded_height = DFT_CFG_HEIGHT;
870 q_data->fmt = &aml_video_formats[CAP_FMT_IDX];
871 q_data->field = V4L2_FIELD_NONE;
872
873 v4l_bound_align_image(&q_data->coded_width,
874 AML_VDEC_MIN_W,
875 AML_VDEC_MAX_W, 4,
876 &q_data->coded_height,
877 AML_VDEC_MIN_H,
878 AML_VDEC_MAX_H, 5, 6);
879
880 q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
881 q_data->bytesperline[0] = q_data->coded_width;
882 q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
883 q_data->bytesperline[1] = q_data->coded_width;
884
885 ctx->state = AML_STATE_IDLE;
886 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_IDLE)",
887 ctx->id, __func__);
888}
889
890static int vidioc_vdec_qbuf(struct file *file, void *priv,
891 struct v4l2_buffer *buf)
892{
893 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
894
895 if (ctx->state == AML_STATE_ABORT) {
896 aml_v4l2_err("[%d] Call on QBUF after unrecoverable error, type = %s",
897 ctx->id, V4L2_TYPE_IS_OUTPUT(buf->type) ?
898 "OUT" : "IN");
899 return -EIO;
900 }
901
902 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
903}
904
905static int vidioc_vdec_dqbuf(struct file *file, void *priv,
906 struct v4l2_buffer *buf)
907{
908 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
909
910 if (ctx->state == AML_STATE_ABORT) {
911 aml_v4l2_err("[%d] Call on DQBUF after unrecoverable error, type = %s",
912 ctx->id, V4L2_TYPE_IS_OUTPUT(buf->type) ?
913 "OUT" : "IN");
914 if (!V4L2_TYPE_IS_OUTPUT(buf->type))
915 return -EIO;
916 }
917
918 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
919}
920
921static int vidioc_vdec_querycap(struct file *file, void *priv,
922 struct v4l2_capability *cap)
923{
924 strlcpy(cap->driver, AML_VCODEC_DEC_NAME, sizeof(cap->driver));
925 strlcpy(cap->bus_info, AML_PLATFORM_STR, sizeof(cap->bus_info));
926 strlcpy(cap->card, AML_PLATFORM_STR, sizeof(cap->card));
927
928 return 0;
929}
930
931static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
932 const struct v4l2_event_subscription *sub)
933{
934 switch (sub->type) {
935 case V4L2_EVENT_EOS:
936 return v4l2_event_subscribe(fh, sub, 2, NULL);
937 case V4L2_EVENT_SOURCE_CHANGE:
938 return v4l2_src_change_event_subscribe(fh, sub);
939 default:
940 return v4l2_ctrl_subscribe_event(fh, sub);
941 }
942}
943
944static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
945{
946 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
947 int i;
948
949 pix_fmt_mp->field = V4L2_FIELD_NONE;
950
951 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
952 pix_fmt_mp->num_planes = 1;
953 pix_fmt_mp->plane_fmt[0].bytesperline = 0;
954 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
955 int tmp_w, tmp_h;
956
957 pix_fmt_mp->height = clamp(pix_fmt_mp->height,
958 AML_VDEC_MIN_H,
959 AML_VDEC_MAX_H);
960 pix_fmt_mp->width = clamp(pix_fmt_mp->width,
961 AML_VDEC_MIN_W,
962 AML_VDEC_MAX_W);
963
964 /*
965 * Find next closer width align 64, heign align 64, size align
966 * 64 rectangle
967 * Note: This only get default value, the real HW needed value
968 * only available when ctx in AML_STATE_PROBE state
969 */
970 tmp_w = pix_fmt_mp->width;
971 tmp_h = pix_fmt_mp->height;
972 v4l_bound_align_image(&pix_fmt_mp->width,
973 AML_VDEC_MIN_W,
974 AML_VDEC_MAX_W, 6,
975 &pix_fmt_mp->height,
976 AML_VDEC_MIN_H,
977 AML_VDEC_MAX_H, 6, 9);
978
979 if (pix_fmt_mp->width < tmp_w &&
980 (pix_fmt_mp->width + 64) <= AML_VDEC_MAX_W)
981 pix_fmt_mp->width += 64;
982 if (pix_fmt_mp->height < tmp_h &&
983 (pix_fmt_mp->height + 64) <= AML_VDEC_MAX_H)
984 pix_fmt_mp->height += 64;
985
986 aml_v4l2_debug(4,
987 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d",
988 tmp_w, tmp_h, pix_fmt_mp->width,
989 pix_fmt_mp->height,
990 pix_fmt_mp->width * pix_fmt_mp->height);
991
992 pix_fmt_mp->num_planes = fmt->num_planes;
993 pix_fmt_mp->plane_fmt[0].sizeimage =
994 pix_fmt_mp->width * pix_fmt_mp->height;
995 pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
996
997 if (pix_fmt_mp->num_planes == 2) {
998 pix_fmt_mp->plane_fmt[1].sizeimage =
999 (pix_fmt_mp->width * pix_fmt_mp->height) / 2;
1000 pix_fmt_mp->plane_fmt[1].bytesperline =
1001 pix_fmt_mp->width;
1002 }
1003 }
1004
1005 for (i = 0; i < pix_fmt_mp->num_planes; i++)
1006 memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0,
1007 sizeof(pix_fmt_mp->plane_fmt[0].reserved));
1008
1009 pix_fmt_mp->flags = 0;
1010 memset(&pix_fmt_mp->reserved, 0x0, sizeof(pix_fmt_mp->reserved));
1011 return 0;
1012}
1013
1014static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
1015 struct v4l2_format *f)
1016{
1017 struct aml_video_fmt *fmt = NULL;
1018
1019 fmt = aml_vdec_find_format(f);
1020 if (!fmt)
1021 return -EINVAL;
1022
1023 return vidioc_try_fmt(f, fmt);
1024}
1025
1026static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
1027 struct v4l2_format *f)
1028{
1029 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
1030 struct aml_video_fmt *fmt = NULL;
1031
1032 fmt = aml_vdec_find_format(f);
1033 if (!fmt)
1034 return -EINVAL;
1035
1036 if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
1037 aml_v4l2_err("sizeimage of output format must be given");
1038 return -EINVAL;
1039 }
1040
1041 return vidioc_try_fmt(f, fmt);
1042}
1043
1044static int vidioc_vdec_g_selection(struct file *file, void *priv,
1045 struct v4l2_selection *s)
1046{
1047 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1048 struct aml_q_data *q_data;
1049
1050 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1051 return -EINVAL;
1052
1053 q_data = &ctx->q_data[AML_Q_DATA_DST];
1054
1055 switch (s->target) {
1056 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1057 s->r.left = 0;
1058 s->r.top = 0;
1059 s->r.width = ctx->picinfo.visible_width;
1060 s->r.height = ctx->picinfo.visible_height;
1061 break;
1062 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1063 s->r.left = 0;
1064 s->r.top = 0;
1065 s->r.width = ctx->picinfo.coded_width;
1066 s->r.height = ctx->picinfo.coded_height;
1067 break;
1068 case V4L2_SEL_TGT_COMPOSE:
1069 if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
1070 /* set to default value if header info not ready yet*/
1071 s->r.left = 0;
1072 s->r.top = 0;
1073 s->r.width = q_data->visible_width;
1074 s->r.height = q_data->visible_height;
1075 }
1076 break;
1077 default:
1078 return -EINVAL;
1079 }
1080
1081 if (ctx->state < AML_STATE_PROBE) {
1082 /* set to default value if header info not ready yet*/
1083 s->r.left = 0;
1084 s->r.top = 0;
1085 s->r.width = q_data->visible_width;
1086 s->r.height = q_data->visible_height;
1087 return 0;
1088 }
1089
1090 return 0;
1091}
1092
1093static int vidioc_vdec_s_selection(struct file *file, void *priv,
1094 struct v4l2_selection *s)
1095{
1096 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1097
1098 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1099 return -EINVAL;
1100
1101 switch (s->target) {
1102 case V4L2_SEL_TGT_COMPOSE:
1103 s->r.left = 0;
1104 s->r.top = 0;
1105 s->r.width = ctx->picinfo.visible_width;
1106 s->r.height = ctx->picinfo.visible_height;
1107 break;
1108 default:
1109 return -EINVAL;
1110 }
1111
1112 return 0;
1113}
1114
1115static int vidioc_vdec_s_fmt(struct file *file, void *priv,
1116 struct v4l2_format *f)
1117{
1118 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1119 struct v4l2_pix_format_mplane *pix_mp;
1120 struct aml_q_data *q_data;
1121 int ret = 0;
1122 struct aml_video_fmt *fmt;
1123
1124 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
1125
1126 q_data = aml_vdec_get_q_data(ctx, f->type);
1127 if (!q_data)
1128 return -EINVAL;
1129
1130 pix_mp = &f->fmt.pix_mp;
1131 if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
1132 vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
1133 aml_v4l2_err("[%d] out_q_ctx buffers already requested", ctx->id);
1134 }
1135
1136 if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
1137 vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
1138 aml_v4l2_err("[%d] cap_q_ctx buffers already requested", ctx->id);
1139 }
1140
1141 fmt = aml_vdec_find_format(f);
1142 if (fmt == NULL) {
1143 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1144 f->fmt.pix.pixelformat =
1145 aml_video_formats[OUT_FMT_IDX].fourcc;
1146 fmt = aml_vdec_find_format(f);
1147 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1148 f->fmt.pix.pixelformat =
1149 aml_video_formats[CAP_FMT_IDX].fourcc;
1150 fmt = aml_vdec_find_format(f);
1151 }
1152 }
1153
1154 q_data->fmt = fmt;
1155 vidioc_try_fmt(f, q_data->fmt);
1156 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1157 q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
1158 q_data->coded_width = pix_mp->width;
1159 q_data->coded_height = pix_mp->height;
1160
1161 aml_v4l2_debug(4, "[%d] %s() [%d], w: %d, h: %d, size: %d",
1162 ctx->id, __func__, __LINE__, pix_mp->width, pix_mp->height,
1163 pix_mp->plane_fmt[0].sizeimage);
1164
1165 ctx->colorspace = f->fmt.pix_mp.colorspace;
1166 ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
1167 ctx->quantization = f->fmt.pix_mp.quantization;
1168 ctx->xfer_func = f->fmt.pix_mp.xfer_func;
1169
1170 mutex_lock(&ctx->state_lock);
1171 if (ctx->state == AML_STATE_IDLE) {
1172 ret = vdec_if_init(ctx, q_data->fmt->fourcc);
1173 if (ret) {
1174 aml_v4l2_err("[%d]: vdec_if_init() fail ret=%d",
1175 ctx->id, ret);
1176 mutex_unlock(&ctx->state_lock);
1177 return -EINVAL;
1178 }
1179 ctx->state = AML_STATE_INIT;
1180 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_INIT)",
1181 ctx->id, __func__);
1182 }
1183 mutex_unlock(&ctx->state_lock);
1184 }
1185
1186 return 0;
1187}
1188
1189static int vidioc_enum_framesizes(struct file *file, void *priv,
1190 struct v4l2_frmsizeenum *fsize)
1191{
1192 int i = 0;
1193 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1194
1195 if (fsize->index != 0)
1196 return -EINVAL;
1197
1198 for (i = 0; i < NUM_SUPPORTED_FRAMESIZE; ++i) {
1199 if (fsize->pixel_format != aml_vdec_framesizes[i].fourcc)
1200 continue;
1201
1202 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1203 fsize->stepwise = aml_vdec_framesizes[i].stepwise;
1204 if (!(ctx->dev->dec_capability &
1205 VCODEC_CAPABILITY_4K_DISABLED)) {
1206 aml_v4l2_debug(4, "[%d] 4K is enabled", ctx->id);
1207 fsize->stepwise.max_width =
1208 VCODEC_DEC_4K_CODED_WIDTH;
1209 fsize->stepwise.max_height =
1210 VCODEC_DEC_4K_CODED_HEIGHT;
1211 }
1212 aml_v4l2_debug(4, "[%d] %x, %d %d %d %d %d %d",
1213 ctx->id, ctx->dev->dec_capability,
1214 fsize->stepwise.min_width,
1215 fsize->stepwise.max_width,
1216 fsize->stepwise.step_width,
1217 fsize->stepwise.min_height,
1218 fsize->stepwise.max_height,
1219 fsize->stepwise.step_height);
1220 return 0;
1221 }
1222
1223 return -EINVAL;
1224}
1225
1226static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
1227{
1228 struct aml_video_fmt *fmt;
1229 int i, j = 0;
1230
1231 for (i = 0; i < NUM_FORMATS; i++) {
1232 if (output_queue && (aml_video_formats[i].type != AML_FMT_DEC))
1233 continue;
1234 if (!output_queue &&
1235 (aml_video_formats[i].type != AML_FMT_FRAME))
1236 continue;
1237
1238 if (j == f->index)
1239 break;
1240 ++j;
1241 }
1242
1243 if (i == NUM_FORMATS)
1244 return -EINVAL;
1245
1246 fmt = &aml_video_formats[i];
1247 f->pixelformat = fmt->fourcc;
1248
1249 return 0;
1250}
1251
1252static int vidioc_vdec_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
1253 struct v4l2_fmtdesc *f)
1254{
1255 return vidioc_enum_fmt(f, false);
1256}
1257
1258static int vidioc_vdec_enum_fmt_vid_out_mplane(struct file *file, void *priv,
1259 struct v4l2_fmtdesc *f)
1260{
1261 return vidioc_enum_fmt(f, true);
1262}
1263
1264static int vidioc_vdec_g_fmt(struct file *file, void *priv,
1265 struct v4l2_format *f)
1266{
1267 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1268 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
1269 struct vb2_queue *vq;
1270 struct aml_q_data *q_data;
1271
1272 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
1273 if (!vq) {
1274 aml_v4l2_err("[%d] no vb2 queue for type=%d", ctx->id, f->type);
1275 return -EINVAL;
1276 }
1277
1278 q_data = aml_vdec_get_q_data(ctx, f->type);
1279
1280 pix_mp->field = V4L2_FIELD_NONE;
1281 pix_mp->colorspace = ctx->colorspace;
1282 pix_mp->ycbcr_enc = ctx->ycbcr_enc;
1283 pix_mp->quantization = ctx->quantization;
1284 pix_mp->xfer_func = ctx->xfer_func;
1285
1286 if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
1287 (ctx->state >= AML_STATE_PROBE)) {
1288 /* Until STREAMOFF is called on the CAPTURE queue
1289 * (acknowledging the event), the driver operates as if
1290 * the resolution hasn't changed yet.
1291 * So we just return picinfo yet, and update picinfo in
1292 * stop_streaming hook function
1293 */
1294 /* it is used for alloc the decode buffer size. */
1295 q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
1296 q_data->sizeimage[1] = ctx->picinfo.c_len_sz;
1297
1298 /* it is used for alloc the EGL image buffer size. */
1299 q_data->coded_width = ctx->picinfo.coded_width;
1300 q_data->coded_height = ctx->picinfo.coded_height;
1301
1302 q_data->bytesperline[0] = ctx->picinfo.coded_width;
1303 q_data->bytesperline[1] = ctx->picinfo.coded_width;
1304
1305 /*
1306 * Width and height are set to the dimensions
1307 * of the movie, the buffer is bigger and
1308 * further processing stages should crop to this
1309 * rectangle.
1310 */
1311 pix_mp->width = q_data->coded_width;
1312 pix_mp->height = q_data->coded_height;
1313
1314 /*
1315 * Set pixelformat to the format in which mt vcodec
1316 * outputs the decoded frame
1317 */
1318 pix_mp->num_planes = q_data->fmt->num_planes;
1319 pix_mp->pixelformat = q_data->fmt->fourcc;
1320 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
1321 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
1322 pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
1323 pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
1324 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1325 /*
1326 * This is run on OUTPUT
1327 * The buffer contains compressed image
1328 * so width and height have no meaning.
1329 * Assign value here to pass v4l2-compliance test
1330 */
1331 pix_mp->width = q_data->visible_width;
1332 pix_mp->height = q_data->visible_height;
1333 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
1334 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
1335 pix_mp->pixelformat = q_data->fmt->fourcc;
1336 pix_mp->num_planes = q_data->fmt->num_planes;
1337 } else {
1338 pix_mp->width = q_data->coded_width;
1339 pix_mp->height = q_data->coded_height;
1340 pix_mp->num_planes = q_data->fmt->num_planes;
1341 pix_mp->pixelformat = q_data->fmt->fourcc;
1342 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
1343 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
1344 pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
1345 pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
1346
1347 aml_v4l2_debug(4, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
1348 ctx->id, f->type, ctx->state);
1349 }
1350
1351 return 0;
1352}
1353
1354/*int vidioc_vdec_g_ctrl(struct file *file, void *fh,
1355 struct v4l2_control *a)
1356{
1357 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
1358
1359 if (a->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE)
1360 a->value = 20;
1361
1362 return 0;
1363}*/
1364
1365static int vb2ops_vdec_queue_setup(struct vb2_queue *vq,
1366 unsigned int *nbuffers,
1367 unsigned int *nplanes,
1368 unsigned int sizes[], struct device *alloc_devs[])
1369{
1370 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
1371 struct aml_q_data *q_data;
1372 unsigned int i;
1373
1374 q_data = aml_vdec_get_q_data(ctx, vq->type);
1375
1376 if (q_data == NULL) {
1377 aml_v4l2_err("[%d] vq->type=%d err", ctx->id, vq->type);
1378 return -EINVAL;
1379 }
1380
1381 if (*nplanes) {
1382 for (i = 0; i < *nplanes; i++) {
1383 if (sizes[i] < q_data->sizeimage[i])
1384 return -EINVAL;
1385 //alloc_devs[i] = &ctx->dev->plat_dev->dev;
1386 alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
1387 }
1388 } else {
1389 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1390 *nplanes = 2;
1391 else
1392 *nplanes = 1;
1393
1394 for (i = 0; i < *nplanes; i++) {
1395 sizes[i] = q_data->sizeimage[i];
1396 //alloc_devs[i] = &ctx->dev->plat_dev->dev;
1397 alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
1398 }
1399 }
1400
1401 pr_info("[%d] type: %d, plane: %d, buf cnt: %d, size: [Y: %u, C: %u]\n",
1402 ctx->id, vq->type, *nplanes, *nbuffers, sizes[0], sizes[1]);
1403
1404 return 0;
1405}
1406
1407static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
1408{
1409 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1410 struct aml_q_data *q_data;
1411 int i;
1412
1413 aml_v4l2_debug(4, "[%d] (%d) id=%d",
1414 ctx->id, vb->vb2_queue->type, vb->index);
1415
1416 q_data = aml_vdec_get_q_data(ctx, vb->vb2_queue->type);
1417
1418 for (i = 0; i < q_data->fmt->num_planes; i++) {
1419 if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
1420 aml_v4l2_err("[%d] data will not fit into plane %d (%lu < %d)",
1421 ctx->id, i, vb2_plane_size(vb, i),
1422 q_data->sizeimage[i]);
1423 }
1424 }
1425
1426 return 0;
1427}
1428
1429static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
1430{
1431 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1432 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1433 struct aml_video_dec_buf *buf = NULL;
1434 struct aml_vcodec_mem src_mem;
1435 unsigned int dpb = 0;
1436
1437 vb2_v4l2 = to_vb2_v4l2_buffer(vb);
1438 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1439
1440 aml_v4l2_debug(3, "[%d] %s(), vb: %p, type: %d, idx: %d, state: %d, used: %d",
1441 ctx->id, __func__, vb, vb->vb2_queue->type,
1442 vb->index, vb->state, buf->used);
1443 /*
1444 * check if this buffer is ready to be used after decode
1445 */
1446 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1447 aml_v4l2_debug(3, "[%d] %s() [%d], y_va: %p, vf_h: %lx, state: %d", ctx->id,
1448 __func__, __LINE__, buf->frame_buffer.base_y.va,
1449 buf->frame_buffer.vf_handle, buf->frame_buffer.status);
1450
1451 if (!buf->que_in_m2m && buf->frame_buffer.status == FB_ST_NORMAL) {
1452 aml_v4l2_debug(3, "[%d] enque capture buf idx %d, %p\n",
1453 ctx->id, vb->index, vb);
1454 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
1455 buf->que_in_m2m = true;
1456 buf->queued_in_vb2 = true;
1457 buf->queued_in_v4l2 = true;
1458 buf->ready_to_display = false;
1459
1460 /*save capture bufs to be used for resetting config.*/
1461 list_add(&buf->node, &ctx->capture_list);
1462 } else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
1463 buf->queued_in_vb2 = false;
1464 buf->queued_in_v4l2 = true;
1465 buf->ready_to_display = false;
1466
1467 /* recycle vf */
1468 video_vf_put(ctx->ada_ctx->recv_name,
1469 &buf->frame_buffer, ctx->id);
1470 }
1471 return;
1472 }
1473
1474 v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
1475
1476 if (ctx->state != AML_STATE_INIT) {
1477 aml_v4l2_debug(4, "[%d] already init driver %d",
1478 ctx->id, ctx->state);
1479 return;
1480 }
1481
1482 vb2_v4l2 = to_vb2_v4l2_buffer(vb);
1483 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1484 if (buf->lastframe) {
1485 /* This shouldn't happen. Just in case. */
1486 aml_v4l2_err("[%d] Invalid flush buffer.", ctx->id);
1487 v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
1488 return;
1489 }
1490
1491 src_mem.va = vb2_plane_vaddr(vb, 0);
1492 src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1493 src_mem.size = (size_t)vb->planes[0].bytesused;
1494 if (vdec_if_probe(ctx, &src_mem, NULL))
1495 return;
1496
1497 if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
1498 pr_err("[%d] GET_PARAM_PICTURE_INFO err\n", ctx->id);
1499 return;
1500 }
1501
1502 if (vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpb)) {
1503 pr_err("[%d] GET_PARAM_DPB_SIZE err\n", ctx->id);
1504 return;
1505 }
1506
1507 ctx->dpb_size = dpb;
1508 ctx->last_decoded_picinfo = ctx->picinfo;
1509 aml_vdec_queue_res_chg_event(ctx);
1510
1511 mutex_lock(&ctx->state_lock);
1512 if (ctx->state == AML_STATE_INIT) {
1513 ctx->state = AML_STATE_PROBE;
1514 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_PROBE)",
1515 ctx->id, __func__);
1516 }
1517 mutex_unlock(&ctx->state_lock);
1518}
1519
1520static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
1521{
1522 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1523 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1524 struct aml_video_dec_buf *buf = NULL;
1525 bool buf_error;
1526
1527 vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
1528 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1529
1530 //mutex_lock(&ctx->lock);
1531 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1532 buf->queued_in_v4l2 = false;
1533 buf->queued_in_vb2 = false;
1534 }
1535 buf_error = buf->error;
1536 //mutex_unlock(&ctx->lock);
1537
1538 if (buf_error) {
1539 aml_v4l2_err("[%d] Unrecoverable error on buffer.", ctx->id);
1540 ctx->state = AML_STATE_ABORT;
1541 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
1542 ctx->id, __func__);
1543 }
1544}
1545
1546static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
1547{
1548 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1549 struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
1550 struct vb2_v4l2_buffer, vb2_buf);
1551 struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
1552 struct aml_video_dec_buf, vb);
1553 unsigned int size, phy_addr = 0;
1554 char *owner = __getname();
1555
1556 aml_v4l2_debug(4, "[%d] (%d) id=%d",
1557 ctx->id, vb->vb2_queue->type, vb->index);
1558
1559 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1560 buf->used = false;
1561 buf->ready_to_display = false;
1562 buf->queued_in_v4l2 = false;
1563 buf->frame_buffer.status = FB_ST_NORMAL;
1564 } else {
1565 buf->lastframe = false;
1566 }
1567
1568 /* codec_mm buffers count */
1569 if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
1570 size = vb->planes[0].length;
1571 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1572 snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id);
1573 strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
1574 buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
1575
1576 buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1577 phy_addr, size, vb->index);
1578 aml_v4l2_debug(3, "[%d] IN alloc, addr: %x, size: %u, idx: %u",
1579 ctx->id, phy_addr, size, vb->index);
1580 } else {
1581 size = vb->planes[0].length;
1582 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1583 snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
1584 strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
1585 buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
1586
1587 buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1588 phy_addr, size, vb->index);
1589 aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u",
1590 ctx->id, phy_addr, size, vb->index);
1591
1592 size = vb->planes[1].length;
1593 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
1594 buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1595 phy_addr, size, vb->index);
1596 aml_v4l2_debug(3, "[%d] OUT C alloc, addr: %x, size: %u, idx: %u",
1597 ctx->id, phy_addr, size, vb->index);
1598 }
1599
1600 __putname(owner);
1601
1602 return 0;
1603}
1604
1605static void codec_mm_bufs_cnt_clean(struct vb2_queue *q)
1606{
1607 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
1608 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1609 struct aml_video_dec_buf *buf = NULL;
1610 int i;
1611
1612 for (i = 0; i < q->num_buffers; ++i) {
1613 vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
1614 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1615 if (IS_ERR_OR_NULL(buf->mem[0]))
1616 return;
1617
1618 if (V4L2_TYPE_IS_OUTPUT(q->bufs[i]->type)) {
1619 v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
1620
1621 aml_v4l2_debug(3, "[%d] IN clean, addr: %lx, size: %u, idx: %u",
1622 ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
1623 buf->mem[0] = NULL;
1624 continue;
1625 }
1626
1627 v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
1628 v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]);
1629
1630 aml_v4l2_debug(3, "[%d] OUT Y clean, addr: %lx, size: %u, idx: %u",
1631 ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
1632 aml_v4l2_debug(3, "[%d] OUT C clean, addr: %lx, size: %u, idx: %u",
1633 ctx->id, buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i);
1634 buf->mem[0] = NULL;
1635 buf->mem[1] = NULL;
1636 }
1637}
1638
1639static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
1640{
1641 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
1642
1643 ctx->has_receive_eos = false;
1644 v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
1645
1646 return 0;
1647}
1648
1649static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
1650{
1651 struct aml_video_dec_buf *buf = NULL;
1652 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1653 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
1654 int i;
1655
1656 aml_v4l2_debug(3, "[%d] (%d) state=(%x) frame_cnt=%d",
1657 ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
1658
1659 codec_mm_bufs_cnt_clean(q);
1660
1661 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1662 while (v4l2_m2m_src_buf_remove(ctx->m2m_ctx));
1663 return;
1664 }
1665
1666 while (v4l2_m2m_dst_buf_remove(ctx->m2m_ctx));
1667
1668 for (i = 0; i < q->num_buffers; ++i) {
1669 if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) {
1670 q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
1671 atomic_dec(&q->owned_by_drv_count);
1672 }
1673 vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
1674 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1675 buf->frame_buffer.status = FB_ST_NORMAL;
1676 }
1677
1678 while (!list_empty(&ctx->capture_list)) {
1679 buf = list_entry(ctx->capture_list.next,
1680 struct aml_video_dec_buf, node);
1681 list_del(&buf->node);
1682 }
1683}
1684
1685static void m2mops_vdec_device_run(void *priv)
1686{
1687 struct aml_vcodec_ctx *ctx = priv;
1688 struct aml_vcodec_dev *dev = ctx->dev;
1689
1690 aml_v4l2_debug(4, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
1691
1692 queue_work(dev->decode_workqueue, &ctx->decode_work);
1693}
1694
1695void vdec_device_vf_run(struct aml_vcodec_ctx *ctx)
1696{
1697 aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
1698
1699 if (ctx->state < AML_STATE_ACTIVE ||
1700 ctx->state > AML_STATE_FLUSHED)
1701 return;
1702
1703 aml_thread_notify(ctx, AML_THREAD_CAPTURE);
1704}
1705
1706static int m2mops_vdec_job_ready(void *m2m_priv)
1707{
1708 struct aml_vcodec_ctx *ctx = m2m_priv;
1709
1710 aml_v4l2_debug(4, "[%d] %s(), state: %d", ctx->id,
1711 __func__, ctx->state);
1712
1713 if (ctx->state < AML_STATE_PROBE ||
1714 ctx->state > AML_STATE_FLUSHED)
1715 return 0;
1716
1717 return 1;
1718}
1719
1720static void m2mops_vdec_job_abort(void *priv)
1721{
1722 struct aml_vcodec_ctx *ctx = priv;
1723
1724 aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
1725}
1726
1727static int aml_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
1728{
1729 struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
1730 int ret = 0;
1731
1732 aml_v4l2_debug(4, "%s() [%d]", __func__, __LINE__);
1733
1734 switch (ctrl->id) {
1735 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1736 if (ctx->state >= AML_STATE_PROBE) {
1737 ctrl->val = ctx->dpb_size;
1738 } else {
1739 pr_err("Seqinfo not ready.\n");
1740 ctrl->val = 0;
1741 }
1742 break;
1743 default:
1744 ret = -EINVAL;
1745 }
1746 return ret;
1747}
1748
1749static int aml_vdec_try_s_v_ctrl(struct v4l2_ctrl *ctrl)
1750{
1751 struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
1752
1753 aml_v4l2_debug(4, "%s() [%d]", __func__, __LINE__);
1754
1755 if (ctrl->id == AML_V4L2_SET_DECMODE) {
1756 ctx->is_drm_mode = ctrl->val;
1757 pr_info("set stream mode: %x\n", ctrl->val);
1758 }
1759
1760 return 0;
1761}
1762
1763static const struct v4l2_ctrl_ops aml_vcodec_dec_ctrl_ops = {
1764 .g_volatile_ctrl = aml_vdec_g_v_ctrl,
1765 .try_ctrl = aml_vdec_try_s_v_ctrl,
1766};
1767
1768static const struct v4l2_ctrl_config ctrl_st_mode = {
1769 .name = "stream mode",
1770 .id = AML_V4L2_SET_DECMODE,
1771 .ops = &aml_vcodec_dec_ctrl_ops,
1772 .type = V4L2_CTRL_TYPE_BOOLEAN,
1773 .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
1774 .min = 0,
1775 .max = 1,
1776 .step = 1,
1777 .def = 0,
1778};
1779
1780int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx)
1781{
1782 int ret;
1783 struct v4l2_ctrl *ctrl;
1784
1785 v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1);
1786 ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl,
1787 &aml_vcodec_dec_ctrl_ops,
1788 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
1789 0, 32, 1, 1);
1790 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
1791 if (ctx->ctrl_hdl.error) {
1792 ret = ctx->ctrl_hdl.error;
1793 goto err;
1794 }
1795
1796 ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_mode, NULL);
1797 if (ctx->ctrl_hdl.error) {
1798 ret = ctx->ctrl_hdl.error;
1799 goto err;
1800 }
1801
1802 v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
1803
1804 return 0;
1805err:
1806 aml_v4l2_err("[%d] Adding control failed %d",
1807 ctx->id, ctx->ctrl_hdl.error);
1808 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1809 return ret;
1810}
1811
1812static void m2mops_vdec_lock(void *m2m_priv)
1813{
1814 struct aml_vcodec_ctx *ctx = m2m_priv;
1815
1816 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
1817 mutex_lock(&ctx->dev->dev_mutex);
1818}
1819
1820static void m2mops_vdec_unlock(void *m2m_priv)
1821{
1822 struct aml_vcodec_ctx *ctx = m2m_priv;
1823
1824 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
1825 mutex_unlock(&ctx->dev->dev_mutex);
1826}
1827
1828const struct v4l2_m2m_ops aml_vdec_m2m_ops = {
1829 .device_run = m2mops_vdec_device_run,
1830 .job_ready = m2mops_vdec_job_ready,
1831 .job_abort = m2mops_vdec_job_abort,
1832 .lock = m2mops_vdec_lock,
1833 .unlock = m2mops_vdec_unlock,
1834};
1835
1836static const struct vb2_ops aml_vdec_vb2_ops = {
1837 .queue_setup = vb2ops_vdec_queue_setup,
1838 .buf_prepare = vb2ops_vdec_buf_prepare,
1839 .buf_queue = vb2ops_vdec_buf_queue,
1840 .wait_prepare = vb2_ops_wait_prepare,
1841 .wait_finish = vb2_ops_wait_finish,
1842 .buf_init = vb2ops_vdec_buf_init,
1843 .buf_finish = vb2ops_vdec_buf_finish,
1844 .start_streaming = vb2ops_vdec_start_streaming,
1845 .stop_streaming = vb2ops_vdec_stop_streaming,
1846};
1847
1848const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = {
1849 .vidioc_streamon = vidioc_decoder_streamon,
1850 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1851 .vidioc_reqbufs = vidioc_decoder_reqbufs,
1852 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1853 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,//??
1854 //.vidioc_g_ctrl = vidioc_vdec_g_ctrl,
1855
1856 .vidioc_qbuf = vidioc_vdec_qbuf,
1857 .vidioc_dqbuf = vidioc_vdec_dqbuf,
1858
1859 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
1860 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
1861
1862 .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt,
1863 .vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt,
1864 .vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt,
1865 .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt,
1866
1867 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
1868
1869 .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane,
1870 .vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane,
1871 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1872
1873 .vidioc_querycap = vidioc_vdec_querycap,
1874 .vidioc_subscribe_event = vidioc_vdec_subscribe_evt,
1875 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1876 .vidioc_g_selection = vidioc_vdec_g_selection,
1877 .vidioc_s_selection = vidioc_vdec_s_selection,
1878
1879 .vidioc_decoder_cmd = vidioc_decoder_cmd,
1880 .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
1881};
1882
1883int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
1884 struct vb2_queue *dst_vq)
1885{
1886 struct aml_vcodec_ctx *ctx = priv;
1887 int ret = 0;
1888
1889 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
1890
1891 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1892 src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1893 src_vq->drv_priv = ctx;
1894 src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
1895 src_vq->ops = &aml_vdec_vb2_ops;
1896 src_vq->mem_ops = &vb2_dma_contig_memops;
1897 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1898 src_vq->lock = &ctx->dev->dev_mutex;
1899
1900 ret = vb2_queue_init(src_vq);
1901 if (ret) {
1902 aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(output)", ctx->id);
1903 return ret;
1904 }
1905 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1906 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
1907 dst_vq->drv_priv = ctx;
1908 dst_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
1909 dst_vq->ops = &aml_vdec_vb2_ops;
1910 dst_vq->mem_ops = &vb2_dma_contig_memops;
1911 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1912 dst_vq->lock = &ctx->dev->dev_mutex;
1913
1914 ret = vb2_queue_init(dst_vq);
1915 if (ret) {
1916 vb2_queue_release(src_vq);
1917 aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(capture)", ctx->id);
1918 }
1919
1920 return ret;
1921}
1922
1923