1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Cedrus VPU driver
4 *
5 * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
6 * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
7 * Copyright (C) 2018 Bootlin
8 *
9 * Based on the vim2m driver, that is:
10 *
11 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
12 * Pawel Osciak, <pawel@osciak.com>
13 * Marek Szyprowski, <m.szyprowski@samsung.com>
14 */
15
16 #include <media/v4l2-device.h>
17 #include <media/v4l2-ioctl.h>
18 #include <media/v4l2-event.h>
19 #include <media/v4l2-mem2mem.h>
20
21 #include "cedrus.h"
22 #include "cedrus_dec.h"
23 #include "cedrus_hw.h"
24
cedrus_device_run(void * priv)25 void cedrus_device_run(void *priv)
26 {
27 struct cedrus_ctx *ctx = priv;
28 struct cedrus_dev *dev = ctx->dev;
29 struct cedrus_run run = {};
30 struct media_request *src_req;
31 int error;
32
33 run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
34 run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
35
36 /* Apply request(s) controls if needed. */
37 src_req = run.src->vb2_buf.req_obj.req;
38
39 if (src_req)
40 v4l2_ctrl_request_setup(src_req, &ctx->hdl);
41
42 switch (ctx->src_fmt.pixelformat) {
43 case V4L2_PIX_FMT_MPEG2_SLICE:
44 run.mpeg2.sequence = cedrus_find_control_data(ctx,
45 V4L2_CID_STATELESS_MPEG2_SEQUENCE);
46 run.mpeg2.picture = cedrus_find_control_data(ctx,
47 V4L2_CID_STATELESS_MPEG2_PICTURE);
48 run.mpeg2.quantisation = cedrus_find_control_data(ctx,
49 V4L2_CID_STATELESS_MPEG2_QUANTISATION);
50 break;
51
52 case V4L2_PIX_FMT_H264_SLICE:
53 run.h264.decode_params = cedrus_find_control_data(ctx,
54 V4L2_CID_STATELESS_H264_DECODE_PARAMS);
55 run.h264.pps = cedrus_find_control_data(ctx,
56 V4L2_CID_STATELESS_H264_PPS);
57 run.h264.scaling_matrix = cedrus_find_control_data(ctx,
58 V4L2_CID_STATELESS_H264_SCALING_MATRIX);
59 run.h264.slice_params = cedrus_find_control_data(ctx,
60 V4L2_CID_STATELESS_H264_SLICE_PARAMS);
61 run.h264.sps = cedrus_find_control_data(ctx,
62 V4L2_CID_STATELESS_H264_SPS);
63 run.h264.pred_weights = cedrus_find_control_data(ctx,
64 V4L2_CID_STATELESS_H264_PRED_WEIGHTS);
65 break;
66
67 case V4L2_PIX_FMT_HEVC_SLICE:
68 run.h265.sps = cedrus_find_control_data(ctx,
69 V4L2_CID_STATELESS_HEVC_SPS);
70 run.h265.pps = cedrus_find_control_data(ctx,
71 V4L2_CID_STATELESS_HEVC_PPS);
72 run.h265.slice_params = cedrus_find_control_data(ctx,
73 V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
74 run.h265.decode_params = cedrus_find_control_data(ctx,
75 V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
76 run.h265.scaling_matrix = cedrus_find_control_data(ctx,
77 V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
78 run.h265.entry_points = cedrus_find_control_data(ctx,
79 V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS);
80 run.h265.entry_points_count = cedrus_get_num_of_controls(ctx,
81 V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS);
82 break;
83
84 case V4L2_PIX_FMT_VP8_FRAME:
85 run.vp8.frame_params = cedrus_find_control_data(ctx,
86 V4L2_CID_STATELESS_VP8_FRAME);
87 break;
88
89 default:
90 break;
91 }
92
93 v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
94
95 cedrus_dst_format_set(dev, &ctx->dst_fmt);
96
97 error = ctx->current_codec->setup(ctx, &run);
98 if (error)
99 v4l2_err(&ctx->dev->v4l2_dev,
100 "Failed to setup decoding job: %d\n", error);
101
102 /* Complete request(s) controls if needed. */
103
104 if (src_req)
105 v4l2_ctrl_request_complete(src_req, &ctx->hdl);
106
107 /* Trigger decoding if setup went well, bail out otherwise. */
108 if (!error) {
109 /* Start the watchdog timer. */
110 schedule_delayed_work(&dev->watchdog_work,
111 msecs_to_jiffies(2000));
112
113 ctx->current_codec->trigger(ctx);
114 } else {
115 v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
116 ctx->fh.m2m_ctx,
117 VB2_BUF_STATE_ERROR);
118 }
119 }
120