1
2
3
4
5
6
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#include <soc/mediatek/smi.h>
26
27#include "mtk_jpeg_enc_hw.h"
28#include "mtk_jpeg_dec_hw.h"
29#include "mtk_jpeg_core.h"
30#include "mtk_jpeg_dec_parse.h"
31
32static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = {
33 {
34 .fourcc = V4L2_PIX_FMT_JPEG,
35 .colplanes = 1,
36 .flags = MTK_JPEG_FMT_FLAG_CAPTURE,
37 },
38 {
39 .fourcc = V4L2_PIX_FMT_NV12M,
40 .hw_format = JPEG_ENC_YUV_FORMAT_NV12,
41 .h_sample = {4, 4},
42 .v_sample = {4, 2},
43 .colplanes = 2,
44 .h_align = 4,
45 .v_align = 4,
46 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
47 },
48 {
49 .fourcc = V4L2_PIX_FMT_NV21M,
50 .hw_format = JEPG_ENC_YUV_FORMAT_NV21,
51 .h_sample = {4, 4},
52 .v_sample = {4, 2},
53 .colplanes = 2,
54 .h_align = 4,
55 .v_align = 4,
56 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
57 },
58 {
59 .fourcc = V4L2_PIX_FMT_YUYV,
60 .hw_format = JPEG_ENC_YUV_FORMAT_YUYV,
61 .h_sample = {8},
62 .v_sample = {4},
63 .colplanes = 1,
64 .h_align = 5,
65 .v_align = 3,
66 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
67 },
68 {
69 .fourcc = V4L2_PIX_FMT_YVYU,
70 .hw_format = JPEG_ENC_YUV_FORMAT_YVYU,
71 .h_sample = {8},
72 .v_sample = {4},
73 .colplanes = 1,
74 .h_align = 5,
75 .v_align = 3,
76 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
77 },
78};
79
80static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = {
81 {
82 .fourcc = V4L2_PIX_FMT_JPEG,
83 .colplanes = 1,
84 .flags = MTK_JPEG_FMT_FLAG_OUTPUT,
85 },
86 {
87 .fourcc = V4L2_PIX_FMT_YUV420M,
88 .h_sample = {4, 2, 2},
89 .v_sample = {4, 2, 2},
90 .colplanes = 3,
91 .h_align = 5,
92 .v_align = 4,
93 .flags = MTK_JPEG_FMT_FLAG_CAPTURE,
94 },
95 {
96 .fourcc = V4L2_PIX_FMT_YUV422M,
97 .h_sample = {4, 2, 2},
98 .v_sample = {4, 4, 4},
99 .colplanes = 3,
100 .h_align = 5,
101 .v_align = 3,
102 .flags = MTK_JPEG_FMT_FLAG_CAPTURE,
103 },
104};
105
106#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)
107#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
108
109struct mtk_jpeg_src_buf {
110 struct vb2_v4l2_buffer b;
111 struct list_head list;
112 struct mtk_jpeg_dec_param dec_param;
113};
114
115static int debug;
116module_param(debug, int, 0644);
117
118static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
119{
120 return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl);
121}
122
123static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh)
124{
125 return container_of(fh, struct mtk_jpeg_ctx, fh);
126}
127
128static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
129 struct vb2_buffer *vb)
130{
131 return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b);
132}
133
134static int mtk_jpeg_querycap(struct file *file, void *priv,
135 struct v4l2_capability *cap)
136{
137 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
138
139 strscpy(cap->driver, jpeg->variant->dev_name, sizeof(cap->driver));
140 strscpy(cap->card, jpeg->variant->dev_name, sizeof(cap->card));
141 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
142 dev_name(jpeg->dev));
143
144 return 0;
145}
146
147static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl)
148{
149 struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
150
151 switch (ctrl->id) {
152 case V4L2_CID_JPEG_RESTART_INTERVAL:
153 ctx->restart_interval = ctrl->val;
154 break;
155 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
156 ctx->enc_quality = ctrl->val;
157 break;
158 case V4L2_CID_JPEG_ACTIVE_MARKER:
159 ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1;
160 break;
161 }
162
163 return 0;
164}
165
166static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = {
167 .s_ctrl = vidioc_jpeg_enc_s_ctrl,
168};
169
170static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx)
171{
172 const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops;
173 struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
174
175 v4l2_ctrl_handler_init(handler, 3);
176
177 v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100,
178 1, 0);
179 v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48,
180 100, 1, 90);
181 v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0,
182 V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0);
183
184 if (handler->error) {
185 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
186 return handler->error;
187 }
188
189 v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
190
191 return 0;
192}
193
194static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
195 struct v4l2_fmtdesc *f, u32 type)
196{
197 int i, num = 0;
198
199 for (i = 0; i < n; ++i) {
200 if (mtk_jpeg_formats[i].flags & type) {
201 if (num == f->index)
202 break;
203 ++num;
204 }
205 }
206
207 if (i >= n)
208 return -EINVAL;
209
210 f->pixelformat = mtk_jpeg_formats[i].fourcc;
211
212 return 0;
213}
214
215static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
216 struct v4l2_fmtdesc *f)
217{
218 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
219 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
220
221 return mtk_jpeg_enum_fmt(jpeg->variant->formats,
222 jpeg->variant->num_formats, f,
223 MTK_JPEG_FMT_FLAG_CAPTURE);
224}
225
226static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
227 struct v4l2_fmtdesc *f)
228{
229 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
230 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
231
232 return mtk_jpeg_enum_fmt(jpeg->variant->formats,
233 jpeg->variant->num_formats, f,
234 MTK_JPEG_FMT_FLAG_OUTPUT);
235}
236
237static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx,
238 enum v4l2_buf_type type)
239{
240 if (V4L2_TYPE_IS_OUTPUT(type))
241 return &ctx->out_q;
242 return &ctx->cap_q;
243}
244
245static struct mtk_jpeg_fmt *
246mtk_jpeg_find_format(struct mtk_jpeg_fmt *mtk_jpeg_formats, int num_formats,
247 u32 pixelformat, unsigned int fmt_type)
248{
249 unsigned int k;
250 struct mtk_jpeg_fmt *fmt;
251
252 for (k = 0; k < num_formats; k++) {
253 fmt = &mtk_jpeg_formats[k];
254
255 if (fmt->fourcc == pixelformat && fmt->flags & fmt_type)
256 return fmt;
257 }
258
259 return NULL;
260}
261
262static int mtk_jpeg_try_fmt_mplane(struct v4l2_pix_format_mplane *pix_mp,
263 struct mtk_jpeg_fmt *fmt)
264{
265 int i;
266
267 pix_mp->field = V4L2_FIELD_NONE;
268
269 pix_mp->num_planes = fmt->colplanes;
270 pix_mp->pixelformat = fmt->fourcc;
271
272 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
273 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
274
275 pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT,
276 MTK_JPEG_MAX_HEIGHT);
277 pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH,
278 MTK_JPEG_MAX_WIDTH);
279
280 pfmt->bytesperline = 0;
281
282 pfmt->sizeimage = round_up(pfmt->sizeimage, 128);
283 if (pfmt->sizeimage == 0)
284 pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE;
285 return 0;
286 }
287
288
289 pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align),
290 MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT);
291 pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align),
292 MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH);
293
294 for (i = 0; i < fmt->colplanes; i++) {
295 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
296 u32 stride = pix_mp->width * fmt->h_sample[i] / 4;
297 u32 h = pix_mp->height * fmt->v_sample[i] / 4;
298
299 pfmt->bytesperline = stride;
300 pfmt->sizeimage = stride * h;
301 }
302 return 0;
303}
304
305static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
306 struct v4l2_format *f)
307{
308 struct vb2_queue *vq;
309 struct mtk_jpeg_q_data *q_data = NULL;
310 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
311 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
312 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
313 int i;
314
315 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
316 if (!vq)
317 return -EINVAL;
318
319 q_data = mtk_jpeg_get_q_data(ctx, f->type);
320
321 pix_mp->width = q_data->pix_mp.width;
322 pix_mp->height = q_data->pix_mp.height;
323 pix_mp->field = V4L2_FIELD_NONE;
324 pix_mp->pixelformat = q_data->fmt->fourcc;
325 pix_mp->num_planes = q_data->fmt->colplanes;
326 pix_mp->colorspace = q_data->pix_mp.colorspace;
327 pix_mp->ycbcr_enc = q_data->pix_mp.ycbcr_enc;
328 pix_mp->xfer_func = q_data->pix_mp.xfer_func;
329 pix_mp->quantization = q_data->pix_mp.quantization;
330
331 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) g_fmt:%c%c%c%c wxh:%ux%u\n",
332 f->type,
333 (pix_mp->pixelformat & 0xff),
334 (pix_mp->pixelformat >> 8 & 0xff),
335 (pix_mp->pixelformat >> 16 & 0xff),
336 (pix_mp->pixelformat >> 24 & 0xff),
337 pix_mp->width, pix_mp->height);
338
339 for (i = 0; i < pix_mp->num_planes; i++) {
340 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
341
342 pfmt->bytesperline = q_data->pix_mp.plane_fmt[i].bytesperline;
343 pfmt->sizeimage = q_data->pix_mp.plane_fmt[i].sizeimage;
344
345 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
346 "plane[%d] bpl=%u, size=%u\n",
347 i,
348 pfmt->bytesperline,
349 pfmt->sizeimage);
350 }
351 return 0;
352}
353
354static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
355 struct v4l2_format *f)
356{
357 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
358 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
359 struct mtk_jpeg_fmt *fmt;
360
361 fmt = mtk_jpeg_find_format(jpeg->variant->formats,
362 jpeg->variant->num_formats,
363 f->fmt.pix_mp.pixelformat,
364 MTK_JPEG_FMT_FLAG_CAPTURE);
365 if (!fmt)
366 fmt = ctx->cap_q.fmt;
367
368 v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
369 f->type,
370 (fmt->fourcc & 0xff),
371 (fmt->fourcc >> 8 & 0xff),
372 (fmt->fourcc >> 16 & 0xff),
373 (fmt->fourcc >> 24 & 0xff));
374
375 if (ctx->state != MTK_JPEG_INIT) {
376 mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
377 return 0;
378 }
379
380 return mtk_jpeg_try_fmt_mplane(&f->fmt.pix_mp, fmt);
381}
382
383static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
384 struct v4l2_format *f)
385{
386 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
387 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
388 struct mtk_jpeg_fmt *fmt;
389
390 fmt = mtk_jpeg_find_format(jpeg->variant->formats,
391 jpeg->variant->num_formats,
392 f->fmt.pix_mp.pixelformat,
393 MTK_JPEG_FMT_FLAG_OUTPUT);
394 if (!fmt)
395 fmt = ctx->out_q.fmt;
396
397 v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
398 f->type,
399 (fmt->fourcc & 0xff),
400 (fmt->fourcc >> 8 & 0xff),
401 (fmt->fourcc >> 16 & 0xff),
402 (fmt->fourcc >> 24 & 0xff));
403
404 if (ctx->state != MTK_JPEG_INIT) {
405 mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
406 return 0;
407 }
408
409 return mtk_jpeg_try_fmt_mplane(&f->fmt.pix_mp, fmt);
410}
411
412static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx,
413 struct v4l2_format *f, unsigned int fmt_type)
414{
415 struct vb2_queue *vq;
416 struct mtk_jpeg_q_data *q_data = NULL;
417 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
418 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
419 int i;
420
421 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
422 if (!vq)
423 return -EINVAL;
424
425 q_data = mtk_jpeg_get_q_data(ctx, f->type);
426
427 if (vb2_is_busy(vq)) {
428 v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
429 return -EBUSY;
430 }
431
432 q_data->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
433 jpeg->variant->num_formats,
434 pix_mp->pixelformat, fmt_type);
435 q_data->pix_mp.width = pix_mp->width;
436 q_data->pix_mp.height = pix_mp->height;
437 q_data->enc_crop_rect.width = pix_mp->width;
438 q_data->enc_crop_rect.height = pix_mp->height;
439 q_data->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
440 q_data->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
441 q_data->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
442 q_data->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
443
444 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) s_fmt:%c%c%c%c wxh:%ux%u\n",
445 f->type,
446 (q_data->fmt->fourcc & 0xff),
447 (q_data->fmt->fourcc >> 8 & 0xff),
448 (q_data->fmt->fourcc >> 16 & 0xff),
449 (q_data->fmt->fourcc >> 24 & 0xff),
450 q_data->pix_mp.width, q_data->pix_mp.height);
451
452 for (i = 0; i < q_data->fmt->colplanes; i++) {
453 q_data->pix_mp.plane_fmt[i].bytesperline =
454 pix_mp->plane_fmt[i].bytesperline;
455 q_data->pix_mp.plane_fmt[i].sizeimage =
456 pix_mp->plane_fmt[i].sizeimage;
457
458 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
459 "plane[%d] bpl=%u, size=%u\n",
460 i, q_data->pix_mp.plane_fmt[i].bytesperline,
461 q_data->pix_mp.plane_fmt[i].sizeimage);
462 }
463
464 return 0;
465}
466
467static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
468 struct v4l2_format *f)
469{
470 int ret;
471
472 ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f);
473 if (ret)
474 return ret;
475
476 return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f,
477 MTK_JPEG_FMT_FLAG_OUTPUT);
478}
479
480static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
481 struct v4l2_format *f)
482{
483 int ret;
484
485 ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f);
486 if (ret)
487 return ret;
488
489 return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f,
490 MTK_JPEG_FMT_FLAG_CAPTURE);
491}
492
493static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx)
494{
495 static const struct v4l2_event ev_src_ch = {
496 .type = V4L2_EVENT_SOURCE_CHANGE,
497 .u.src_change.changes =
498 V4L2_EVENT_SRC_CH_RESOLUTION,
499 };
500
501 v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
502}
503
504static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
505 const struct v4l2_event_subscription *sub)
506{
507 switch (sub->type) {
508 case V4L2_EVENT_SOURCE_CHANGE:
509 return v4l2_src_change_event_subscribe(fh, sub);
510 }
511
512 return v4l2_ctrl_subscribe_event(fh, sub);
513}
514
515static int mtk_jpeg_enc_g_selection(struct file *file, void *priv,
516 struct v4l2_selection *s)
517{
518 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
519
520 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
521 return -EINVAL;
522
523 switch (s->target) {
524 case V4L2_SEL_TGT_CROP:
525 s->r = ctx->out_q.enc_crop_rect;
526 break;
527 case V4L2_SEL_TGT_CROP_BOUNDS:
528 case V4L2_SEL_TGT_CROP_DEFAULT:
529 s->r.width = ctx->out_q.pix_mp.width;
530 s->r.height = ctx->out_q.pix_mp.height;
531 s->r.left = 0;
532 s->r.top = 0;
533 break;
534 default:
535 return -EINVAL;
536 }
537 return 0;
538}
539
540static int mtk_jpeg_dec_g_selection(struct file *file, void *priv,
541 struct v4l2_selection *s)
542{
543 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
544
545 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
546 return -EINVAL;
547
548 switch (s->target) {
549 case V4L2_SEL_TGT_COMPOSE:
550 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
551 s->r.width = ctx->out_q.pix_mp.width;
552 s->r.height = ctx->out_q.pix_mp.height;
553 s->r.left = 0;
554 s->r.top = 0;
555 break;
556 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
557 case V4L2_SEL_TGT_COMPOSE_PADDED:
558 s->r.width = ctx->cap_q.pix_mp.width;
559 s->r.height = ctx->cap_q.pix_mp.height;
560 s->r.left = 0;
561 s->r.top = 0;
562 break;
563 default:
564 return -EINVAL;
565 }
566 return 0;
567}
568
569static int mtk_jpeg_enc_s_selection(struct file *file, void *priv,
570 struct v4l2_selection *s)
571{
572 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
573
574 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
575 return -EINVAL;
576
577 switch (s->target) {
578 case V4L2_SEL_TGT_CROP:
579 s->r.left = 0;
580 s->r.top = 0;
581 s->r.width = min(s->r.width, ctx->out_q.pix_mp.width);
582 s->r.height = min(s->r.height, ctx->out_q.pix_mp.height);
583 ctx->out_q.enc_crop_rect = s->r;
584 break;
585 default:
586 return -EINVAL;
587 }
588
589 return 0;
590}
591
592static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = {
593 .vidioc_querycap = mtk_jpeg_querycap,
594 .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap,
595 .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out,
596 .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane,
597 .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane,
598 .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane,
599 .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane,
600 .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane,
601 .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane,
602 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
603 .vidioc_subscribe_event = mtk_jpeg_subscribe_event,
604 .vidioc_g_selection = mtk_jpeg_enc_g_selection,
605 .vidioc_s_selection = mtk_jpeg_enc_s_selection,
606
607 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
608 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
609 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
610 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
611 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
612 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
613 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
614 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
615
616 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
617};
618
619static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = {
620 .vidioc_querycap = mtk_jpeg_querycap,
621 .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap,
622 .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out,
623 .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane,
624 .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane,
625 .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane,
626 .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane,
627 .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane,
628 .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane,
629 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
630 .vidioc_subscribe_event = mtk_jpeg_subscribe_event,
631 .vidioc_g_selection = mtk_jpeg_dec_g_selection,
632
633 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
634 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
635 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
636 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
637 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
638 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
639 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
640 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
641
642 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
643};
644
645static int mtk_jpeg_queue_setup(struct vb2_queue *q,
646 unsigned int *num_buffers,
647 unsigned int *num_planes,
648 unsigned int sizes[],
649 struct device *alloc_ctxs[])
650{
651 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
652 struct mtk_jpeg_q_data *q_data = NULL;
653 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
654 int i;
655
656 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) buf_req count=%u\n",
657 q->type, *num_buffers);
658
659 q_data = mtk_jpeg_get_q_data(ctx, q->type);
660 if (!q_data)
661 return -EINVAL;
662
663 if (*num_planes) {
664 for (i = 0; i < *num_planes; i++)
665 if (sizes[i] < q_data->pix_mp.plane_fmt[i].sizeimage)
666 return -EINVAL;
667 return 0;
668 }
669
670 *num_planes = q_data->fmt->colplanes;
671 for (i = 0; i < q_data->fmt->colplanes; i++) {
672 sizes[i] = q_data->pix_mp.plane_fmt[i].sizeimage;
673 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "sizeimage[%d]=%u\n",
674 i, sizes[i]);
675 }
676
677 return 0;
678}
679
680static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
681{
682 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
683 struct mtk_jpeg_q_data *q_data = NULL;
684 struct v4l2_plane_pix_format plane_fmt = {};
685 int i;
686
687 q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
688 if (!q_data)
689 return -EINVAL;
690
691 for (i = 0; i < q_data->fmt->colplanes; i++) {
692 plane_fmt = q_data->pix_mp.plane_fmt[i];
693 if (ctx->enable_exif &&
694 q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG)
695 vb2_set_plane_payload(vb, i, plane_fmt.sizeimage +
696 MTK_JPEG_MAX_EXIF_SIZE);
697 else
698 vb2_set_plane_payload(vb, i, plane_fmt.sizeimage);
699 }
700
701 return 0;
702}
703
704static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx,
705 struct mtk_jpeg_dec_param *param)
706{
707 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
708 struct mtk_jpeg_q_data *q_data;
709
710 q_data = &ctx->out_q;
711 if (q_data->pix_mp.width != param->pic_w ||
712 q_data->pix_mp.height != param->pic_h) {
713 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Picture size change\n");
714 return true;
715 }
716
717 q_data = &ctx->cap_q;
718 if (q_data->fmt !=
719 mtk_jpeg_find_format(jpeg->variant->formats,
720 jpeg->variant->num_formats, param->dst_fourcc,
721 MTK_JPEG_FMT_FLAG_CAPTURE)) {
722 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n");
723 return true;
724 }
725 return false;
726}
727
728static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx,
729 struct mtk_jpeg_dec_param *param)
730{
731 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
732 struct mtk_jpeg_q_data *q_data;
733 int i;
734
735 q_data = &ctx->out_q;
736 q_data->pix_mp.width = param->pic_w;
737 q_data->pix_mp.height = param->pic_h;
738
739 q_data = &ctx->cap_q;
740 q_data->pix_mp.width = param->dec_w;
741 q_data->pix_mp.height = param->dec_h;
742 q_data->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
743 jpeg->variant->num_formats,
744 param->dst_fourcc,
745 MTK_JPEG_FMT_FLAG_CAPTURE);
746
747 for (i = 0; i < q_data->fmt->colplanes; i++) {
748 q_data->pix_mp.plane_fmt[i].bytesperline = param->mem_stride[i];
749 q_data->pix_mp.plane_fmt[i].sizeimage = param->comp_size[i];
750 }
751
752 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
753 "set_parse cap:%c%c%c%c pic(%u, %u), buf(%u, %u)\n",
754 (param->dst_fourcc & 0xff),
755 (param->dst_fourcc >> 8 & 0xff),
756 (param->dst_fourcc >> 16 & 0xff),
757 (param->dst_fourcc >> 24 & 0xff),
758 param->pic_w, param->pic_h,
759 param->dec_w, param->dec_h);
760}
761
762static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb)
763{
764 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
765 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
766
767 v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
768 vb->vb2_queue->type, vb->index, vb);
769
770 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
771}
772
773static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb)
774{
775 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
776 struct mtk_jpeg_dec_param *param;
777 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
778 struct mtk_jpeg_src_buf *jpeg_src_buf;
779 bool header_valid;
780
781 v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
782 vb->vb2_queue->type, vb->index, vb);
783
784 if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
785 goto end;
786
787 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
788 param = &jpeg_src_buf->dec_param;
789 memset(param, 0, sizeof(*param));
790
791 header_valid = mtk_jpeg_parse(param, (u8 *)vb2_plane_vaddr(vb, 0),
792 vb2_get_plane_payload(vb, 0));
793 if (!header_valid) {
794 v4l2_err(&jpeg->v4l2_dev, "Header invalid.\n");
795 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
796 return;
797 }
798
799 if (ctx->state == MTK_JPEG_INIT) {
800 struct vb2_queue *dst_vq = v4l2_m2m_get_vq(
801 ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
802
803 mtk_jpeg_queue_src_chg_event(ctx);
804 mtk_jpeg_set_queue_data(ctx, param);
805 ctx->state = vb2_is_streaming(dst_vq) ?
806 MTK_JPEG_SOURCE_CHANGE : MTK_JPEG_RUNNING;
807 }
808end:
809 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
810}
811
812static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
813 enum v4l2_buf_type type)
814{
815 if (V4L2_TYPE_IS_OUTPUT(type))
816 return v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
817 else
818 return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
819}
820
821static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
822{
823 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
824 struct vb2_v4l2_buffer *vb;
825
826 while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
827 v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
828}
829
830static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
831{
832 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
833 struct vb2_v4l2_buffer *vb;
834
835
836
837
838
839
840 if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
841 V4L2_TYPE_IS_CAPTURE(q->type)) {
842 struct mtk_jpeg_src_buf *src_buf;
843
844 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
845 src_buf = mtk_jpeg_vb2_to_srcbuf(&vb->vb2_buf);
846 mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param);
847 ctx->state = MTK_JPEG_RUNNING;
848 } else if (V4L2_TYPE_IS_OUTPUT(q->type)) {
849 ctx->state = MTK_JPEG_INIT;
850 }
851
852 while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
853 v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
854}
855
856static const struct vb2_ops mtk_jpeg_dec_qops = {
857 .queue_setup = mtk_jpeg_queue_setup,
858 .buf_prepare = mtk_jpeg_buf_prepare,
859 .buf_queue = mtk_jpeg_dec_buf_queue,
860 .wait_prepare = vb2_ops_wait_prepare,
861 .wait_finish = vb2_ops_wait_finish,
862 .stop_streaming = mtk_jpeg_dec_stop_streaming,
863};
864
865static const struct vb2_ops mtk_jpeg_enc_qops = {
866 .queue_setup = mtk_jpeg_queue_setup,
867 .buf_prepare = mtk_jpeg_buf_prepare,
868 .buf_queue = mtk_jpeg_enc_buf_queue,
869 .wait_prepare = vb2_ops_wait_prepare,
870 .wait_finish = vb2_ops_wait_finish,
871 .stop_streaming = mtk_jpeg_enc_stop_streaming,
872};
873
874static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx,
875 struct vb2_buffer *src_buf,
876 struct mtk_jpeg_bs *bs)
877{
878 bs->str_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
879 bs->end_addr = bs->str_addr +
880 round_up(vb2_get_plane_payload(src_buf, 0), 16);
881 bs->size = round_up(vb2_plane_size(src_buf, 0), 128);
882}
883
884static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,
885 struct mtk_jpeg_dec_param *param,
886 struct vb2_buffer *dst_buf,
887 struct mtk_jpeg_fb *fb)
888{
889 int i;
890
891 if (param->comp_num != dst_buf->num_planes) {
892 dev_err(ctx->jpeg->dev, "plane number mismatch (%u != %u)\n",
893 param->comp_num, dst_buf->num_planes);
894 return -EINVAL;
895 }
896
897 for (i = 0; i < dst_buf->num_planes; i++) {
898 if (vb2_plane_size(dst_buf, i) < param->comp_size[i]) {
899 dev_err(ctx->jpeg->dev,
900 "buffer size is underflow (%lu < %u)\n",
901 vb2_plane_size(dst_buf, 0),
902 param->comp_size[i]);
903 return -EINVAL;
904 }
905 fb->plane_addr[i] = vb2_dma_contig_plane_dma_addr(dst_buf, i);
906 }
907
908 return 0;
909}
910
911static void mtk_jpeg_enc_device_run(void *priv)
912{
913 struct mtk_jpeg_ctx *ctx = priv;
914 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
915 struct vb2_v4l2_buffer *src_buf, *dst_buf;
916 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
917 unsigned long flags;
918 int ret;
919
920 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
921 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
922
923 ret = pm_runtime_get_sync(jpeg->dev);
924 if (ret < 0)
925 goto enc_end;
926
927 schedule_delayed_work(&jpeg->job_timeout_work,
928 msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
929
930 spin_lock_irqsave(&jpeg->hw_lock, flags);
931
932
933
934
935
936 mtk_jpeg_enc_reset(jpeg->reg_base);
937
938 mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf);
939 mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf);
940 mtk_jpeg_set_enc_params(ctx, jpeg->reg_base);
941 mtk_jpeg_enc_start(jpeg->reg_base);
942 spin_unlock_irqrestore(&jpeg->hw_lock, flags);
943 return;
944
945enc_end:
946 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
947 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
948 v4l2_m2m_buf_done(src_buf, buf_state);
949 v4l2_m2m_buf_done(dst_buf, buf_state);
950 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
951}
952
953static void mtk_jpeg_dec_device_run(void *priv)
954{
955 struct mtk_jpeg_ctx *ctx = priv;
956 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
957 struct vb2_v4l2_buffer *src_buf, *dst_buf;
958 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
959 unsigned long flags;
960 struct mtk_jpeg_src_buf *jpeg_src_buf;
961 struct mtk_jpeg_bs bs;
962 struct mtk_jpeg_fb fb;
963 int ret;
964
965 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
966 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
967 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
968
969 if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) {
970 mtk_jpeg_queue_src_chg_event(ctx);
971 ctx->state = MTK_JPEG_SOURCE_CHANGE;
972 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
973 return;
974 }
975
976 ret = pm_runtime_get_sync(jpeg->dev);
977 if (ret < 0)
978 goto dec_end;
979
980 schedule_delayed_work(&jpeg->job_timeout_work,
981 msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
982
983 mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
984 if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb))
985 goto dec_end;
986
987 spin_lock_irqsave(&jpeg->hw_lock, flags);
988 mtk_jpeg_dec_reset(jpeg->reg_base);
989 mtk_jpeg_dec_set_config(jpeg->reg_base,
990 &jpeg_src_buf->dec_param, &bs, &fb);
991
992 mtk_jpeg_dec_start(jpeg->reg_base);
993 spin_unlock_irqrestore(&jpeg->hw_lock, flags);
994 return;
995
996dec_end:
997 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
998 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
999 v4l2_m2m_buf_done(src_buf, buf_state);
1000 v4l2_m2m_buf_done(dst_buf, buf_state);
1001 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1002}
1003
1004static int mtk_jpeg_dec_job_ready(void *priv)
1005{
1006 struct mtk_jpeg_ctx *ctx = priv;
1007
1008 return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0;
1009}
1010
1011static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = {
1012 .device_run = mtk_jpeg_enc_device_run,
1013};
1014
1015static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = {
1016 .device_run = mtk_jpeg_dec_device_run,
1017 .job_ready = mtk_jpeg_dec_job_ready,
1018};
1019
1020static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
1021 struct vb2_queue *dst_vq)
1022{
1023 struct mtk_jpeg_ctx *ctx = priv;
1024 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1025 int ret;
1026
1027 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1028 src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1029 src_vq->drv_priv = ctx;
1030 src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
1031 src_vq->ops = jpeg->variant->qops;
1032 src_vq->mem_ops = &vb2_dma_contig_memops;
1033 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1034 src_vq->lock = &ctx->jpeg->lock;
1035 src_vq->dev = ctx->jpeg->dev;
1036 ret = vb2_queue_init(src_vq);
1037 if (ret)
1038 return ret;
1039
1040 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1041 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1042 dst_vq->drv_priv = ctx;
1043 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1044 dst_vq->ops = jpeg->variant->qops;
1045 dst_vq->mem_ops = &vb2_dma_contig_memops;
1046 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1047 dst_vq->lock = &ctx->jpeg->lock;
1048 dst_vq->dev = ctx->jpeg->dev;
1049 ret = vb2_queue_init(dst_vq);
1050
1051 return ret;
1052}
1053
1054static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
1055{
1056 int ret;
1057
1058 ret = mtk_smi_larb_get(jpeg->larb);
1059 if (ret)
1060 dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
1061
1062 ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
1063 jpeg->variant->clks);
1064 if (ret)
1065 dev_err(jpeg->dev, "Failed to open jpeg clk: %d\n", ret);
1066}
1067
1068static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
1069{
1070 clk_bulk_disable_unprepare(jpeg->variant->num_clks,
1071 jpeg->variant->clks);
1072 mtk_smi_larb_put(jpeg->larb);
1073}
1074
1075static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
1076{
1077 struct mtk_jpeg_ctx *ctx;
1078 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1079 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1080 u32 result_size;
1081
1082 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1083 if (!ctx) {
1084 v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1085 return IRQ_HANDLED;
1086 }
1087
1088 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1089 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1090
1091 result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base);
1092 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
1093
1094 buf_state = VB2_BUF_STATE_DONE;
1095
1096 v4l2_m2m_buf_done(src_buf, buf_state);
1097 v4l2_m2m_buf_done(dst_buf, buf_state);
1098 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1099 pm_runtime_put(ctx->jpeg->dev);
1100 return IRQ_HANDLED;
1101}
1102
1103static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv)
1104{
1105 struct mtk_jpeg_dev *jpeg = priv;
1106 u32 irq_status;
1107 irqreturn_t ret = IRQ_NONE;
1108
1109 cancel_delayed_work(&jpeg->job_timeout_work);
1110
1111 irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) &
1112 JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
1113 if (irq_status)
1114 writel(0, jpeg->reg_base + JPEG_ENC_INT_STS);
1115
1116 if (!(irq_status & JPEG_ENC_INT_STATUS_DONE))
1117 return ret;
1118
1119 ret = mtk_jpeg_enc_done(jpeg);
1120 return ret;
1121}
1122
1123static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
1124{
1125 struct mtk_jpeg_dev *jpeg = priv;
1126 struct mtk_jpeg_ctx *ctx;
1127 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1128 struct mtk_jpeg_src_buf *jpeg_src_buf;
1129 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1130 u32 dec_irq_ret;
1131 u32 dec_ret;
1132 int i;
1133
1134 cancel_delayed_work(&jpeg->job_timeout_work);
1135
1136 dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base);
1137 dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret);
1138 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1139 if (!ctx) {
1140 v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1141 return IRQ_HANDLED;
1142 }
1143
1144 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1145 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1146 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
1147
1148 if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)
1149 mtk_jpeg_dec_reset(jpeg->reg_base);
1150
1151 if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) {
1152 dev_err(jpeg->dev, "decode failed\n");
1153 goto dec_end;
1154 }
1155
1156 for (i = 0; i < dst_buf->vb2_buf.num_planes; i++)
1157 vb2_set_plane_payload(&dst_buf->vb2_buf, i,
1158 jpeg_src_buf->dec_param.comp_size[i]);
1159
1160 buf_state = VB2_BUF_STATE_DONE;
1161
1162dec_end:
1163 v4l2_m2m_buf_done(src_buf, buf_state);
1164 v4l2_m2m_buf_done(dst_buf, buf_state);
1165 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1166 pm_runtime_put(ctx->jpeg->dev);
1167 return IRQ_HANDLED;
1168}
1169
1170static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx)
1171{
1172 struct mtk_jpeg_q_data *q = &ctx->out_q;
1173 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1174
1175 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1176 q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1177 q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1178 q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1179 q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1180
1181 q->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
1182 jpeg->variant->num_formats,
1183 jpeg->variant->out_q_default_fourcc,
1184 MTK_JPEG_FMT_FLAG_OUTPUT);
1185 q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1186 q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1187 mtk_jpeg_try_fmt_mplane(&q->pix_mp, q->fmt);
1188
1189 q = &ctx->cap_q;
1190 q->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
1191 jpeg->variant->num_formats,
1192 jpeg->variant->cap_q_default_fourcc,
1193 MTK_JPEG_FMT_FLAG_CAPTURE);
1194 q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1195 q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1196 q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1197 q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1198 q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1199 q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1200
1201 mtk_jpeg_try_fmt_mplane(&q->pix_mp, q->fmt);
1202}
1203
1204static int mtk_jpeg_open(struct file *file)
1205{
1206 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1207 struct video_device *vfd = video_devdata(file);
1208 struct mtk_jpeg_ctx *ctx;
1209 int ret = 0;
1210
1211 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1212 if (!ctx)
1213 return -ENOMEM;
1214
1215 if (mutex_lock_interruptible(&jpeg->lock)) {
1216 ret = -ERESTARTSYS;
1217 goto free;
1218 }
1219
1220 v4l2_fh_init(&ctx->fh, vfd);
1221 file->private_data = &ctx->fh;
1222 v4l2_fh_add(&ctx->fh);
1223
1224 ctx->jpeg = jpeg;
1225 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx,
1226 mtk_jpeg_queue_init);
1227 if (IS_ERR(ctx->fh.m2m_ctx)) {
1228 ret = PTR_ERR(ctx->fh.m2m_ctx);
1229 goto error;
1230 }
1231
1232 if (jpeg->variant->cap_q_default_fourcc == V4L2_PIX_FMT_JPEG) {
1233 ret = mtk_jpeg_enc_ctrls_setup(ctx);
1234 if (ret) {
1235 v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n");
1236 goto error;
1237 }
1238 } else {
1239 v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0);
1240 }
1241 mtk_jpeg_set_default_params(ctx);
1242 mutex_unlock(&jpeg->lock);
1243 return 0;
1244
1245error:
1246 v4l2_fh_del(&ctx->fh);
1247 v4l2_fh_exit(&ctx->fh);
1248 mutex_unlock(&jpeg->lock);
1249free:
1250 kfree(ctx);
1251 return ret;
1252}
1253
1254static int mtk_jpeg_release(struct file *file)
1255{
1256 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1257 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(file->private_data);
1258
1259 mutex_lock(&jpeg->lock);
1260 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1261 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1262 v4l2_fh_del(&ctx->fh);
1263 v4l2_fh_exit(&ctx->fh);
1264 kfree(ctx);
1265 mutex_unlock(&jpeg->lock);
1266 return 0;
1267}
1268
1269static const struct v4l2_file_operations mtk_jpeg_fops = {
1270 .owner = THIS_MODULE,
1271 .open = mtk_jpeg_open,
1272 .release = mtk_jpeg_release,
1273 .poll = v4l2_m2m_fop_poll,
1274 .unlocked_ioctl = video_ioctl2,
1275 .mmap = v4l2_m2m_fop_mmap,
1276};
1277
1278static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = {
1279 { .id = "jpgdec-smi" },
1280 { .id = "jpgdec" },
1281};
1282
1283static struct clk_bulk_data mtk_jpeg_clocks[] = {
1284 { .id = "jpgenc" },
1285};
1286
1287static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
1288{
1289 struct device_node *node;
1290 struct platform_device *pdev;
1291 int ret;
1292
1293 node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
1294 if (!node)
1295 return -EINVAL;
1296 pdev = of_find_device_by_node(node);
1297 if (WARN_ON(!pdev)) {
1298 of_node_put(node);
1299 return -EINVAL;
1300 }
1301 of_node_put(node);
1302
1303 jpeg->larb = &pdev->dev;
1304
1305 ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
1306 jpeg->variant->clks);
1307 if (ret) {
1308 dev_err(&pdev->dev, "failed to get jpeg clock:%d\n", ret);
1309 put_device(&pdev->dev);
1310 return ret;
1311 }
1312
1313 return 0;
1314}
1315
1316static void mtk_jpeg_job_timeout_work(struct work_struct *work)
1317{
1318 struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
1319 job_timeout_work.work);
1320 struct mtk_jpeg_ctx *ctx;
1321 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1322
1323 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1324 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1325 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1326
1327 jpeg->variant->hw_reset(jpeg->reg_base);
1328
1329 pm_runtime_put(jpeg->dev);
1330
1331 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1332 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1333 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1334}
1335
1336static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
1337{
1338 put_device(jpeg->larb);
1339}
1340
1341static int mtk_jpeg_probe(struct platform_device *pdev)
1342{
1343 struct mtk_jpeg_dev *jpeg;
1344 struct resource *res;
1345 int jpeg_irq;
1346 int ret;
1347
1348 jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL);
1349 if (!jpeg)
1350 return -ENOMEM;
1351
1352 mutex_init(&jpeg->lock);
1353 spin_lock_init(&jpeg->hw_lock);
1354 jpeg->dev = &pdev->dev;
1355 jpeg->variant = of_device_get_match_data(jpeg->dev);
1356 INIT_DELAYED_WORK(&jpeg->job_timeout_work, mtk_jpeg_job_timeout_work);
1357
1358 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1359 jpeg->reg_base = devm_ioremap_resource(&pdev->dev, res);
1360 if (IS_ERR(jpeg->reg_base)) {
1361 ret = PTR_ERR(jpeg->reg_base);
1362 return ret;
1363 }
1364
1365 jpeg_irq = platform_get_irq(pdev, 0);
1366 if (jpeg_irq < 0) {
1367 dev_err(&pdev->dev, "Failed to get jpeg_irq %d.\n", jpeg_irq);
1368 return jpeg_irq;
1369 }
1370
1371 ret = devm_request_irq(&pdev->dev, jpeg_irq,
1372 jpeg->variant->irq_handler, 0, pdev->name, jpeg);
1373 if (ret) {
1374 dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n",
1375 jpeg_irq, ret);
1376 goto err_req_irq;
1377 }
1378
1379 ret = mtk_jpeg_clk_init(jpeg);
1380 if (ret) {
1381 dev_err(&pdev->dev, "Failed to init clk, err %d\n", ret);
1382 goto err_clk_init;
1383 }
1384
1385 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1386 if (ret) {
1387 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1388 ret = -EINVAL;
1389 goto err_dev_register;
1390 }
1391
1392 jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
1393
1394 if (IS_ERR(jpeg->m2m_dev)) {
1395 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1396 ret = PTR_ERR(jpeg->m2m_dev);
1397 goto err_m2m_init;
1398 }
1399
1400 jpeg->vdev = video_device_alloc();
1401 if (!jpeg->vdev) {
1402 ret = -ENOMEM;
1403 goto err_vfd_jpeg_alloc;
1404 }
1405 snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name),
1406 "%s", jpeg->variant->dev_name);
1407 jpeg->vdev->fops = &mtk_jpeg_fops;
1408 jpeg->vdev->ioctl_ops = jpeg->variant->ioctl_ops;
1409 jpeg->vdev->minor = -1;
1410 jpeg->vdev->release = video_device_release;
1411 jpeg->vdev->lock = &jpeg->lock;
1412 jpeg->vdev->v4l2_dev = &jpeg->v4l2_dev;
1413 jpeg->vdev->vfl_dir = VFL_DIR_M2M;
1414 jpeg->vdev->device_caps = V4L2_CAP_STREAMING |
1415 V4L2_CAP_VIDEO_M2M_MPLANE;
1416
1417 ret = video_register_device(jpeg->vdev, VFL_TYPE_VIDEO, -1);
1418 if (ret) {
1419 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1420 goto err_vfd_jpeg_register;
1421 }
1422
1423 video_set_drvdata(jpeg->vdev, jpeg);
1424 v4l2_info(&jpeg->v4l2_dev,
1425 "%s device registered as /dev/video%d (%d,%d)\n",
1426 jpeg->variant->dev_name, jpeg->vdev->num,
1427 VIDEO_MAJOR, jpeg->vdev->minor);
1428
1429 platform_set_drvdata(pdev, jpeg);
1430
1431 pm_runtime_enable(&pdev->dev);
1432
1433 return 0;
1434
1435err_vfd_jpeg_register:
1436 video_device_release(jpeg->vdev);
1437
1438err_vfd_jpeg_alloc:
1439 v4l2_m2m_release(jpeg->m2m_dev);
1440
1441err_m2m_init:
1442 v4l2_device_unregister(&jpeg->v4l2_dev);
1443
1444err_dev_register:
1445 mtk_jpeg_clk_release(jpeg);
1446
1447err_clk_init:
1448
1449err_req_irq:
1450
1451 return ret;
1452}
1453
1454static int mtk_jpeg_remove(struct platform_device *pdev)
1455{
1456 struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
1457
1458 pm_runtime_disable(&pdev->dev);
1459 video_unregister_device(jpeg->vdev);
1460 video_device_release(jpeg->vdev);
1461 v4l2_m2m_release(jpeg->m2m_dev);
1462 v4l2_device_unregister(&jpeg->v4l2_dev);
1463 mtk_jpeg_clk_release(jpeg);
1464
1465 return 0;
1466}
1467
1468static __maybe_unused int mtk_jpeg_pm_suspend(struct device *dev)
1469{
1470 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1471
1472 mtk_jpeg_clk_off(jpeg);
1473
1474 return 0;
1475}
1476
1477static __maybe_unused int mtk_jpeg_pm_resume(struct device *dev)
1478{
1479 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1480
1481 mtk_jpeg_clk_on(jpeg);
1482
1483 return 0;
1484}
1485
1486static __maybe_unused int mtk_jpeg_suspend(struct device *dev)
1487{
1488 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1489
1490 v4l2_m2m_suspend(jpeg->m2m_dev);
1491 return pm_runtime_force_suspend(dev);
1492}
1493
1494static __maybe_unused int mtk_jpeg_resume(struct device *dev)
1495{
1496 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1497 int ret;
1498
1499 ret = pm_runtime_force_resume(dev);
1500 if (ret < 0)
1501 return ret;
1502
1503 v4l2_m2m_resume(jpeg->m2m_dev);
1504 return ret;
1505}
1506
1507static const struct dev_pm_ops mtk_jpeg_pm_ops = {
1508 SET_SYSTEM_SLEEP_PM_OPS(mtk_jpeg_suspend, mtk_jpeg_resume)
1509 SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL)
1510};
1511
1512static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = {
1513 .clks = mt8173_jpeg_dec_clocks,
1514 .num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks),
1515 .formats = mtk_jpeg_dec_formats,
1516 .num_formats = MTK_JPEG_DEC_NUM_FORMATS,
1517 .qops = &mtk_jpeg_dec_qops,
1518 .irq_handler = mtk_jpeg_dec_irq,
1519 .hw_reset = mtk_jpeg_dec_reset,
1520 .m2m_ops = &mtk_jpeg_dec_m2m_ops,
1521 .dev_name = "mtk-jpeg-dec",
1522 .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
1523 .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1524 .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
1525};
1526
1527static const struct mtk_jpeg_variant mtk_jpeg_drvdata = {
1528 .clks = mtk_jpeg_clocks,
1529 .num_clks = ARRAY_SIZE(mtk_jpeg_clocks),
1530 .formats = mtk_jpeg_enc_formats,
1531 .num_formats = MTK_JPEG_ENC_NUM_FORMATS,
1532 .qops = &mtk_jpeg_enc_qops,
1533 .irq_handler = mtk_jpeg_enc_irq,
1534 .hw_reset = mtk_jpeg_enc_reset,
1535 .m2m_ops = &mtk_jpeg_enc_m2m_ops,
1536 .dev_name = "mtk-jpeg-enc",
1537 .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
1538 .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
1539 .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1540};
1541
1542static const struct of_device_id mtk_jpeg_match[] = {
1543 {
1544 .compatible = "mediatek,mt8173-jpgdec",
1545 .data = &mt8173_jpeg_drvdata,
1546 },
1547 {
1548 .compatible = "mediatek,mt2701-jpgdec",
1549 .data = &mt8173_jpeg_drvdata,
1550 },
1551 {
1552 .compatible = "mediatek,mtk-jpgenc",
1553 .data = &mtk_jpeg_drvdata,
1554 },
1555 {},
1556};
1557
1558MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
1559
1560static struct platform_driver mtk_jpeg_driver = {
1561 .probe = mtk_jpeg_probe,
1562 .remove = mtk_jpeg_remove,
1563 .driver = {
1564 .name = MTK_JPEG_NAME,
1565 .of_match_table = mtk_jpeg_match,
1566 .pm = &mtk_jpeg_pm_ops,
1567 },
1568};
1569
1570module_platform_driver(mtk_jpeg_driver);
1571
1572MODULE_DESCRIPTION("MediaTek JPEG codec driver");
1573MODULE_LICENSE("GPL v2");
1574