Adding support for MOXA ART SoC. Testing port of linux-2.6.32.60-moxart.
[linux-3.6.7-moxart.git] / drivers / media / video / s5p-jpeg / jpeg-core.c
blob813b801238d1f72e910ab8eea63feeb586b477bb
1 /* linux/drivers/media/video/s5p-jpeg/jpeg-core.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/clk.h>
14 #include <linux/err.h>
15 #include <linux/gfp.h>
16 #include <linux/interrupt.h>
17 #include <linux/io.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/slab.h>
23 #include <linux/spinlock.h>
24 #include <linux/string.h>
25 #include <media/v4l2-mem2mem.h>
26 #include <media/v4l2-ioctl.h>
27 #include <media/videobuf2-core.h>
28 #include <media/videobuf2-dma-contig.h>
30 #include "jpeg-core.h"
31 #include "jpeg-hw.h"
33 static struct s5p_jpeg_fmt formats_enc[] = {
35 .name = "JPEG JFIF",
36 .fourcc = V4L2_PIX_FMT_JPEG,
37 .colplanes = 1,
38 .types = MEM2MEM_CAPTURE,
41 .name = "YUV 4:2:2 packed, YCbYCr",
42 .fourcc = V4L2_PIX_FMT_YUYV,
43 .depth = 16,
44 .colplanes = 1,
45 .types = MEM2MEM_OUTPUT,
48 .name = "RGB565",
49 .fourcc = V4L2_PIX_FMT_RGB565,
50 .depth = 16,
51 .colplanes = 1,
52 .types = MEM2MEM_OUTPUT,
55 #define NUM_FORMATS_ENC ARRAY_SIZE(formats_enc)
57 static struct s5p_jpeg_fmt formats_dec[] = {
59 .name = "YUV 4:2:0 planar, YCbCr",
60 .fourcc = V4L2_PIX_FMT_YUV420,
61 .depth = 12,
62 .colplanes = 3,
63 .h_align = 4,
64 .v_align = 4,
65 .types = MEM2MEM_CAPTURE,
68 .name = "YUV 4:2:2 packed, YCbYCr",
69 .fourcc = V4L2_PIX_FMT_YUYV,
70 .depth = 16,
71 .colplanes = 1,
72 .h_align = 4,
73 .v_align = 3,
74 .types = MEM2MEM_CAPTURE,
77 .name = "JPEG JFIF",
78 .fourcc = V4L2_PIX_FMT_JPEG,
79 .colplanes = 1,
80 .types = MEM2MEM_OUTPUT,
83 #define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec)
85 static const unsigned char qtbl_luminance[4][64] = {
86 {/* level 1 - high quality */
87 8, 6, 6, 8, 12, 14, 16, 17,
88 6, 6, 6, 8, 10, 13, 12, 15,
89 6, 6, 7, 8, 13, 14, 18, 24,
90 8, 8, 8, 14, 13, 19, 24, 35,
91 12, 10, 13, 13, 20, 26, 34, 39,
92 14, 13, 14, 19, 26, 34, 39, 39,
93 16, 12, 18, 24, 34, 39, 39, 39,
94 17, 15, 24, 35, 39, 39, 39, 39
96 {/* level 2 */
97 12, 8, 8, 12, 17, 21, 24, 23,
98 8, 9, 9, 11, 15, 19, 18, 23,
99 8, 9, 10, 12, 19, 20, 27, 36,
100 12, 11, 12, 21, 20, 28, 36, 53,
101 17, 15, 19, 20, 30, 39, 51, 59,
102 21, 19, 20, 28, 39, 51, 59, 59,
103 24, 18, 27, 36, 51, 59, 59, 59,
104 23, 23, 36, 53, 59, 59, 59, 59
106 {/* level 3 */
107 16, 11, 11, 16, 23, 27, 31, 30,
108 11, 12, 12, 15, 20, 23, 23, 30,
109 11, 12, 13, 16, 23, 26, 35, 47,
110 16, 15, 16, 23, 26, 37, 47, 64,
111 23, 20, 23, 26, 39, 51, 64, 64,
112 27, 23, 26, 37, 51, 64, 64, 64,
113 31, 23, 35, 47, 64, 64, 64, 64,
114 30, 30, 47, 64, 64, 64, 64, 64
116 {/*level 4 - low quality */
117 20, 16, 25, 39, 50, 46, 62, 68,
118 16, 18, 23, 38, 38, 53, 65, 68,
119 25, 23, 31, 38, 53, 65, 68, 68,
120 39, 38, 38, 53, 65, 68, 68, 68,
121 50, 38, 53, 65, 68, 68, 68, 68,
122 46, 53, 65, 68, 68, 68, 68, 68,
123 62, 65, 68, 68, 68, 68, 68, 68,
124 68, 68, 68, 68, 68, 68, 68, 68
128 static const unsigned char qtbl_chrominance[4][64] = {
129 {/* level 1 - high quality */
130 9, 8, 9, 11, 14, 17, 19, 24,
131 8, 10, 9, 11, 14, 13, 17, 22,
132 9, 9, 13, 14, 13, 15, 23, 26,
133 11, 11, 14, 14, 15, 20, 26, 33,
134 14, 14, 13, 15, 20, 24, 33, 39,
135 17, 13, 15, 20, 24, 32, 39, 39,
136 19, 17, 23, 26, 33, 39, 39, 39,
137 24, 22, 26, 33, 39, 39, 39, 39
139 {/* level 2 */
140 13, 11, 13, 16, 20, 20, 29, 37,
141 11, 14, 14, 14, 16, 20, 26, 32,
142 13, 14, 15, 17, 20, 23, 35, 40,
143 16, 14, 17, 21, 23, 30, 40, 50,
144 20, 16, 20, 23, 30, 37, 50, 59,
145 20, 20, 23, 30, 37, 48, 59, 59,
146 29, 26, 35, 40, 50, 59, 59, 59,
147 37, 32, 40, 50, 59, 59, 59, 59
149 {/* level 3 */
150 17, 15, 17, 21, 20, 26, 38, 48,
151 15, 19, 18, 17, 20, 26, 35, 43,
152 17, 18, 20, 22, 26, 30, 46, 53,
153 21, 17, 22, 28, 30, 39, 53, 64,
154 20, 20, 26, 30, 39, 48, 64, 64,
155 26, 26, 30, 39, 48, 63, 64, 64,
156 38, 35, 46, 53, 64, 64, 64, 64,
157 48, 43, 53, 64, 64, 64, 64, 64
159 {/*level 4 - low quality */
160 21, 25, 32, 38, 54, 68, 68, 68,
161 25, 28, 24, 38, 54, 68, 68, 68,
162 32, 24, 32, 43, 66, 68, 68, 68,
163 38, 38, 43, 53, 68, 68, 68, 68,
164 54, 54, 66, 68, 68, 68, 68, 68,
165 68, 68, 68, 68, 68, 68, 68, 68,
166 68, 68, 68, 68, 68, 68, 68, 68,
167 68, 68, 68, 68, 68, 68, 68, 68
171 static const unsigned char hdctbl0[16] = {
172 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
175 static const unsigned char hdctblg0[12] = {
176 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
178 static const unsigned char hactbl0[16] = {
179 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
181 static const unsigned char hactblg0[162] = {
182 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
183 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
184 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
185 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
186 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
187 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
188 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
189 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
190 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
191 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
192 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
193 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
194 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
195 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
196 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
197 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
198 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
199 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
200 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
201 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
202 0xf9, 0xfa
205 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
207 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
210 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
212 return container_of(fh, struct s5p_jpeg_ctx, fh);
215 static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
216 unsigned long tab, int len)
218 int i;
220 for (i = 0; i < len; i++)
221 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
224 static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality)
226 /* this driver fills quantisation table 0 with data for luma */
227 jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0),
228 ARRAY_SIZE(qtbl_luminance[quality]));
231 static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality)
233 /* this driver fills quantisation table 1 with data for chroma */
234 jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1),
235 ARRAY_SIZE(qtbl_chrominance[quality]));
238 static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
239 unsigned long tab, int len)
241 int i;
243 for (i = 0; i < len; i++)
244 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
247 static inline void jpeg_set_hdctbl(void __iomem *regs)
249 /* this driver fills table 0 for this component */
250 jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0));
253 static inline void jpeg_set_hdctblg(void __iomem *regs)
255 /* this driver fills table 0 for this component */
256 jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0));
259 static inline void jpeg_set_hactbl(void __iomem *regs)
261 /* this driver fills table 0 for this component */
262 jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0));
265 static inline void jpeg_set_hactblg(void __iomem *regs)
267 /* this driver fills table 0 for this component */
268 jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
272 * ============================================================================
273 * Device file operations
274 * ============================================================================
277 static int queue_init(void *priv, struct vb2_queue *src_vq,
278 struct vb2_queue *dst_vq);
279 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
280 __u32 pixelformat);
281 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
283 static int s5p_jpeg_open(struct file *file)
285 struct s5p_jpeg *jpeg = video_drvdata(file);
286 struct video_device *vfd = video_devdata(file);
287 struct s5p_jpeg_ctx *ctx;
288 struct s5p_jpeg_fmt *out_fmt;
289 int ret = 0;
291 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
292 if (!ctx)
293 return -ENOMEM;
295 v4l2_fh_init(&ctx->fh, vfd);
296 /* Use separate control handler per file handle */
297 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
298 file->private_data = &ctx->fh;
299 v4l2_fh_add(&ctx->fh);
301 ctx->jpeg = jpeg;
302 if (vfd == jpeg->vfd_encoder) {
303 ctx->mode = S5P_JPEG_ENCODE;
304 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
305 } else {
306 ctx->mode = S5P_JPEG_DECODE;
307 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
310 ret = s5p_jpeg_controls_create(ctx);
311 if (ret < 0)
312 goto error;
314 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
315 if (IS_ERR(ctx->m2m_ctx)) {
316 ret = PTR_ERR(ctx->m2m_ctx);
317 goto error;
320 ctx->out_q.fmt = out_fmt;
321 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
322 return 0;
324 error:
325 v4l2_fh_del(&ctx->fh);
326 v4l2_fh_exit(&ctx->fh);
327 kfree(ctx);
328 return ret;
331 static int s5p_jpeg_release(struct file *file)
333 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
335 v4l2_m2m_ctx_release(ctx->m2m_ctx);
336 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
337 v4l2_fh_del(&ctx->fh);
338 v4l2_fh_exit(&ctx->fh);
339 kfree(ctx);
341 return 0;
344 static unsigned int s5p_jpeg_poll(struct file *file,
345 struct poll_table_struct *wait)
347 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
349 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
352 static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
354 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
356 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
359 static const struct v4l2_file_operations s5p_jpeg_fops = {
360 .owner = THIS_MODULE,
361 .open = s5p_jpeg_open,
362 .release = s5p_jpeg_release,
363 .poll = s5p_jpeg_poll,
364 .unlocked_ioctl = video_ioctl2,
365 .mmap = s5p_jpeg_mmap,
369 * ============================================================================
370 * video ioctl operations
371 * ============================================================================
374 static int get_byte(struct s5p_jpeg_buffer *buf)
376 if (buf->curr >= buf->size)
377 return -1;
379 return ((unsigned char *)buf->data)[buf->curr++];
382 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
384 unsigned int temp;
385 int byte;
387 byte = get_byte(buf);
388 if (byte == -1)
389 return -1;
390 temp = byte << 8;
391 byte = get_byte(buf);
392 if (byte == -1)
393 return -1;
394 *word = (unsigned int)byte | temp;
395 return 0;
398 static void skip(struct s5p_jpeg_buffer *buf, long len)
400 if (len <= 0)
401 return;
403 while (len--)
404 get_byte(buf);
407 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
408 unsigned long buffer, unsigned long size)
410 int c, components, notfound;
411 unsigned int height, width, word;
412 long length;
413 struct s5p_jpeg_buffer jpeg_buffer;
415 jpeg_buffer.size = size;
416 jpeg_buffer.data = buffer;
417 jpeg_buffer.curr = 0;
419 notfound = 1;
420 while (notfound) {
421 c = get_byte(&jpeg_buffer);
422 if (c == -1)
423 break;
424 if (c != 0xff)
425 continue;
427 c = get_byte(&jpeg_buffer);
428 while (c == 0xff);
429 if (c == -1)
430 break;
431 if (c == 0)
432 continue;
433 length = 0;
434 switch (c) {
435 /* SOF0: baseline JPEG */
436 case SOF0:
437 if (get_word_be(&jpeg_buffer, &word))
438 break;
439 if (get_byte(&jpeg_buffer) == -1)
440 break;
441 if (get_word_be(&jpeg_buffer, &height))
442 break;
443 if (get_word_be(&jpeg_buffer, &width))
444 break;
445 components = get_byte(&jpeg_buffer);
446 if (components == -1)
447 break;
448 notfound = 0;
450 skip(&jpeg_buffer, components * 3);
451 break;
453 /* skip payload-less markers */
454 case RST ... RST + 7:
455 case SOI:
456 case EOI:
457 case TEM:
458 break;
460 /* skip uninteresting payload markers */
461 default:
462 if (get_word_be(&jpeg_buffer, &word))
463 break;
464 length = (long)word - 2;
465 skip(&jpeg_buffer, length);
466 break;
469 result->w = width;
470 result->h = height;
471 result->size = components;
472 return !notfound;
475 static int s5p_jpeg_querycap(struct file *file, void *priv,
476 struct v4l2_capability *cap)
478 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
480 if (ctx->mode == S5P_JPEG_ENCODE) {
481 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
482 sizeof(cap->driver));
483 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
484 sizeof(cap->card));
485 } else {
486 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
487 sizeof(cap->driver));
488 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
489 sizeof(cap->card));
491 cap->bus_info[0] = 0;
493 * This is only a mem-to-mem video device. The capture and output
494 * device capability flags are left only for backward compatibility
495 * and are scheduled for removal.
497 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
498 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
499 return 0;
502 static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
503 struct v4l2_fmtdesc *f, u32 type)
505 int i, num = 0;
507 for (i = 0; i < n; ++i) {
508 if (formats[i].types & type) {
509 /* index-th format of type type found ? */
510 if (num == f->index)
511 break;
512 /* Correct type but haven't reached our index yet,
513 * just increment per-type index */
514 ++num;
518 /* Format not found */
519 if (i >= n)
520 return -EINVAL;
522 strlcpy(f->description, formats[i].name, sizeof(f->description));
523 f->pixelformat = formats[i].fourcc;
525 return 0;
528 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
529 struct v4l2_fmtdesc *f)
531 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
533 if (ctx->mode == S5P_JPEG_ENCODE)
534 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
535 MEM2MEM_CAPTURE);
537 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE);
540 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
541 struct v4l2_fmtdesc *f)
543 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
545 if (ctx->mode == S5P_JPEG_ENCODE)
546 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
547 MEM2MEM_OUTPUT);
549 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT);
552 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
553 enum v4l2_buf_type type)
555 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
556 return &ctx->out_q;
557 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
558 return &ctx->cap_q;
560 return NULL;
563 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
565 struct vb2_queue *vq;
566 struct s5p_jpeg_q_data *q_data = NULL;
567 struct v4l2_pix_format *pix = &f->fmt.pix;
568 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
570 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
571 if (!vq)
572 return -EINVAL;
574 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
575 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
576 return -EINVAL;
577 q_data = get_q_data(ct, f->type);
578 BUG_ON(q_data == NULL);
580 pix->width = q_data->w;
581 pix->height = q_data->h;
582 pix->field = V4L2_FIELD_NONE;
583 pix->pixelformat = q_data->fmt->fourcc;
584 pix->bytesperline = 0;
585 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
586 u32 bpl = q_data->w;
587 if (q_data->fmt->colplanes == 1)
588 bpl = (bpl * q_data->fmt->depth) >> 3;
589 pix->bytesperline = bpl;
591 pix->sizeimage = q_data->size;
593 return 0;
596 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
597 u32 pixelformat)
599 unsigned int k;
600 struct s5p_jpeg_fmt *formats;
601 int n;
603 if (mode == S5P_JPEG_ENCODE) {
604 formats = formats_enc;
605 n = NUM_FORMATS_ENC;
606 } else {
607 formats = formats_dec;
608 n = NUM_FORMATS_DEC;
611 for (k = 0; k < n; k++) {
612 struct s5p_jpeg_fmt *fmt = &formats[k];
613 if (fmt->fourcc == pixelformat)
614 return fmt;
617 return NULL;
621 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
622 unsigned int walign,
623 u32 *h, unsigned int hmin, unsigned int hmax,
624 unsigned int halign)
626 int width, height, w_step, h_step;
628 width = *w;
629 height = *h;
631 w_step = 1 << walign;
632 h_step = 1 << halign;
633 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
635 if (*w < width && (*w + w_step) < wmax)
636 *w += w_step;
637 if (*h < height && (*h + h_step) < hmax)
638 *h += h_step;
642 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
643 struct s5p_jpeg_ctx *ctx, int q_type)
645 struct v4l2_pix_format *pix = &f->fmt.pix;
647 if (pix->field == V4L2_FIELD_ANY)
648 pix->field = V4L2_FIELD_NONE;
649 else if (pix->field != V4L2_FIELD_NONE)
650 return -EINVAL;
652 /* V4L2 specification suggests the driver corrects the format struct
653 * if any of the dimensions is unsupported */
654 if (q_type == MEM2MEM_OUTPUT)
655 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
656 S5P_JPEG_MAX_WIDTH, 0,
657 &pix->height, S5P_JPEG_MIN_HEIGHT,
658 S5P_JPEG_MAX_HEIGHT, 0);
659 else
660 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
661 S5P_JPEG_MAX_WIDTH, fmt->h_align,
662 &pix->height, S5P_JPEG_MIN_HEIGHT,
663 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
665 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
666 if (pix->sizeimage <= 0)
667 pix->sizeimage = PAGE_SIZE;
668 pix->bytesperline = 0;
669 } else {
670 u32 bpl = pix->bytesperline;
672 if (fmt->colplanes > 1 && bpl < pix->width)
673 bpl = pix->width; /* planar */
675 if (fmt->colplanes == 1 && /* packed */
676 (bpl << 3) * fmt->depth < pix->width)
677 bpl = (pix->width * fmt->depth) >> 3;
679 pix->bytesperline = bpl;
680 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
683 return 0;
686 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
687 struct v4l2_format *f)
689 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
690 struct s5p_jpeg_fmt *fmt;
692 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
693 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
694 v4l2_err(&ctx->jpeg->v4l2_dev,
695 "Fourcc format (0x%08x) invalid.\n",
696 f->fmt.pix.pixelformat);
697 return -EINVAL;
700 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE);
703 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
704 struct v4l2_format *f)
706 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
707 struct s5p_jpeg_fmt *fmt;
709 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
710 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
711 v4l2_err(&ctx->jpeg->v4l2_dev,
712 "Fourcc format (0x%08x) invalid.\n",
713 f->fmt.pix.pixelformat);
714 return -EINVAL;
717 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT);
720 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
722 struct vb2_queue *vq;
723 struct s5p_jpeg_q_data *q_data = NULL;
724 struct v4l2_pix_format *pix = &f->fmt.pix;
726 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
727 if (!vq)
728 return -EINVAL;
730 q_data = get_q_data(ct, f->type);
731 BUG_ON(q_data == NULL);
733 if (vb2_is_busy(vq)) {
734 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
735 return -EBUSY;
738 q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat);
739 q_data->w = pix->width;
740 q_data->h = pix->height;
741 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
742 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
743 else
744 q_data->size = pix->sizeimage;
746 return 0;
749 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
750 struct v4l2_format *f)
752 int ret;
754 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
755 if (ret)
756 return ret;
758 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
761 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
762 struct v4l2_format *f)
764 int ret;
766 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
767 if (ret)
768 return ret;
770 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
773 static int s5p_jpeg_reqbufs(struct file *file, void *priv,
774 struct v4l2_requestbuffers *reqbufs)
776 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
778 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
781 static int s5p_jpeg_querybuf(struct file *file, void *priv,
782 struct v4l2_buffer *buf)
784 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
786 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
789 static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
791 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
793 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
796 static int s5p_jpeg_dqbuf(struct file *file, void *priv,
797 struct v4l2_buffer *buf)
799 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
801 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
804 static int s5p_jpeg_streamon(struct file *file, void *priv,
805 enum v4l2_buf_type type)
807 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
809 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
812 static int s5p_jpeg_streamoff(struct file *file, void *priv,
813 enum v4l2_buf_type type)
815 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
817 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
820 static int s5p_jpeg_g_selection(struct file *file, void *priv,
821 struct v4l2_selection *s)
823 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
825 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
826 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
827 return -EINVAL;
829 /* For JPEG blob active == default == bounds */
830 switch (s->target) {
831 case V4L2_SEL_TGT_CROP:
832 case V4L2_SEL_TGT_CROP_BOUNDS:
833 case V4L2_SEL_TGT_CROP_DEFAULT:
834 case V4L2_SEL_TGT_COMPOSE:
835 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
836 s->r.width = ctx->out_q.w;
837 s->r.height = ctx->out_q.h;
838 break;
839 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
840 case V4L2_SEL_TGT_COMPOSE_PADDED:
841 s->r.width = ctx->cap_q.w;
842 s->r.height = ctx->cap_q.h;
843 break;
844 default:
845 return -EINVAL;
847 s->r.left = 0;
848 s->r.top = 0;
849 return 0;
853 * V4L2 controls
856 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
858 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
859 struct s5p_jpeg *jpeg = ctx->jpeg;
860 unsigned long flags;
862 switch (ctrl->id) {
863 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
864 spin_lock_irqsave(&jpeg->slock, flags);
866 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
867 if (ctx->subsampling > 2)
868 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
869 else
870 ctrl->val = ctx->subsampling;
871 spin_unlock_irqrestore(&jpeg->slock, flags);
872 break;
875 return 0;
878 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
880 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
881 unsigned long flags;
883 spin_lock_irqsave(&ctx->jpeg->slock, flags);
885 switch (ctrl->id) {
886 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
887 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
888 break;
889 case V4L2_CID_JPEG_RESTART_INTERVAL:
890 ctx->restart_interval = ctrl->val;
891 break;
892 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
893 ctx->subsampling = ctrl->val;
894 break;
897 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
898 return 0;
901 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
902 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
903 .s_ctrl = s5p_jpeg_s_ctrl,
906 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
908 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
909 struct v4l2_ctrl *ctrl;
911 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
913 if (ctx->mode == S5P_JPEG_ENCODE) {
914 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
915 V4L2_CID_JPEG_COMPRESSION_QUALITY,
916 0, 3, 1, 3);
918 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
919 V4L2_CID_JPEG_RESTART_INTERVAL,
920 0, 3, 0xffff, 0);
921 mask = ~0x06; /* 422, 420 */
924 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
925 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
926 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
927 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
929 if (ctx->ctrl_handler.error)
930 return ctx->ctrl_handler.error;
932 if (ctx->mode == S5P_JPEG_DECODE)
933 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
934 V4L2_CTRL_FLAG_READ_ONLY;
935 return 0;
938 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
939 .vidioc_querycap = s5p_jpeg_querycap,
941 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
942 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
944 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
945 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
947 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
948 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
950 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
951 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
953 .vidioc_reqbufs = s5p_jpeg_reqbufs,
954 .vidioc_querybuf = s5p_jpeg_querybuf,
956 .vidioc_qbuf = s5p_jpeg_qbuf,
957 .vidioc_dqbuf = s5p_jpeg_dqbuf,
959 .vidioc_streamon = s5p_jpeg_streamon,
960 .vidioc_streamoff = s5p_jpeg_streamoff,
962 .vidioc_g_selection = s5p_jpeg_g_selection,
966 * ============================================================================
967 * mem2mem callbacks
968 * ============================================================================
971 static void s5p_jpeg_device_run(void *priv)
973 struct s5p_jpeg_ctx *ctx = priv;
974 struct s5p_jpeg *jpeg = ctx->jpeg;
975 struct vb2_buffer *src_buf, *dst_buf;
976 unsigned long src_addr, dst_addr;
978 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
979 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
980 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
981 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
983 jpeg_reset(jpeg->regs);
984 jpeg_poweron(jpeg->regs);
985 jpeg_proc_mode(jpeg->regs, ctx->mode);
986 if (ctx->mode == S5P_JPEG_ENCODE) {
987 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
988 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
989 else
990 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
991 jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
992 jpeg_dri(jpeg->regs, ctx->restart_interval);
993 jpeg_x(jpeg->regs, ctx->out_q.w);
994 jpeg_y(jpeg->regs, ctx->out_q.h);
995 jpeg_imgadr(jpeg->regs, src_addr);
996 jpeg_jpgadr(jpeg->regs, dst_addr);
998 /* ultimately comes from sizeimage from userspace */
999 jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1001 /* JPEG RGB to YCbCr conversion matrix */
1002 jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1003 jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1004 jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1005 jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1006 jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1007 jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1008 jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1009 jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1010 jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1013 * JPEG IP allows storing 4 quantization tables
1014 * We fill table 0 for luma and table 1 for chroma
1016 jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1017 jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1018 /* use table 0 for Y */
1019 jpeg_qtbl(jpeg->regs, 1, 0);
1020 /* use table 1 for Cb and Cr*/
1021 jpeg_qtbl(jpeg->regs, 2, 1);
1022 jpeg_qtbl(jpeg->regs, 3, 1);
1024 /* Y, Cb, Cr use Huffman table 0 */
1025 jpeg_htbl_ac(jpeg->regs, 1);
1026 jpeg_htbl_dc(jpeg->regs, 1);
1027 jpeg_htbl_ac(jpeg->regs, 2);
1028 jpeg_htbl_dc(jpeg->regs, 2);
1029 jpeg_htbl_ac(jpeg->regs, 3);
1030 jpeg_htbl_dc(jpeg->regs, 3);
1031 } else { /* S5P_JPEG_DECODE */
1032 jpeg_rst_int_enable(jpeg->regs, true);
1033 jpeg_data_num_int_enable(jpeg->regs, true);
1034 jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1035 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1036 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1037 else
1038 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1039 jpeg_jpgadr(jpeg->regs, src_addr);
1040 jpeg_imgadr(jpeg->regs, dst_addr);
1043 jpeg_start(jpeg->regs);
1046 static int s5p_jpeg_job_ready(void *priv)
1048 struct s5p_jpeg_ctx *ctx = priv;
1050 if (ctx->mode == S5P_JPEG_DECODE)
1051 return ctx->hdr_parsed;
1052 return 1;
1055 static void s5p_jpeg_job_abort(void *priv)
1059 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1060 .device_run = s5p_jpeg_device_run,
1061 .job_ready = s5p_jpeg_job_ready,
1062 .job_abort = s5p_jpeg_job_abort,
1066 * ============================================================================
1067 * Queue operations
1068 * ============================================================================
1071 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1072 const struct v4l2_format *fmt,
1073 unsigned int *nbuffers, unsigned int *nplanes,
1074 unsigned int sizes[], void *alloc_ctxs[])
1076 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1077 struct s5p_jpeg_q_data *q_data = NULL;
1078 unsigned int size, count = *nbuffers;
1080 q_data = get_q_data(ctx, vq->type);
1081 BUG_ON(q_data == NULL);
1083 size = q_data->size;
1086 * header is parsed during decoding and parsed information stored
1087 * in the context so we do not allow another buffer to overwrite it
1089 if (ctx->mode == S5P_JPEG_DECODE)
1090 count = 1;
1092 *nbuffers = count;
1093 *nplanes = 1;
1094 sizes[0] = size;
1095 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1097 return 0;
1100 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1102 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1103 struct s5p_jpeg_q_data *q_data = NULL;
1105 q_data = get_q_data(ctx, vb->vb2_queue->type);
1106 BUG_ON(q_data == NULL);
1108 if (vb2_plane_size(vb, 0) < q_data->size) {
1109 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1110 __func__, vb2_plane_size(vb, 0),
1111 (long)q_data->size);
1112 return -EINVAL;
1115 vb2_set_plane_payload(vb, 0, q_data->size);
1117 return 0;
1120 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1122 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1124 if (ctx->mode == S5P_JPEG_DECODE &&
1125 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1126 struct s5p_jpeg_q_data tmp, *q_data;
1127 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1128 (unsigned long)vb2_plane_vaddr(vb, 0),
1129 min((unsigned long)ctx->out_q.size,
1130 vb2_get_plane_payload(vb, 0)));
1131 if (!ctx->hdr_parsed) {
1132 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1133 return;
1136 q_data = &ctx->out_q;
1137 q_data->w = tmp.w;
1138 q_data->h = tmp.h;
1140 q_data = &ctx->cap_q;
1141 q_data->w = tmp.w;
1142 q_data->h = tmp.h;
1144 jpeg_bound_align_image(&q_data->w, S5P_JPEG_MIN_WIDTH,
1145 S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1146 &q_data->h, S5P_JPEG_MIN_HEIGHT,
1147 S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
1149 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1151 if (ctx->m2m_ctx)
1152 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
1155 static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
1157 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1159 mutex_unlock(&ctx->jpeg->lock);
1162 static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
1164 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1166 mutex_lock(&ctx->jpeg->lock);
1169 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1171 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1172 int ret;
1174 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1176 return ret > 0 ? 0 : ret;
1179 static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1181 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1183 pm_runtime_put(ctx->jpeg->dev);
1185 return 0;
1188 static struct vb2_ops s5p_jpeg_qops = {
1189 .queue_setup = s5p_jpeg_queue_setup,
1190 .buf_prepare = s5p_jpeg_buf_prepare,
1191 .buf_queue = s5p_jpeg_buf_queue,
1192 .wait_prepare = s5p_jpeg_wait_prepare,
1193 .wait_finish = s5p_jpeg_wait_finish,
1194 .start_streaming = s5p_jpeg_start_streaming,
1195 .stop_streaming = s5p_jpeg_stop_streaming,
1198 static int queue_init(void *priv, struct vb2_queue *src_vq,
1199 struct vb2_queue *dst_vq)
1201 struct s5p_jpeg_ctx *ctx = priv;
1202 int ret;
1204 memset(src_vq, 0, sizeof(*src_vq));
1205 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1206 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1207 src_vq->drv_priv = ctx;
1208 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1209 src_vq->ops = &s5p_jpeg_qops;
1210 src_vq->mem_ops = &vb2_dma_contig_memops;
1212 ret = vb2_queue_init(src_vq);
1213 if (ret)
1214 return ret;
1216 memset(dst_vq, 0, sizeof(*dst_vq));
1217 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1218 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1219 dst_vq->drv_priv = ctx;
1220 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1221 dst_vq->ops = &s5p_jpeg_qops;
1222 dst_vq->mem_ops = &vb2_dma_contig_memops;
1224 return vb2_queue_init(dst_vq);
1228 * ============================================================================
1229 * ISR
1230 * ============================================================================
1233 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1235 struct s5p_jpeg *jpeg = dev_id;
1236 struct s5p_jpeg_ctx *curr_ctx;
1237 struct vb2_buffer *src_buf, *dst_buf;
1238 unsigned long payload_size = 0;
1239 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1240 bool enc_jpeg_too_large = false;
1241 bool timer_elapsed = false;
1242 bool op_completed = false;
1244 spin_lock(&jpeg->slock);
1246 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1248 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
1249 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
1251 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1252 enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
1253 timer_elapsed = jpeg_timer_stat(jpeg->regs);
1254 op_completed = jpeg_result_stat_ok(jpeg->regs);
1255 if (curr_ctx->mode == S5P_JPEG_DECODE)
1256 op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
1258 if (enc_jpeg_too_large) {
1259 state = VB2_BUF_STATE_ERROR;
1260 jpeg_clear_enc_stream_stat(jpeg->regs);
1261 } else if (timer_elapsed) {
1262 state = VB2_BUF_STATE_ERROR;
1263 jpeg_clear_timer_stat(jpeg->regs);
1264 } else if (!op_completed) {
1265 state = VB2_BUF_STATE_ERROR;
1266 } else {
1267 payload_size = jpeg_compressed_size(jpeg->regs);
1270 v4l2_m2m_buf_done(src_buf, state);
1271 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1272 vb2_set_plane_payload(dst_buf, 0, payload_size);
1273 v4l2_m2m_buf_done(dst_buf, state);
1274 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
1276 curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
1277 spin_unlock(&jpeg->slock);
1279 jpeg_clear_int(jpeg->regs);
1281 return IRQ_HANDLED;
1285 * ============================================================================
1286 * Driver basic infrastructure
1287 * ============================================================================
1290 static int s5p_jpeg_probe(struct platform_device *pdev)
1292 struct s5p_jpeg *jpeg;
1293 struct resource *res;
1294 int ret;
1296 /* JPEG IP abstraction struct */
1297 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1298 if (!jpeg)
1299 return -ENOMEM;
1301 mutex_init(&jpeg->lock);
1302 spin_lock_init(&jpeg->slock);
1303 jpeg->dev = &pdev->dev;
1305 /* memory-mapped registers */
1306 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1308 jpeg->regs = devm_request_and_ioremap(&pdev->dev, res);
1309 if (jpeg->regs == NULL) {
1310 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1311 return -ENOENT;
1314 /* interrupt service routine registration */
1315 jpeg->irq = ret = platform_get_irq(pdev, 0);
1316 if (ret < 0) {
1317 dev_err(&pdev->dev, "cannot find IRQ\n");
1318 return ret;
1321 ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0,
1322 dev_name(&pdev->dev), jpeg);
1323 if (ret) {
1324 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1325 return ret;
1328 /* clocks */
1329 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1330 if (IS_ERR(jpeg->clk)) {
1331 dev_err(&pdev->dev, "cannot get clock\n");
1332 ret = PTR_ERR(jpeg->clk);
1333 return ret;
1335 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1336 clk_enable(jpeg->clk);
1338 /* v4l2 device */
1339 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1340 if (ret) {
1341 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1342 goto clk_get_rollback;
1345 /* mem2mem device */
1346 jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops);
1347 if (IS_ERR(jpeg->m2m_dev)) {
1348 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1349 ret = PTR_ERR(jpeg->m2m_dev);
1350 goto device_register_rollback;
1353 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1354 if (IS_ERR(jpeg->alloc_ctx)) {
1355 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1356 ret = PTR_ERR(jpeg->alloc_ctx);
1357 goto m2m_init_rollback;
1360 /* JPEG encoder /dev/videoX node */
1361 jpeg->vfd_encoder = video_device_alloc();
1362 if (!jpeg->vfd_encoder) {
1363 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1364 ret = -ENOMEM;
1365 goto vb2_allocator_rollback;
1367 strlcpy(jpeg->vfd_encoder->name, S5P_JPEG_M2M_NAME,
1368 sizeof(jpeg->vfd_encoder->name));
1369 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1370 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1371 jpeg->vfd_encoder->minor = -1;
1372 jpeg->vfd_encoder->release = video_device_release;
1373 jpeg->vfd_encoder->lock = &jpeg->lock;
1374 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1375 /* Locking in file operations other than ioctl should be done
1376 by the driver, not the V4L2 core.
1377 This driver needs auditing so that this flag can be removed. */
1378 set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_encoder->flags);
1380 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1381 if (ret) {
1382 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1383 goto enc_vdev_alloc_rollback;
1386 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1387 v4l2_info(&jpeg->v4l2_dev,
1388 "encoder device registered as /dev/video%d\n",
1389 jpeg->vfd_encoder->num);
1391 /* JPEG decoder /dev/videoX node */
1392 jpeg->vfd_decoder = video_device_alloc();
1393 if (!jpeg->vfd_decoder) {
1394 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1395 ret = -ENOMEM;
1396 goto enc_vdev_register_rollback;
1398 strlcpy(jpeg->vfd_decoder->name, S5P_JPEG_M2M_NAME,
1399 sizeof(jpeg->vfd_decoder->name));
1400 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1401 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1402 jpeg->vfd_decoder->minor = -1;
1403 jpeg->vfd_decoder->release = video_device_release;
1404 jpeg->vfd_decoder->lock = &jpeg->lock;
1405 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1406 /* Locking in file operations other than ioctl should be done by the driver,
1407 not the V4L2 core.
1408 This driver needs auditing so that this flag can be removed. */
1409 set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_decoder->flags);
1411 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1412 if (ret) {
1413 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1414 goto dec_vdev_alloc_rollback;
1417 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1418 v4l2_info(&jpeg->v4l2_dev,
1419 "decoder device registered as /dev/video%d\n",
1420 jpeg->vfd_decoder->num);
1422 /* final statements & power management */
1423 platform_set_drvdata(pdev, jpeg);
1425 pm_runtime_enable(&pdev->dev);
1427 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1429 return 0;
1431 dec_vdev_alloc_rollback:
1432 video_device_release(jpeg->vfd_decoder);
1434 enc_vdev_register_rollback:
1435 video_unregister_device(jpeg->vfd_encoder);
1437 enc_vdev_alloc_rollback:
1438 video_device_release(jpeg->vfd_encoder);
1440 vb2_allocator_rollback:
1441 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1443 m2m_init_rollback:
1444 v4l2_m2m_release(jpeg->m2m_dev);
1446 device_register_rollback:
1447 v4l2_device_unregister(&jpeg->v4l2_dev);
1449 clk_get_rollback:
1450 clk_disable(jpeg->clk);
1451 clk_put(jpeg->clk);
1453 return ret;
1456 static int s5p_jpeg_remove(struct platform_device *pdev)
1458 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
1460 pm_runtime_disable(jpeg->dev);
1462 video_unregister_device(jpeg->vfd_decoder);
1463 video_device_release(jpeg->vfd_decoder);
1464 video_unregister_device(jpeg->vfd_encoder);
1465 video_device_release(jpeg->vfd_encoder);
1466 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1467 v4l2_m2m_release(jpeg->m2m_dev);
1468 v4l2_device_unregister(&jpeg->v4l2_dev);
1470 clk_disable(jpeg->clk);
1471 clk_put(jpeg->clk);
1473 return 0;
1476 static int s5p_jpeg_runtime_suspend(struct device *dev)
1478 return 0;
1481 static int s5p_jpeg_runtime_resume(struct device *dev)
1483 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1485 * JPEG IP allows storing two Huffman tables for each component
1486 * We fill table 0 for each component
1488 jpeg_set_hdctbl(jpeg->regs);
1489 jpeg_set_hdctblg(jpeg->regs);
1490 jpeg_set_hactbl(jpeg->regs);
1491 jpeg_set_hactblg(jpeg->regs);
1492 return 0;
1495 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
1496 .runtime_suspend = s5p_jpeg_runtime_suspend,
1497 .runtime_resume = s5p_jpeg_runtime_resume,
1500 static struct platform_driver s5p_jpeg_driver = {
1501 .probe = s5p_jpeg_probe,
1502 .remove = s5p_jpeg_remove,
1503 .driver = {
1504 .owner = THIS_MODULE,
1505 .name = S5P_JPEG_M2M_NAME,
1506 .pm = &s5p_jpeg_pm_ops,
1510 module_platform_driver(s5p_jpeg_driver);
1512 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
1513 MODULE_DESCRIPTION("Samsung JPEG codec driver");
1514 MODULE_LICENSE("GPL");