1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
5 * Rick Chang <rick.chang@mediatek.com>
6 * Xia Jiang <xia.jiang@mediatek.com>
7 */
8
9#include <linux/clk.h>
10#include <linux/err.h>
11#include <linux/interrupt.h>
12#include <linux/io.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/of_platform.h>
16#include <linux/platform_device.h>
17#include <linux/pm_runtime.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20#include <media/v4l2-event.h>
21#include <media/v4l2-mem2mem.h>
22#include <media/v4l2-ioctl.h>
23#include <media/videobuf2-core.h>
24#include <media/videobuf2-dma-contig.h>
25
26#include "mtk_jpeg_enc_hw.h"
27#include "mtk_jpeg_dec_hw.h"
28#include "mtk_jpeg_core.h"
29#include "mtk_jpeg_dec_parse.h"
30
31static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = {
32 {
33 .fourcc = V4L2_PIX_FMT_JPEG,
34 .colplanes = 1,
35 .flags = MTK_JPEG_FMT_FLAG_CAPTURE,
36 },
37 {
38 .fourcc = V4L2_PIX_FMT_NV12M,
39 .hw_format = JPEG_ENC_YUV_FORMAT_NV12,
40 .h_sample = {4, 4},
41 .v_sample = {4, 2},
42 .colplanes = 2,
43 .h_align = 4,
44 .v_align = 4,
45 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
46 },
47 {
48 .fourcc = V4L2_PIX_FMT_NV21M,
49 .hw_format = JEPG_ENC_YUV_FORMAT_NV21,
50 .h_sample = {4, 4},
51 .v_sample = {4, 2},
52 .colplanes = 2,
53 .h_align = 4,
54 .v_align = 4,
55 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
56 },
57 {
58 .fourcc = V4L2_PIX_FMT_YUYV,
59 .hw_format = JPEG_ENC_YUV_FORMAT_YUYV,
60 .h_sample = {8},
61 .v_sample = {4},
62 .colplanes = 1,
63 .h_align = 5,
64 .v_align = 3,
65 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
66 },
67 {
68 .fourcc = V4L2_PIX_FMT_YVYU,
69 .hw_format = JPEG_ENC_YUV_FORMAT_YVYU,
70 .h_sample = {8},
71 .v_sample = {4},
72 .colplanes = 1,
73 .h_align = 5,
74 .v_align = 3,
75 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
76 },
77};
78
79static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = {
80 {
81 .fourcc = V4L2_PIX_FMT_JPEG,
82 .colplanes = 1,
83 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
84 },
85 {
86 .fourcc = V4L2_PIX_FMT_YUV420M,
87 .h_sample = {4, 2, 2},
88 .v_sample = {4, 2, 2},
89 .colplanes = 3,
90 .h_align = 5,
91 .v_align = 4,
92 .flags = MTK_JPEG_FMT_FLAG_CAPTURE,
93 },
94 {
95 .fourcc = V4L2_PIX_FMT_YUV422M,
96 .h_sample = {4, 2, 2},
97 .v_sample = {4, 4, 4},
98 .colplanes = 3,
99 .h_align = 5,
100 .v_align = 3,
101 .flags = MTK_JPEG_FMT_FLAG_CAPTURE,
102 },
103};
104
105#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)
106#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
107#define MTK_JPEG_MAX_RETRY_TIME 5000
108
109enum {
110 MTK_JPEG_BUF_FLAGS_INIT = 0,
111 MTK_JPEG_BUF_FLAGS_LAST_FRAME = 1,
112};
113
114static int debug;
115module_param(debug, int, 0644);
116
117static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
118{
119 return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl);
120}
121
122static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh)
123{
124 return container_of(fh, struct mtk_jpeg_ctx, fh);
125}
126
127static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
128 struct vb2_buffer *vb)
129{
130 return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b);
131}
132
133static int mtk_jpeg_querycap(struct file *file, void *priv,
134 struct v4l2_capability *cap)
135{
136 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
137
138 strscpy(cap->driver, jpeg->variant->dev_name, sizeof(cap->driver));
139 strscpy(cap->card, jpeg->variant->dev_name, sizeof(cap->card));
140
141 return 0;
142}
143
144static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl)
145{
146 struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
147
148 switch (ctrl->id) {
149 case V4L2_CID_JPEG_RESTART_INTERVAL:
150 ctx->restart_interval = ctrl->val;
151 break;
152 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
153 ctx->enc_quality = ctrl->val;
154 break;
155 case V4L2_CID_JPEG_ACTIVE_MARKER:
156 ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1;
157 break;
158 }
159
160 return 0;
161}
162
163static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = {
164 .s_ctrl = vidioc_jpeg_enc_s_ctrl,
165};
166
167static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx)
168{
169 const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops;
170 struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
171
172 v4l2_ctrl_handler_init(handler, 3);
173
174 v4l2_ctrl_new_std(hdl: handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, min: 0, max: 100,
175 step: 1, def: 0);
176 v4l2_ctrl_new_std(hdl: handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, min: 48,
177 max: 100, step: 1, def: 90);
178 v4l2_ctrl_new_std(hdl: handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, min: 0,
179 V4L2_JPEG_ACTIVE_MARKER_APP1, step: 0, def: 0);
180
181 if (handler->error) {
182 v4l2_ctrl_handler_free(hdl: &ctx->ctrl_hdl);
183 return handler->error;
184 }
185
186 v4l2_ctrl_handler_setup(hdl: &ctx->ctrl_hdl);
187
188 return 0;
189}
190
191static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
192 struct v4l2_fmtdesc *f, u32 type)
193{
194 int i, num = 0;
195
196 for (i = 0; i < n; ++i) {
197 if (mtk_jpeg_formats[i].flags & type) {
198 if (num == f->index)
199 break;
200 ++num;
201 }
202 }
203
204 if (i >= n)
205 return -EINVAL;
206
207 f->pixelformat = mtk_jpeg_formats[i].fourcc;
208
209 return 0;
210}
211
212static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
213 struct v4l2_fmtdesc *f)
214{
215 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
216 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
217
218 return mtk_jpeg_enum_fmt(mtk_jpeg_formats: jpeg->variant->formats,
219 n: jpeg->variant->num_formats, f,
220 MTK_JPEG_FMT_FLAG_CAPTURE);
221}
222
223static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
224 struct v4l2_fmtdesc *f)
225{
226 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
227 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
228
229 return mtk_jpeg_enum_fmt(mtk_jpeg_formats: jpeg->variant->formats,
230 n: jpeg->variant->num_formats, f,
231 MTK_JPEG_FMT_FLAG_OUTPUT);
232}
233
234static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx,
235 enum v4l2_buf_type type)
236{
237 if (V4L2_TYPE_IS_OUTPUT(type))
238 return &ctx->out_q;
239 return &ctx->cap_q;
240}
241
242static struct mtk_jpeg_fmt *
243mtk_jpeg_find_format(struct mtk_jpeg_fmt *mtk_jpeg_formats, int num_formats,
244 u32 pixelformat, unsigned int fmt_type)
245{
246 unsigned int k;
247 struct mtk_jpeg_fmt *fmt;
248
249 for (k = 0; k < num_formats; k++) {
250 fmt = &mtk_jpeg_formats[k];
251
252 if (fmt->fourcc == pixelformat && fmt->flags & fmt_type)
253 return fmt;
254 }
255
256 return NULL;
257}
258
259static int mtk_jpeg_try_fmt_mplane(struct v4l2_pix_format_mplane *pix_mp,
260 struct mtk_jpeg_fmt *fmt)
261{
262 int i;
263
264 pix_mp->field = V4L2_FIELD_NONE;
265
266 pix_mp->num_planes = fmt->colplanes;
267 pix_mp->pixelformat = fmt->fourcc;
268
269 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
270 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
271
272 pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT,
273 MTK_JPEG_MAX_HEIGHT);
274 pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH,
275 MTK_JPEG_MAX_WIDTH);
276
277 pfmt->bytesperline = 0;
278 /* Source size must be aligned to 128 */
279 pfmt->sizeimage = round_up(pfmt->sizeimage, 128);
280 if (pfmt->sizeimage == 0)
281 pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE;
282 return 0;
283 }
284
285 /* other fourcc */
286 pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align),
287 MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT);
288 pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align),
289 MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH);
290
291 for (i = 0; i < fmt->colplanes; i++) {
292 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
293 u32 stride = pix_mp->width * fmt->h_sample[i] / 4;
294 u32 h = pix_mp->height * fmt->v_sample[i] / 4;
295
296 pfmt->bytesperline = stride;
297 pfmt->sizeimage = stride * h;
298 }
299 return 0;
300}
301
302static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
303 struct v4l2_format *f)
304{
305 struct vb2_queue *vq;
306 struct mtk_jpeg_q_data *q_data = NULL;
307 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
308 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
309 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
310 int i;
311
312 vq = v4l2_m2m_get_vq(m2m_ctx: ctx->fh.m2m_ctx, type: f->type);
313 if (!vq)
314 return -EINVAL;
315
316 q_data = mtk_jpeg_get_q_data(ctx, type: f->type);
317
318 pix_mp->width = q_data->pix_mp.width;
319 pix_mp->height = q_data->pix_mp.height;
320 pix_mp->field = V4L2_FIELD_NONE;
321 pix_mp->pixelformat = q_data->fmt->fourcc;
322 pix_mp->num_planes = q_data->fmt->colplanes;
323 pix_mp->colorspace = q_data->pix_mp.colorspace;
324 pix_mp->ycbcr_enc = q_data->pix_mp.ycbcr_enc;
325 pix_mp->xfer_func = q_data->pix_mp.xfer_func;
326 pix_mp->quantization = q_data->pix_mp.quantization;
327
328 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) g_fmt:%c%c%c%c wxh:%ux%u\n",
329 f->type,
330 (pix_mp->pixelformat & 0xff),
331 (pix_mp->pixelformat >> 8 & 0xff),
332 (pix_mp->pixelformat >> 16 & 0xff),
333 (pix_mp->pixelformat >> 24 & 0xff),
334 pix_mp->width, pix_mp->height);
335
336 for (i = 0; i < pix_mp->num_planes; i++) {
337 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
338
339 pfmt->bytesperline = q_data->pix_mp.plane_fmt[i].bytesperline;
340 pfmt->sizeimage = q_data->pix_mp.plane_fmt[i].sizeimage;
341
342 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
343 "plane[%d] bpl=%u, size=%u\n",
344 i,
345 pfmt->bytesperline,
346 pfmt->sizeimage);
347 }
348 return 0;
349}
350
351static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
352 struct v4l2_format *f)
353{
354 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
355 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
356 struct mtk_jpeg_fmt *fmt;
357
358 fmt = mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
359 num_formats: jpeg->variant->num_formats,
360 pixelformat: f->fmt.pix_mp.pixelformat,
361 MTK_JPEG_FMT_FLAG_CAPTURE);
362 if (!fmt)
363 fmt = ctx->cap_q.fmt;
364
365 v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
366 f->type,
367 (fmt->fourcc & 0xff),
368 (fmt->fourcc >> 8 & 0xff),
369 (fmt->fourcc >> 16 & 0xff),
370 (fmt->fourcc >> 24 & 0xff));
371
372 if (ctx->state != MTK_JPEG_INIT) {
373 mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
374 return 0;
375 }
376
377 return mtk_jpeg_try_fmt_mplane(pix_mp: &f->fmt.pix_mp, fmt);
378}
379
380static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
381 struct v4l2_format *f)
382{
383 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
384 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
385 struct mtk_jpeg_fmt *fmt;
386
387 fmt = mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
388 num_formats: jpeg->variant->num_formats,
389 pixelformat: f->fmt.pix_mp.pixelformat,
390 MTK_JPEG_FMT_FLAG_OUTPUT);
391 if (!fmt)
392 fmt = ctx->out_q.fmt;
393
394 v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
395 f->type,
396 (fmt->fourcc & 0xff),
397 (fmt->fourcc >> 8 & 0xff),
398 (fmt->fourcc >> 16 & 0xff),
399 (fmt->fourcc >> 24 & 0xff));
400
401 if (ctx->state != MTK_JPEG_INIT) {
402 mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
403 return 0;
404 }
405
406 return mtk_jpeg_try_fmt_mplane(pix_mp: &f->fmt.pix_mp, fmt);
407}
408
409static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx,
410 struct v4l2_format *f, unsigned int fmt_type)
411{
412 struct vb2_queue *vq;
413 struct mtk_jpeg_q_data *q_data = NULL;
414 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
415 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
416 int i;
417
418 vq = v4l2_m2m_get_vq(m2m_ctx: ctx->fh.m2m_ctx, type: f->type);
419 if (!vq)
420 return -EINVAL;
421
422 q_data = mtk_jpeg_get_q_data(ctx, type: f->type);
423
424 if (vb2_is_busy(q: vq)) {
425 v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
426 return -EBUSY;
427 }
428
429 q_data->fmt = mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
430 num_formats: jpeg->variant->num_formats,
431 pixelformat: pix_mp->pixelformat, fmt_type);
432 q_data->pix_mp.width = pix_mp->width;
433 q_data->pix_mp.height = pix_mp->height;
434 q_data->enc_crop_rect.width = pix_mp->width;
435 q_data->enc_crop_rect.height = pix_mp->height;
436 q_data->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
437 q_data->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
438 q_data->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
439 q_data->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
440
441 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) s_fmt:%c%c%c%c wxh:%ux%u\n",
442 f->type,
443 (q_data->fmt->fourcc & 0xff),
444 (q_data->fmt->fourcc >> 8 & 0xff),
445 (q_data->fmt->fourcc >> 16 & 0xff),
446 (q_data->fmt->fourcc >> 24 & 0xff),
447 q_data->pix_mp.width, q_data->pix_mp.height);
448
449 for (i = 0; i < q_data->fmt->colplanes; i++) {
450 q_data->pix_mp.plane_fmt[i].bytesperline =
451 pix_mp->plane_fmt[i].bytesperline;
452 q_data->pix_mp.plane_fmt[i].sizeimage =
453 pix_mp->plane_fmt[i].sizeimage;
454
455 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
456 "plane[%d] bpl=%u, size=%u\n",
457 i, q_data->pix_mp.plane_fmt[i].bytesperline,
458 q_data->pix_mp.plane_fmt[i].sizeimage);
459 }
460
461 return 0;
462}
463
464static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
465 struct v4l2_format *f)
466{
467 int ret;
468
469 ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f);
470 if (ret)
471 return ret;
472
473 return mtk_jpeg_s_fmt_mplane(ctx: mtk_jpeg_fh_to_ctx(fh: priv), f,
474 MTK_JPEG_FMT_FLAG_OUTPUT);
475}
476
477static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
478 struct v4l2_format *f)
479{
480 int ret;
481
482 ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f);
483 if (ret)
484 return ret;
485
486 return mtk_jpeg_s_fmt_mplane(ctx: mtk_jpeg_fh_to_ctx(fh: priv), f,
487 MTK_JPEG_FMT_FLAG_CAPTURE);
488}
489
490static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx)
491{
492 static const struct v4l2_event ev_src_ch = {
493 .type = V4L2_EVENT_SOURCE_CHANGE,
494 .u.src_change.changes =
495 V4L2_EVENT_SRC_CH_RESOLUTION,
496 };
497
498 v4l2_event_queue_fh(fh: &ctx->fh, ev: &ev_src_ch);
499}
500
501static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
502 const struct v4l2_event_subscription *sub)
503{
504 switch (sub->type) {
505 case V4L2_EVENT_SOURCE_CHANGE:
506 return v4l2_src_change_event_subscribe(fh, sub);
507 }
508
509 return v4l2_ctrl_subscribe_event(fh, sub);
510}
511
512static int mtk_jpeg_enc_g_selection(struct file *file, void *priv,
513 struct v4l2_selection *s)
514{
515 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
516
517 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
518 return -EINVAL;
519
520 switch (s->target) {
521 case V4L2_SEL_TGT_CROP:
522 s->r = ctx->out_q.enc_crop_rect;
523 break;
524 case V4L2_SEL_TGT_CROP_BOUNDS:
525 case V4L2_SEL_TGT_CROP_DEFAULT:
526 s->r.width = ctx->out_q.pix_mp.width;
527 s->r.height = ctx->out_q.pix_mp.height;
528 s->r.left = 0;
529 s->r.top = 0;
530 break;
531 default:
532 return -EINVAL;
533 }
534 return 0;
535}
536
537static int mtk_jpeg_dec_g_selection(struct file *file, void *priv,
538 struct v4l2_selection *s)
539{
540 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
541
542 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
543 return -EINVAL;
544
545 switch (s->target) {
546 case V4L2_SEL_TGT_COMPOSE:
547 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
548 s->r.width = ctx->out_q.pix_mp.width;
549 s->r.height = ctx->out_q.pix_mp.height;
550 s->r.left = 0;
551 s->r.top = 0;
552 break;
553 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
554 case V4L2_SEL_TGT_COMPOSE_PADDED:
555 s->r.width = ctx->cap_q.pix_mp.width;
556 s->r.height = ctx->cap_q.pix_mp.height;
557 s->r.left = 0;
558 s->r.top = 0;
559 break;
560 default:
561 return -EINVAL;
562 }
563 return 0;
564}
565
566static int mtk_jpeg_enc_s_selection(struct file *file, void *priv,
567 struct v4l2_selection *s)
568{
569 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
570
571 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
572 return -EINVAL;
573
574 switch (s->target) {
575 case V4L2_SEL_TGT_CROP:
576 s->r.left = 0;
577 s->r.top = 0;
578 s->r.width = min(s->r.width, ctx->out_q.pix_mp.width);
579 s->r.height = min(s->r.height, ctx->out_q.pix_mp.height);
580 ctx->out_q.enc_crop_rect = s->r;
581 break;
582 default:
583 return -EINVAL;
584 }
585
586 return 0;
587}
588
589static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
590{
591 struct v4l2_fh *fh = file->private_data;
592 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: priv);
593 struct vb2_queue *vq;
594 struct vb2_buffer *vb;
595 struct mtk_jpeg_src_buf *jpeg_src_buf;
596
597 if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
598 goto end;
599
600 vq = v4l2_m2m_get_vq(m2m_ctx: fh->m2m_ctx, type: buf->type);
601 vb = vb2_get_buffer(q: vq, index: buf->index);
602 if (!vb) {
603 dev_err(ctx->jpeg->dev, "buffer not found\n");
604 return -EINVAL;
605 }
606 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
607 jpeg_src_buf->bs_size = buf->m.planes[0].bytesused;
608
609end:
610 return v4l2_m2m_qbuf(file, m2m_ctx: fh->m2m_ctx, buf);
611}
612
613static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = {
614 .vidioc_querycap = mtk_jpeg_querycap,
615 .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap,
616 .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out,
617 .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane,
618 .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane,
619 .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane,
620 .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane,
621 .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane,
622 .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane,
623 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
624 .vidioc_subscribe_event = mtk_jpeg_subscribe_event,
625 .vidioc_g_selection = mtk_jpeg_enc_g_selection,
626 .vidioc_s_selection = mtk_jpeg_enc_s_selection,
627
628 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
629 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
630 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
631 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
632 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
633 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
634 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
635 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
636
637 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
638
639 .vidioc_encoder_cmd = v4l2_m2m_ioctl_encoder_cmd,
640 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
641};
642
643static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = {
644 .vidioc_querycap = mtk_jpeg_querycap,
645 .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap,
646 .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out,
647 .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane,
648 .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane,
649 .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane,
650 .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane,
651 .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane,
652 .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane,
653 .vidioc_qbuf = mtk_jpeg_qbuf,
654 .vidioc_subscribe_event = mtk_jpeg_subscribe_event,
655 .vidioc_g_selection = mtk_jpeg_dec_g_selection,
656
657 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
658 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
659 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
660 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
661 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
662 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
663 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
664 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
665
666 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
667
668 .vidioc_decoder_cmd = v4l2_m2m_ioctl_decoder_cmd,
669 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
670};
671
672static int mtk_jpeg_queue_setup(struct vb2_queue *q,
673 unsigned int *num_buffers,
674 unsigned int *num_planes,
675 unsigned int sizes[],
676 struct device *alloc_ctxs[])
677{
678 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
679 struct mtk_jpeg_q_data *q_data = NULL;
680 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
681 int i;
682
683 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) buf_req count=%u\n",
684 q->type, *num_buffers);
685
686 q_data = mtk_jpeg_get_q_data(ctx, type: q->type);
687 if (!q_data)
688 return -EINVAL;
689
690 if (*num_planes) {
691 for (i = 0; i < *num_planes; i++)
692 if (sizes[i] < q_data->pix_mp.plane_fmt[i].sizeimage)
693 return -EINVAL;
694 return 0;
695 }
696
697 *num_planes = q_data->fmt->colplanes;
698 for (i = 0; i < q_data->fmt->colplanes; i++) {
699 sizes[i] = q_data->pix_mp.plane_fmt[i].sizeimage;
700 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "sizeimage[%d]=%u\n",
701 i, sizes[i]);
702 }
703
704 return 0;
705}
706
707static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
708{
709 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q: vb->vb2_queue);
710 struct mtk_jpeg_q_data *q_data = NULL;
711 struct v4l2_plane_pix_format plane_fmt = {};
712 int i;
713
714 q_data = mtk_jpeg_get_q_data(ctx, type: vb->vb2_queue->type);
715 if (!q_data)
716 return -EINVAL;
717
718 for (i = 0; i < q_data->fmt->colplanes; i++) {
719 plane_fmt = q_data->pix_mp.plane_fmt[i];
720 if (ctx->enable_exif &&
721 q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG)
722 vb2_set_plane_payload(vb, plane_no: i, size: plane_fmt.sizeimage +
723 MTK_JPEG_MAX_EXIF_SIZE);
724 else
725 vb2_set_plane_payload(vb, plane_no: i, size: plane_fmt.sizeimage);
726 }
727
728 return 0;
729}
730
731static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx,
732 struct mtk_jpeg_dec_param *param)
733{
734 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
735 struct mtk_jpeg_q_data *q_data;
736
737 q_data = &ctx->out_q;
738 if (q_data->pix_mp.width != param->pic_w ||
739 q_data->pix_mp.height != param->pic_h) {
740 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Picture size change\n");
741 return true;
742 }
743
744 q_data = &ctx->cap_q;
745 if (q_data->fmt !=
746 mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
747 num_formats: jpeg->variant->num_formats, pixelformat: param->dst_fourcc,
748 MTK_JPEG_FMT_FLAG_CAPTURE)) {
749 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n");
750 return true;
751 }
752 return false;
753}
754
755static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx,
756 struct mtk_jpeg_dec_param *param)
757{
758 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
759 struct mtk_jpeg_q_data *q_data;
760 int i;
761
762 q_data = &ctx->out_q;
763 q_data->pix_mp.width = param->pic_w;
764 q_data->pix_mp.height = param->pic_h;
765
766 q_data = &ctx->cap_q;
767 q_data->pix_mp.width = param->dec_w;
768 q_data->pix_mp.height = param->dec_h;
769 q_data->fmt = mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
770 num_formats: jpeg->variant->num_formats,
771 pixelformat: param->dst_fourcc,
772 MTK_JPEG_FMT_FLAG_CAPTURE);
773
774 for (i = 0; i < q_data->fmt->colplanes; i++) {
775 q_data->pix_mp.plane_fmt[i].bytesperline = param->mem_stride[i];
776 q_data->pix_mp.plane_fmt[i].sizeimage = param->comp_size[i];
777 }
778
779 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
780 "set_parse cap:%c%c%c%c pic(%u, %u), buf(%u, %u)\n",
781 (param->dst_fourcc & 0xff),
782 (param->dst_fourcc >> 8 & 0xff),
783 (param->dst_fourcc >> 16 & 0xff),
784 (param->dst_fourcc >> 24 & 0xff),
785 param->pic_w, param->pic_h,
786 param->dec_w, param->dec_h);
787}
788
789static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb)
790{
791 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q: vb->vb2_queue);
792 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
793
794 v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
795 vb->vb2_queue->type, vb->index, vb);
796
797 v4l2_m2m_buf_queue(m2m_ctx: ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
798}
799
800static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb)
801{
802 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q: vb->vb2_queue);
803 struct mtk_jpeg_dec_param *param;
804 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
805 struct mtk_jpeg_src_buf *jpeg_src_buf;
806 bool header_valid;
807
808 v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
809 vb->vb2_queue->type, vb->index, vb);
810
811 if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
812 goto end;
813
814 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
815 param = &jpeg_src_buf->dec_param;
816 memset(param, 0, sizeof(*param));
817
818 header_valid = mtk_jpeg_parse(param, src_addr_va: (u8 *)vb2_plane_vaddr(vb, plane_no: 0),
819 src_size: vb2_get_plane_payload(vb, plane_no: 0));
820 if (!header_valid) {
821 v4l2_err(&jpeg->v4l2_dev, "Header invalid.\n");
822 vb2_buffer_done(vb, state: VB2_BUF_STATE_ERROR);
823 return;
824 }
825
826 if (ctx->state == MTK_JPEG_INIT) {
827 struct vb2_queue *dst_vq = v4l2_m2m_get_vq(
828 m2m_ctx: ctx->fh.m2m_ctx, type: V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
829
830 mtk_jpeg_queue_src_chg_event(ctx);
831 mtk_jpeg_set_queue_data(ctx, param);
832 ctx->state = vb2_is_streaming(q: dst_vq) ?
833 MTK_JPEG_SOURCE_CHANGE : MTK_JPEG_RUNNING;
834 }
835end:
836 v4l2_m2m_buf_queue(m2m_ctx: ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
837}
838
839static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
840 enum v4l2_buf_type type)
841{
842 if (V4L2_TYPE_IS_OUTPUT(type))
843 return v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
844 else
845 return v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
846}
847
848static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
849{
850 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
851 struct vb2_v4l2_buffer *vb;
852
853 while ((vb = mtk_jpeg_buf_remove(ctx, type: q->type)))
854 v4l2_m2m_buf_done(buf: vb, state: VB2_BUF_STATE_ERROR);
855}
856
857static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
858{
859 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
860 struct vb2_v4l2_buffer *vb;
861
862 /*
863 * STREAMOFF is an acknowledgment for source change event.
864 * Before STREAMOFF, we still have to return the old resolution and
865 * subsampling. Update capture queue when the stream is off.
866 */
867 if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
868 V4L2_TYPE_IS_CAPTURE(q->type)) {
869 struct mtk_jpeg_src_buf *src_buf;
870
871 vb = v4l2_m2m_next_src_buf(m2m_ctx: ctx->fh.m2m_ctx);
872 src_buf = mtk_jpeg_vb2_to_srcbuf(vb: &vb->vb2_buf);
873 mtk_jpeg_set_queue_data(ctx, param: &src_buf->dec_param);
874 ctx->state = MTK_JPEG_RUNNING;
875 } else if (V4L2_TYPE_IS_OUTPUT(q->type)) {
876 ctx->state = MTK_JPEG_INIT;
877 }
878
879 while ((vb = mtk_jpeg_buf_remove(ctx, type: q->type)))
880 v4l2_m2m_buf_done(buf: vb, state: VB2_BUF_STATE_ERROR);
881}
882
883static const struct vb2_ops mtk_jpeg_dec_qops = {
884 .queue_setup = mtk_jpeg_queue_setup,
885 .buf_prepare = mtk_jpeg_buf_prepare,
886 .buf_queue = mtk_jpeg_dec_buf_queue,
887 .wait_prepare = vb2_ops_wait_prepare,
888 .wait_finish = vb2_ops_wait_finish,
889 .stop_streaming = mtk_jpeg_dec_stop_streaming,
890};
891
892static const struct vb2_ops mtk_jpeg_enc_qops = {
893 .queue_setup = mtk_jpeg_queue_setup,
894 .buf_prepare = mtk_jpeg_buf_prepare,
895 .buf_queue = mtk_jpeg_enc_buf_queue,
896 .wait_prepare = vb2_ops_wait_prepare,
897 .wait_finish = vb2_ops_wait_finish,
898 .stop_streaming = mtk_jpeg_enc_stop_streaming,
899};
900
901static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx,
902 struct vb2_buffer *src_buf,
903 struct mtk_jpeg_bs *bs)
904{
905 bs->str_addr = vb2_dma_contig_plane_dma_addr(vb: src_buf, plane_no: 0);
906 bs->end_addr = bs->str_addr +
907 round_up(vb2_get_plane_payload(src_buf, 0), 16);
908 bs->size = round_up(vb2_plane_size(src_buf, 0), 128);
909}
910
911static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,
912 struct mtk_jpeg_dec_param *param,
913 struct vb2_buffer *dst_buf,
914 struct mtk_jpeg_fb *fb)
915{
916 int i;
917
918 if (param->comp_num != dst_buf->num_planes) {
919 dev_err(ctx->jpeg->dev, "plane number mismatch (%u != %u)\n",
920 param->comp_num, dst_buf->num_planes);
921 return -EINVAL;
922 }
923
924 for (i = 0; i < dst_buf->num_planes; i++) {
925 if (vb2_plane_size(vb: dst_buf, plane_no: i) < param->comp_size[i]) {
926 dev_err(ctx->jpeg->dev,
927 "buffer size is underflow (%lu < %u)\n",
928 vb2_plane_size(dst_buf, 0),
929 param->comp_size[i]);
930 return -EINVAL;
931 }
932 fb->plane_addr[i] = vb2_dma_contig_plane_dma_addr(vb: dst_buf, plane_no: i);
933 }
934
935 return 0;
936}
937
938static void mtk_jpeg_enc_device_run(void *priv)
939{
940 struct mtk_jpeg_ctx *ctx = priv;
941 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
942 struct vb2_v4l2_buffer *src_buf, *dst_buf;
943 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
944 unsigned long flags;
945 int ret;
946
947 src_buf = v4l2_m2m_next_src_buf(m2m_ctx: ctx->fh.m2m_ctx);
948 dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx: ctx->fh.m2m_ctx);
949
950 ret = pm_runtime_resume_and_get(dev: jpeg->dev);
951 if (ret < 0)
952 goto enc_end;
953
954 schedule_delayed_work(dwork: &jpeg->job_timeout_work,
955 delay: msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
956
957 spin_lock_irqsave(&jpeg->hw_lock, flags);
958
959 /*
960 * Resetting the hardware every frame is to ensure that all the
961 * registers are cleared. This is a hardware requirement.
962 */
963 mtk_jpeg_enc_reset(base: jpeg->reg_base);
964
965 mtk_jpeg_set_enc_src(ctx, base: jpeg->reg_base, src_buf: &src_buf->vb2_buf);
966 mtk_jpeg_set_enc_dst(ctx, base: jpeg->reg_base, dst_buf: &dst_buf->vb2_buf);
967 mtk_jpeg_set_enc_params(ctx, base: jpeg->reg_base);
968 mtk_jpeg_enc_start(enc_reg_base: jpeg->reg_base);
969 spin_unlock_irqrestore(lock: &jpeg->hw_lock, flags);
970 return;
971
972enc_end:
973 v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
974 v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
975 v4l2_m2m_buf_done(buf: src_buf, state: buf_state);
976 v4l2_m2m_buf_done(buf: dst_buf, state: buf_state);
977 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
978}
979
980static void mtk_jpeg_multicore_enc_device_run(void *priv)
981{
982 struct mtk_jpeg_ctx *ctx = priv;
983 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
984
985 queue_work(wq: jpeg->workqueue, work: &ctx->jpeg_work);
986}
987
988static void mtk_jpeg_multicore_dec_device_run(void *priv)
989{
990 struct mtk_jpeg_ctx *ctx = priv;
991 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
992
993 queue_work(wq: jpeg->workqueue, work: &ctx->jpeg_work);
994}
995
996static void mtk_jpeg_dec_device_run(void *priv)
997{
998 struct mtk_jpeg_ctx *ctx = priv;
999 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1000 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1001 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1002 unsigned long flags;
1003 struct mtk_jpeg_src_buf *jpeg_src_buf;
1004 struct mtk_jpeg_bs bs;
1005 struct mtk_jpeg_fb fb;
1006 int ret;
1007
1008 src_buf = v4l2_m2m_next_src_buf(m2m_ctx: ctx->fh.m2m_ctx);
1009 dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx: ctx->fh.m2m_ctx);
1010 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb: &src_buf->vb2_buf);
1011
1012 if (mtk_jpeg_check_resolution_change(ctx, param: &jpeg_src_buf->dec_param)) {
1013 mtk_jpeg_queue_src_chg_event(ctx);
1014 ctx->state = MTK_JPEG_SOURCE_CHANGE;
1015 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1016 return;
1017 }
1018
1019 ret = pm_runtime_resume_and_get(dev: jpeg->dev);
1020 if (ret < 0)
1021 goto dec_end;
1022
1023 mtk_jpeg_set_dec_src(ctx, src_buf: &src_buf->vb2_buf, bs: &bs);
1024 if (mtk_jpeg_set_dec_dst(ctx, param: &jpeg_src_buf->dec_param, dst_buf: &dst_buf->vb2_buf, fb: &fb))
1025 goto dec_end;
1026
1027 schedule_delayed_work(dwork: &jpeg->job_timeout_work,
1028 delay: msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
1029
1030 spin_lock_irqsave(&jpeg->hw_lock, flags);
1031 mtk_jpeg_dec_reset(dec_reg_base: jpeg->reg_base);
1032 mtk_jpeg_dec_set_config(base: jpeg->reg_base,
1033 cfg: &jpeg_src_buf->dec_param,
1034 bitstream_size: jpeg_src_buf->bs_size,
1035 bs: &bs,
1036 fb: &fb);
1037 mtk_jpeg_dec_start(dec_reg_base: jpeg->reg_base);
1038 spin_unlock_irqrestore(lock: &jpeg->hw_lock, flags);
1039 return;
1040
1041dec_end:
1042 v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1043 v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1044 v4l2_m2m_buf_done(buf: src_buf, state: buf_state);
1045 v4l2_m2m_buf_done(buf: dst_buf, state: buf_state);
1046 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1047}
1048
1049static int mtk_jpeg_dec_job_ready(void *priv)
1050{
1051 struct mtk_jpeg_ctx *ctx = priv;
1052
1053 return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0;
1054}
1055
1056static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = {
1057 .device_run = mtk_jpeg_enc_device_run,
1058};
1059
1060static const struct v4l2_m2m_ops mtk_jpeg_multicore_enc_m2m_ops = {
1061 .device_run = mtk_jpeg_multicore_enc_device_run,
1062};
1063
1064static const struct v4l2_m2m_ops mtk_jpeg_multicore_dec_m2m_ops = {
1065 .device_run = mtk_jpeg_multicore_dec_device_run,
1066};
1067
1068static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = {
1069 .device_run = mtk_jpeg_dec_device_run,
1070 .job_ready = mtk_jpeg_dec_job_ready,
1071};
1072
1073static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
1074 struct vb2_queue *dst_vq)
1075{
1076 struct mtk_jpeg_ctx *ctx = priv;
1077 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1078 int ret;
1079
1080 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1081 src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1082 src_vq->drv_priv = ctx;
1083 src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
1084 src_vq->ops = jpeg->variant->qops;
1085 src_vq->mem_ops = &vb2_dma_contig_memops;
1086 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1087 src_vq->lock = &ctx->jpeg->lock;
1088 src_vq->dev = ctx->jpeg->dev;
1089 ret = vb2_queue_init(q: src_vq);
1090 if (ret)
1091 return ret;
1092
1093 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1094 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1095 dst_vq->drv_priv = ctx;
1096 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1097 dst_vq->ops = jpeg->variant->qops;
1098 dst_vq->mem_ops = &vb2_dma_contig_memops;
1099 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1100 dst_vq->lock = &ctx->jpeg->lock;
1101 dst_vq->dev = ctx->jpeg->dev;
1102 ret = vb2_queue_init(q: dst_vq);
1103
1104 return ret;
1105}
1106
1107static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
1108{
1109 int ret;
1110
1111 ret = clk_bulk_prepare_enable(num_clks: jpeg->variant->num_clks,
1112 clks: jpeg->variant->clks);
1113 if (ret)
1114 dev_err(jpeg->dev, "Failed to open jpeg clk: %d\n", ret);
1115}
1116
1117static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
1118{
1119 clk_bulk_disable_unprepare(num_clks: jpeg->variant->num_clks,
1120 clks: jpeg->variant->clks);
1121}
1122
1123static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx)
1124{
1125 struct mtk_jpeg_q_data *q = &ctx->out_q;
1126 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1127
1128 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1129 q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1130 q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1131 q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1132 q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1133
1134 q->fmt = mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
1135 num_formats: jpeg->variant->num_formats,
1136 pixelformat: jpeg->variant->out_q_default_fourcc,
1137 MTK_JPEG_FMT_FLAG_OUTPUT);
1138 q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1139 q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1140 mtk_jpeg_try_fmt_mplane(pix_mp: &q->pix_mp, fmt: q->fmt);
1141
1142 q = &ctx->cap_q;
1143 q->fmt = mtk_jpeg_find_format(mtk_jpeg_formats: jpeg->variant->formats,
1144 num_formats: jpeg->variant->num_formats,
1145 pixelformat: jpeg->variant->cap_q_default_fourcc,
1146 MTK_JPEG_FMT_FLAG_CAPTURE);
1147 q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1148 q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1149 q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1150 q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1151 q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1152 q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1153
1154 mtk_jpeg_try_fmt_mplane(pix_mp: &q->pix_mp, fmt: q->fmt);
1155}
1156
1157static int mtk_jpeg_open(struct file *file)
1158{
1159 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1160 struct video_device *vfd = video_devdata(file);
1161 struct mtk_jpeg_ctx *ctx;
1162 int ret = 0;
1163
1164 ctx = kzalloc(size: sizeof(*ctx), GFP_KERNEL);
1165 if (!ctx)
1166 return -ENOMEM;
1167
1168 if (mutex_lock_interruptible(&jpeg->lock)) {
1169 ret = -ERESTARTSYS;
1170 goto free;
1171 }
1172
1173 INIT_WORK(&ctx->jpeg_work, jpeg->variant->jpeg_worker);
1174 INIT_LIST_HEAD(list: &ctx->dst_done_queue);
1175 spin_lock_init(&ctx->done_queue_lock);
1176 v4l2_fh_init(fh: &ctx->fh, vdev: vfd);
1177 file->private_data = &ctx->fh;
1178 v4l2_fh_add(fh: &ctx->fh);
1179
1180 ctx->jpeg = jpeg;
1181 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(m2m_dev: jpeg->m2m_dev, drv_priv: ctx,
1182 queue_init: mtk_jpeg_queue_init);
1183 if (IS_ERR(ptr: ctx->fh.m2m_ctx)) {
1184 ret = PTR_ERR(ptr: ctx->fh.m2m_ctx);
1185 goto error;
1186 }
1187
1188 if (jpeg->variant->cap_q_default_fourcc == V4L2_PIX_FMT_JPEG) {
1189 ret = mtk_jpeg_enc_ctrls_setup(ctx);
1190 if (ret) {
1191 v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n");
1192 goto error;
1193 }
1194 } else {
1195 v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0);
1196 }
1197
1198 mtk_jpeg_set_default_params(ctx);
1199 mutex_unlock(lock: &jpeg->lock);
1200 return 0;
1201
1202error:
1203 v4l2_fh_del(fh: &ctx->fh);
1204 v4l2_fh_exit(fh: &ctx->fh);
1205 mutex_unlock(lock: &jpeg->lock);
1206free:
1207 kfree(objp: ctx);
1208 return ret;
1209}
1210
1211static int mtk_jpeg_release(struct file *file)
1212{
1213 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1214 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(fh: file->private_data);
1215
1216 mutex_lock(&jpeg->lock);
1217 v4l2_m2m_ctx_release(m2m_ctx: ctx->fh.m2m_ctx);
1218 v4l2_ctrl_handler_free(hdl: &ctx->ctrl_hdl);
1219 v4l2_fh_del(fh: &ctx->fh);
1220 v4l2_fh_exit(fh: &ctx->fh);
1221 kfree(objp: ctx);
1222 mutex_unlock(lock: &jpeg->lock);
1223 return 0;
1224}
1225
1226static const struct v4l2_file_operations mtk_jpeg_fops = {
1227 .owner = THIS_MODULE,
1228 .open = mtk_jpeg_open,
1229 .release = mtk_jpeg_release,
1230 .poll = v4l2_m2m_fop_poll,
1231 .unlocked_ioctl = video_ioctl2,
1232 .mmap = v4l2_m2m_fop_mmap,
1233};
1234
1235static void mtk_jpeg_job_timeout_work(struct work_struct *work)
1236{
1237 struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
1238 job_timeout_work.work);
1239 struct mtk_jpeg_ctx *ctx;
1240 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1241
1242 ctx = v4l2_m2m_get_curr_priv(m2m_dev: jpeg->m2m_dev);
1243 src_buf = v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1244 dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1245
1246 jpeg->variant->hw_reset(jpeg->reg_base);
1247
1248 pm_runtime_put(dev: jpeg->dev);
1249
1250 v4l2_m2m_buf_done(buf: src_buf, state: VB2_BUF_STATE_ERROR);
1251 v4l2_m2m_buf_done(buf: dst_buf, state: VB2_BUF_STATE_ERROR);
1252 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1253}
1254
1255static int mtk_jpeg_single_core_init(struct platform_device *pdev,
1256 struct mtk_jpeg_dev *jpeg_dev)
1257{
1258 struct mtk_jpeg_dev *jpeg = jpeg_dev;
1259 int jpeg_irq, ret;
1260
1261 INIT_DELAYED_WORK(&jpeg->job_timeout_work,
1262 mtk_jpeg_job_timeout_work);
1263
1264 jpeg->reg_base = devm_platform_ioremap_resource(pdev, index: 0);
1265 if (IS_ERR(ptr: jpeg->reg_base)) {
1266 ret = PTR_ERR(ptr: jpeg->reg_base);
1267 return ret;
1268 }
1269
1270 jpeg_irq = platform_get_irq(pdev, 0);
1271 if (jpeg_irq < 0)
1272 return jpeg_irq;
1273
1274 ret = devm_request_irq(dev: &pdev->dev,
1275 irq: jpeg_irq,
1276 handler: jpeg->variant->irq_handler,
1277 irqflags: 0,
1278 devname: pdev->name, dev_id: jpeg);
1279 if (ret) {
1280 dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n",
1281 jpeg_irq, ret);
1282 return ret;
1283 }
1284
1285 ret = devm_clk_bulk_get(dev: jpeg->dev,
1286 num_clks: jpeg->variant->num_clks,
1287 clks: jpeg->variant->clks);
1288 if (ret) {
1289 dev_err(&pdev->dev, "Failed to init clk\n");
1290 return ret;
1291 }
1292
1293 return 0;
1294}
1295
1296static int mtk_jpeg_probe(struct platform_device *pdev)
1297{
1298 struct mtk_jpeg_dev *jpeg;
1299 struct device_node *child;
1300 int num_child = 0;
1301 int ret;
1302
1303 jpeg = devm_kzalloc(dev: &pdev->dev, size: sizeof(*jpeg), GFP_KERNEL);
1304 if (!jpeg)
1305 return -ENOMEM;
1306
1307 mutex_init(&jpeg->lock);
1308 spin_lock_init(&jpeg->hw_lock);
1309 jpeg->dev = &pdev->dev;
1310 jpeg->variant = of_device_get_match_data(dev: jpeg->dev);
1311
1312 platform_set_drvdata(pdev, data: jpeg);
1313
1314 ret = devm_of_platform_populate(dev: &pdev->dev);
1315 if (ret) {
1316 v4l2_err(&jpeg->v4l2_dev, "Master of platform populate failed.");
1317 return -EINVAL;
1318 }
1319
1320 if (!jpeg->variant->multi_core) {
1321 ret = mtk_jpeg_single_core_init(pdev, jpeg_dev: jpeg);
1322 if (ret) {
1323 v4l2_err(&jpeg->v4l2_dev, "mtk_jpeg_single_core_init failed.");
1324 return -EINVAL;
1325 }
1326 } else {
1327 init_waitqueue_head(&jpeg->hw_wq);
1328
1329 for_each_child_of_node(pdev->dev.of_node, child)
1330 num_child++;
1331
1332 atomic_set(v: &jpeg->hw_rdy, i: num_child);
1333 atomic_set(v: &jpeg->hw_index, i: 0);
1334
1335 jpeg->workqueue = alloc_ordered_workqueue(MTK_JPEG_NAME,
1336 WQ_MEM_RECLAIM
1337 | WQ_FREEZABLE);
1338 if (!jpeg->workqueue)
1339 return -EINVAL;
1340 }
1341
1342 ret = v4l2_device_register(dev: &pdev->dev, v4l2_dev: &jpeg->v4l2_dev);
1343 if (ret) {
1344 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1345 return -EINVAL;
1346 }
1347
1348 jpeg->m2m_dev = v4l2_m2m_init(m2m_ops: jpeg->variant->m2m_ops);
1349
1350 if (IS_ERR(ptr: jpeg->m2m_dev)) {
1351 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1352 ret = PTR_ERR(ptr: jpeg->m2m_dev);
1353 goto err_m2m_init;
1354 }
1355
1356 jpeg->vdev = video_device_alloc();
1357 if (!jpeg->vdev) {
1358 ret = -ENOMEM;
1359 goto err_vfd_jpeg_alloc;
1360 }
1361 snprintf(buf: jpeg->vdev->name, size: sizeof(jpeg->vdev->name),
1362 fmt: "%s", jpeg->variant->dev_name);
1363 jpeg->vdev->fops = &mtk_jpeg_fops;
1364 jpeg->vdev->ioctl_ops = jpeg->variant->ioctl_ops;
1365 jpeg->vdev->minor = -1;
1366 jpeg->vdev->release = video_device_release;
1367 jpeg->vdev->lock = &jpeg->lock;
1368 jpeg->vdev->v4l2_dev = &jpeg->v4l2_dev;
1369 jpeg->vdev->vfl_dir = VFL_DIR_M2M;
1370 jpeg->vdev->device_caps = V4L2_CAP_STREAMING |
1371 V4L2_CAP_VIDEO_M2M_MPLANE;
1372
1373 ret = video_register_device(vdev: jpeg->vdev, type: VFL_TYPE_VIDEO, nr: -1);
1374 if (ret) {
1375 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1376 goto err_vfd_jpeg_register;
1377 }
1378
1379 video_set_drvdata(vdev: jpeg->vdev, data: jpeg);
1380 v4l2_info(&jpeg->v4l2_dev,
1381 "%s device registered as /dev/video%d (%d,%d)\n",
1382 jpeg->variant->dev_name, jpeg->vdev->num,
1383 VIDEO_MAJOR, jpeg->vdev->minor);
1384
1385 pm_runtime_enable(dev: &pdev->dev);
1386
1387 return 0;
1388
1389err_vfd_jpeg_register:
1390 video_device_release(vdev: jpeg->vdev);
1391
1392err_vfd_jpeg_alloc:
1393 v4l2_m2m_release(m2m_dev: jpeg->m2m_dev);
1394
1395err_m2m_init:
1396 v4l2_device_unregister(v4l2_dev: &jpeg->v4l2_dev);
1397
1398 return ret;
1399}
1400
1401static void mtk_jpeg_remove(struct platform_device *pdev)
1402{
1403 struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
1404
1405 pm_runtime_disable(dev: &pdev->dev);
1406 video_unregister_device(vdev: jpeg->vdev);
1407 v4l2_m2m_release(m2m_dev: jpeg->m2m_dev);
1408 v4l2_device_unregister(v4l2_dev: &jpeg->v4l2_dev);
1409}
1410
1411static __maybe_unused int mtk_jpeg_pm_suspend(struct device *dev)
1412{
1413 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1414
1415 mtk_jpeg_clk_off(jpeg);
1416
1417 return 0;
1418}
1419
1420static __maybe_unused int mtk_jpeg_pm_resume(struct device *dev)
1421{
1422 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1423
1424 mtk_jpeg_clk_on(jpeg);
1425
1426 return 0;
1427}
1428
1429static __maybe_unused int mtk_jpeg_suspend(struct device *dev)
1430{
1431 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1432
1433 v4l2_m2m_suspend(m2m_dev: jpeg->m2m_dev);
1434 return pm_runtime_force_suspend(dev);
1435}
1436
1437static __maybe_unused int mtk_jpeg_resume(struct device *dev)
1438{
1439 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1440 int ret;
1441
1442 ret = pm_runtime_force_resume(dev);
1443 if (ret < 0)
1444 return ret;
1445
1446 v4l2_m2m_resume(m2m_dev: jpeg->m2m_dev);
1447 return ret;
1448}
1449
1450static const struct dev_pm_ops mtk_jpeg_pm_ops = {
1451 SET_SYSTEM_SLEEP_PM_OPS(mtk_jpeg_suspend, mtk_jpeg_resume)
1452 SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL)
1453};
1454
1455static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx)
1456{
1457 struct mtk_jpegenc_comp_dev *comp_jpeg;
1458 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1459 unsigned long flags;
1460 int hw_id = -1;
1461 int i;
1462
1463 spin_lock_irqsave(&jpeg->hw_lock, flags);
1464 for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) {
1465 comp_jpeg = jpeg->enc_hw_dev[i];
1466 if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
1467 hw_id = i;
1468 comp_jpeg->hw_state = MTK_JPEG_HW_BUSY;
1469 break;
1470 }
1471 }
1472 spin_unlock_irqrestore(lock: &jpeg->hw_lock, flags);
1473
1474 return hw_id;
1475}
1476
1477static int mtk_jpegenc_set_hw_param(struct mtk_jpeg_ctx *ctx,
1478 int hw_id,
1479 struct vb2_v4l2_buffer *src_buf,
1480 struct vb2_v4l2_buffer *dst_buf)
1481{
1482 struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg->enc_hw_dev[hw_id];
1483
1484 jpeg->hw_param.curr_ctx = ctx;
1485 jpeg->hw_param.src_buffer = src_buf;
1486 jpeg->hw_param.dst_buffer = dst_buf;
1487
1488 return 0;
1489}
1490
1491static int mtk_jpegenc_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id)
1492{
1493 unsigned long flags;
1494
1495 spin_lock_irqsave(&jpeg->hw_lock, flags);
1496 jpeg->enc_hw_dev[hw_id]->hw_state = MTK_JPEG_HW_IDLE;
1497 spin_unlock_irqrestore(lock: &jpeg->hw_lock, flags);
1498
1499 return 0;
1500}
1501
1502static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx)
1503{
1504 struct mtk_jpegdec_comp_dev *comp_jpeg;
1505 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1506 unsigned long flags;
1507 int hw_id = -1;
1508 int i;
1509
1510 spin_lock_irqsave(&jpeg->hw_lock, flags);
1511 for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) {
1512 comp_jpeg = jpeg->dec_hw_dev[i];
1513 if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
1514 hw_id = i;
1515 comp_jpeg->hw_state = MTK_JPEG_HW_BUSY;
1516 break;
1517 }
1518 }
1519 spin_unlock_irqrestore(lock: &jpeg->hw_lock, flags);
1520
1521 return hw_id;
1522}
1523
1524static int mtk_jpegdec_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id)
1525{
1526 unsigned long flags;
1527
1528 spin_lock_irqsave(&jpeg->hw_lock, flags);
1529 jpeg->dec_hw_dev[hw_id]->hw_state =
1530 MTK_JPEG_HW_IDLE;
1531 spin_unlock_irqrestore(lock: &jpeg->hw_lock, flags);
1532
1533 return 0;
1534}
1535
1536static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx,
1537 int hw_id,
1538 struct vb2_v4l2_buffer *src_buf,
1539 struct vb2_v4l2_buffer *dst_buf)
1540{
1541 struct mtk_jpegdec_comp_dev *jpeg =
1542 ctx->jpeg->dec_hw_dev[hw_id];
1543
1544 jpeg->hw_param.curr_ctx = ctx;
1545 jpeg->hw_param.src_buffer = src_buf;
1546 jpeg->hw_param.dst_buffer = dst_buf;
1547
1548 return 0;
1549}
1550
1551static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
1552{
1553 struct mtk_jpeg_ctx *ctx;
1554 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1555 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1556 u32 result_size;
1557
1558 ctx = v4l2_m2m_get_curr_priv(m2m_dev: jpeg->m2m_dev);
1559 if (!ctx) {
1560 v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1561 return IRQ_HANDLED;
1562 }
1563
1564 src_buf = v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1565 dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1566
1567 result_size = mtk_jpeg_enc_get_file_size(base: jpeg->reg_base);
1568 vb2_set_plane_payload(vb: &dst_buf->vb2_buf, plane_no: 0, size: result_size);
1569
1570 buf_state = VB2_BUF_STATE_DONE;
1571
1572 v4l2_m2m_buf_done(buf: src_buf, state: buf_state);
1573 v4l2_m2m_buf_done(buf: dst_buf, state: buf_state);
1574 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1575 pm_runtime_put(dev: ctx->jpeg->dev);
1576 return IRQ_HANDLED;
1577}
1578
1579static void mtk_jpegenc_worker(struct work_struct *work)
1580{
1581 struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX];
1582 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1583 struct mtk_jpeg_src_buf *jpeg_dst_buf;
1584 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1585 int ret, i, hw_id = 0;
1586 unsigned long flags;
1587
1588 struct mtk_jpeg_ctx *ctx = container_of(work,
1589 struct mtk_jpeg_ctx,
1590 jpeg_work);
1591 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1592
1593 for (i = 0; i < MTK_JPEGENC_HW_MAX; i++)
1594 comp_jpeg[i] = jpeg->enc_hw_dev[i];
1595 i = 0;
1596
1597retry_select:
1598 hw_id = mtk_jpegenc_get_hw(ctx);
1599 if (hw_id < 0) {
1600 ret = wait_event_interruptible(jpeg->hw_wq,
1601 atomic_read(&jpeg->hw_rdy) > 0);
1602 if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) {
1603 dev_err(jpeg->dev, "%s : %d, all HW are busy\n",
1604 __func__, __LINE__);
1605 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1606 return;
1607 }
1608
1609 goto retry_select;
1610 }
1611
1612 atomic_dec(v: &jpeg->hw_rdy);
1613 src_buf = v4l2_m2m_next_src_buf(m2m_ctx: ctx->fh.m2m_ctx);
1614 if (!src_buf)
1615 goto getbuf_fail;
1616
1617 dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx: ctx->fh.m2m_ctx);
1618 if (!dst_buf)
1619 goto getbuf_fail;
1620
1621 v4l2_m2m_buf_copy_metadata(out_vb: src_buf, cap_vb: dst_buf, copy_frame_flags: true);
1622
1623 mtk_jpegenc_set_hw_param(ctx, hw_id, src_buf, dst_buf);
1624 ret = pm_runtime_get_sync(dev: comp_jpeg[hw_id]->dev);
1625 if (ret < 0) {
1626 dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n",
1627 __func__, __LINE__);
1628 goto enc_end;
1629 }
1630
1631 ret = clk_prepare_enable(clk: comp_jpeg[hw_id]->venc_clk.clks->clk);
1632 if (ret) {
1633 dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n",
1634 __func__, __LINE__);
1635 goto enc_end;
1636 }
1637
1638 v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1639 v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1640
1641 schedule_delayed_work(dwork: &comp_jpeg[hw_id]->job_timeout_work,
1642 delay: msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
1643
1644 spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
1645 jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(vb: &dst_buf->vb2_buf);
1646 jpeg_dst_buf->curr_ctx = ctx;
1647 jpeg_dst_buf->frame_num = ctx->total_frame_num;
1648 ctx->total_frame_num++;
1649 mtk_jpeg_enc_reset(base: comp_jpeg[hw_id]->reg_base);
1650 mtk_jpeg_set_enc_dst(ctx,
1651 base: comp_jpeg[hw_id]->reg_base,
1652 dst_buf: &dst_buf->vb2_buf);
1653 mtk_jpeg_set_enc_src(ctx,
1654 base: comp_jpeg[hw_id]->reg_base,
1655 src_buf: &src_buf->vb2_buf);
1656 mtk_jpeg_set_enc_params(ctx, base: comp_jpeg[hw_id]->reg_base);
1657 mtk_jpeg_enc_start(enc_reg_base: comp_jpeg[hw_id]->reg_base);
1658 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1659 spin_unlock_irqrestore(lock: &comp_jpeg[hw_id]->hw_lock, flags);
1660
1661 return;
1662
1663enc_end:
1664 v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1665 v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1666 v4l2_m2m_buf_done(buf: src_buf, state: buf_state);
1667 v4l2_m2m_buf_done(buf: dst_buf, state: buf_state);
1668getbuf_fail:
1669 atomic_inc(v: &jpeg->hw_rdy);
1670 mtk_jpegenc_put_hw(jpeg, hw_id);
1671 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1672}
1673
1674static void mtk_jpegdec_worker(struct work_struct *work)
1675{
1676 struct mtk_jpeg_ctx *ctx = container_of(work, struct mtk_jpeg_ctx,
1677 jpeg_work);
1678 struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX];
1679 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1680 struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf;
1681 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1682 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1683 int ret, i, hw_id = 0;
1684 struct mtk_jpeg_bs bs;
1685 struct mtk_jpeg_fb fb;
1686 unsigned long flags;
1687
1688 for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++)
1689 comp_jpeg[i] = jpeg->dec_hw_dev[i];
1690 i = 0;
1691
1692retry_select:
1693 hw_id = mtk_jpegdec_get_hw(ctx);
1694 if (hw_id < 0) {
1695 ret = wait_event_interruptible_timeout(jpeg->hw_wq,
1696 atomic_read(&jpeg->hw_rdy) > 0,
1697 MTK_JPEG_HW_TIMEOUT_MSEC);
1698 if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) {
1699 dev_err(jpeg->dev, "%s : %d, all HW are busy\n",
1700 __func__, __LINE__);
1701 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1702 return;
1703 }
1704
1705 goto retry_select;
1706 }
1707
1708 atomic_dec(v: &jpeg->hw_rdy);
1709 src_buf = v4l2_m2m_next_src_buf(m2m_ctx: ctx->fh.m2m_ctx);
1710 if (!src_buf)
1711 goto getbuf_fail;
1712
1713 dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx: ctx->fh.m2m_ctx);
1714 if (!dst_buf)
1715 goto getbuf_fail;
1716
1717 v4l2_m2m_buf_copy_metadata(out_vb: src_buf, cap_vb: dst_buf, copy_frame_flags: true);
1718 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb: &src_buf->vb2_buf);
1719 jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(vb: &dst_buf->vb2_buf);
1720
1721 if (mtk_jpeg_check_resolution_change(ctx,
1722 param: &jpeg_src_buf->dec_param)) {
1723 mtk_jpeg_queue_src_chg_event(ctx);
1724 ctx->state = MTK_JPEG_SOURCE_CHANGE;
1725 goto getbuf_fail;
1726 }
1727
1728 jpeg_src_buf->curr_ctx = ctx;
1729 jpeg_src_buf->frame_num = ctx->total_frame_num;
1730 jpeg_dst_buf->curr_ctx = ctx;
1731 jpeg_dst_buf->frame_num = ctx->total_frame_num;
1732
1733 mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
1734 ret = pm_runtime_get_sync(dev: comp_jpeg[hw_id]->dev);
1735 if (ret < 0) {
1736 dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n",
1737 __func__, __LINE__);
1738 goto dec_end;
1739 }
1740
1741 ret = clk_prepare_enable(clk: comp_jpeg[hw_id]->jdec_clk.clks->clk);
1742 if (ret) {
1743 dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n",
1744 __func__, __LINE__);
1745 goto clk_end;
1746 }
1747
1748 v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1749 v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1750
1751 mtk_jpeg_set_dec_src(ctx, src_buf: &src_buf->vb2_buf, bs: &bs);
1752 if (mtk_jpeg_set_dec_dst(ctx,
1753 param: &jpeg_src_buf->dec_param,
1754 dst_buf: &dst_buf->vb2_buf, fb: &fb)) {
1755 dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n",
1756 __func__, __LINE__);
1757 goto setdst_end;
1758 }
1759
1760 schedule_delayed_work(dwork: &comp_jpeg[hw_id]->job_timeout_work,
1761 delay: msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
1762
1763 spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
1764 ctx->total_frame_num++;
1765 mtk_jpeg_dec_reset(dec_reg_base: comp_jpeg[hw_id]->reg_base);
1766 mtk_jpeg_dec_set_config(base: comp_jpeg[hw_id]->reg_base,
1767 cfg: &jpeg_src_buf->dec_param,
1768 bitstream_size: jpeg_src_buf->bs_size,
1769 bs: &bs,
1770 fb: &fb);
1771 mtk_jpeg_dec_start(dec_reg_base: comp_jpeg[hw_id]->reg_base);
1772 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1773 spin_unlock_irqrestore(lock: &comp_jpeg[hw_id]->hw_lock, flags);
1774
1775 return;
1776
1777setdst_end:
1778 clk_disable_unprepare(clk: comp_jpeg[hw_id]->jdec_clk.clks->clk);
1779clk_end:
1780 pm_runtime_put(dev: comp_jpeg[hw_id]->dev);
1781dec_end:
1782 v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1783 v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1784 v4l2_m2m_buf_done(buf: src_buf, state: buf_state);
1785 v4l2_m2m_buf_done(buf: dst_buf, state: buf_state);
1786getbuf_fail:
1787 atomic_inc(v: &jpeg->hw_rdy);
1788 mtk_jpegdec_put_hw(jpeg, hw_id);
1789 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1790}
1791
1792static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv)
1793{
1794 struct mtk_jpeg_dev *jpeg = priv;
1795 u32 irq_status;
1796 irqreturn_t ret = IRQ_NONE;
1797
1798 cancel_delayed_work(dwork: &jpeg->job_timeout_work);
1799
1800 irq_status = readl(addr: jpeg->reg_base + JPEG_ENC_INT_STS) &
1801 JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
1802 if (irq_status)
1803 writel(val: 0, addr: jpeg->reg_base + JPEG_ENC_INT_STS);
1804
1805 if (!(irq_status & JPEG_ENC_INT_STATUS_DONE))
1806 return ret;
1807
1808 ret = mtk_jpeg_enc_done(jpeg);
1809 return ret;
1810}
1811
1812static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
1813{
1814 struct mtk_jpeg_dev *jpeg = priv;
1815 struct mtk_jpeg_ctx *ctx;
1816 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1817 struct mtk_jpeg_src_buf *jpeg_src_buf;
1818 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1819 u32 dec_irq_ret;
1820 u32 dec_ret;
1821 int i;
1822
1823 cancel_delayed_work(dwork: &jpeg->job_timeout_work);
1824
1825 dec_ret = mtk_jpeg_dec_get_int_status(dec_reg_base: jpeg->reg_base);
1826 dec_irq_ret = mtk_jpeg_dec_enum_result(irq_result: dec_ret);
1827 ctx = v4l2_m2m_get_curr_priv(m2m_dev: jpeg->m2m_dev);
1828 if (!ctx) {
1829 v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1830 return IRQ_HANDLED;
1831 }
1832
1833 src_buf = v4l2_m2m_src_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1834 dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx: ctx->fh.m2m_ctx);
1835 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb: &src_buf->vb2_buf);
1836
1837 if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)
1838 mtk_jpeg_dec_reset(dec_reg_base: jpeg->reg_base);
1839
1840 if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) {
1841 dev_err(jpeg->dev, "decode failed\n");
1842 goto dec_end;
1843 }
1844
1845 for (i = 0; i < dst_buf->vb2_buf.num_planes; i++)
1846 vb2_set_plane_payload(vb: &dst_buf->vb2_buf, plane_no: i,
1847 size: jpeg_src_buf->dec_param.comp_size[i]);
1848
1849 buf_state = VB2_BUF_STATE_DONE;
1850
1851dec_end:
1852 v4l2_m2m_buf_done(buf: src_buf, state: buf_state);
1853 v4l2_m2m_buf_done(buf: dst_buf, state: buf_state);
1854 v4l2_m2m_job_finish(m2m_dev: jpeg->m2m_dev, m2m_ctx: ctx->fh.m2m_ctx);
1855 pm_runtime_put(dev: ctx->jpeg->dev);
1856 return IRQ_HANDLED;
1857}
1858
1859static struct clk_bulk_data mtk_jpeg_clocks[] = {
1860 { .id = "jpgenc" },
1861};
1862
1863static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = {
1864 { .id = "jpgdec-smi" },
1865 { .id = "jpgdec" },
1866};
1867
1868static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = {
1869 .clks = mt8173_jpeg_dec_clocks,
1870 .num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks),
1871 .formats = mtk_jpeg_dec_formats,
1872 .num_formats = MTK_JPEG_DEC_NUM_FORMATS,
1873 .qops = &mtk_jpeg_dec_qops,
1874 .irq_handler = mtk_jpeg_dec_irq,
1875 .hw_reset = mtk_jpeg_dec_reset,
1876 .m2m_ops = &mtk_jpeg_dec_m2m_ops,
1877 .dev_name = "mtk-jpeg-dec",
1878 .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
1879 .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1880 .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
1881};
1882
1883static const struct mtk_jpeg_variant mtk_jpeg_drvdata = {
1884 .clks = mtk_jpeg_clocks,
1885 .num_clks = ARRAY_SIZE(mtk_jpeg_clocks),
1886 .formats = mtk_jpeg_enc_formats,
1887 .num_formats = MTK_JPEG_ENC_NUM_FORMATS,
1888 .qops = &mtk_jpeg_enc_qops,
1889 .irq_handler = mtk_jpeg_enc_irq,
1890 .hw_reset = mtk_jpeg_enc_reset,
1891 .m2m_ops = &mtk_jpeg_enc_m2m_ops,
1892 .dev_name = "mtk-jpeg-enc",
1893 .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
1894 .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
1895 .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1896 .multi_core = false,
1897};
1898
1899static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
1900 .formats = mtk_jpeg_enc_formats,
1901 .num_formats = MTK_JPEG_ENC_NUM_FORMATS,
1902 .qops = &mtk_jpeg_enc_qops,
1903 .m2m_ops = &mtk_jpeg_multicore_enc_m2m_ops,
1904 .dev_name = "mtk-jpeg-enc",
1905 .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
1906 .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
1907 .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1908 .multi_core = true,
1909 .jpeg_worker = mtk_jpegenc_worker,
1910};
1911
1912static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
1913 .formats = mtk_jpeg_dec_formats,
1914 .num_formats = MTK_JPEG_DEC_NUM_FORMATS,
1915 .qops = &mtk_jpeg_dec_qops,
1916 .m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops,
1917 .dev_name = "mtk-jpeg-dec",
1918 .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
1919 .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1920 .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
1921 .multi_core = true,
1922 .jpeg_worker = mtk_jpegdec_worker,
1923};
1924
1925static const struct of_device_id mtk_jpeg_match[] = {
1926 {
1927 .compatible = "mediatek,mt8173-jpgdec",
1928 .data = &mt8173_jpeg_drvdata,
1929 },
1930 {
1931 .compatible = "mediatek,mt2701-jpgdec",
1932 .data = &mt8173_jpeg_drvdata,
1933 },
1934 {
1935 .compatible = "mediatek,mtk-jpgenc",
1936 .data = &mtk_jpeg_drvdata,
1937 },
1938 {
1939 .compatible = "mediatek,mt8195-jpgenc",
1940 .data = &mtk8195_jpegenc_drvdata,
1941 },
1942 {
1943 .compatible = "mediatek,mt8195-jpgdec",
1944 .data = &mtk8195_jpegdec_drvdata,
1945 },
1946 {},
1947};
1948
1949MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
1950
1951static struct platform_driver mtk_jpeg_driver = {
1952 .probe = mtk_jpeg_probe,
1953 .remove_new = mtk_jpeg_remove,
1954 .driver = {
1955 .name = MTK_JPEG_NAME,
1956 .of_match_table = mtk_jpeg_match,
1957 .pm = &mtk_jpeg_pm_ops,
1958 },
1959};
1960
1961module_platform_driver(mtk_jpeg_driver);
1962
1963MODULE_DESCRIPTION("MediaTek JPEG codec driver");
1964MODULE_LICENSE("GPL v2");
1965

source code of linux/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c