1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43#include <linux/kernel.h>
44#include <linux/module.h>
45#include <linux/io.h>
46#include <linux/clk.h>
47#include <linux/of_platform.h>
48#include <linux/platform_device.h>
49#include <linux/slab.h>
50#include <linux/irqreturn.h>
51#include <linux/interrupt.h>
52#include <linux/pm_domain.h>
53#include <linux/string.h>
54
55#include <media/v4l2-jpeg.h>
56#include <media/v4l2-mem2mem.h>
57#include <media/v4l2-ioctl.h>
58#include <media/v4l2-common.h>
59#include <media/v4l2-event.h>
60#include <media/videobuf2-dma-contig.h>
61
62#include "mxc-jpeg-hw.h"
63#include "mxc-jpeg.h"
64
65static const struct mxc_jpeg_fmt mxc_formats[] = {
66 {
67 .name = "JPEG",
68 .fourcc = V4L2_PIX_FMT_JPEG,
69 .subsampling = -1,
70 .nc = -1,
71 .colplanes = 1,
72 .flags = MXC_JPEG_FMT_TYPE_ENC,
73 },
74 {
75 .name = "RGB",
76 .fourcc = V4L2_PIX_FMT_RGB24,
77 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
78 .nc = 3,
79 .depth = 24,
80 .colplanes = 1,
81 .h_align = 3,
82 .v_align = 3,
83 .flags = MXC_JPEG_FMT_TYPE_RAW,
84 },
85 {
86 .name = "ARGB",
87 .fourcc = V4L2_PIX_FMT_ARGB32,
88 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
89 .nc = 4,
90 .depth = 32,
91 .colplanes = 1,
92 .h_align = 3,
93 .v_align = 3,
94 .flags = MXC_JPEG_FMT_TYPE_RAW,
95 },
96 {
97 .name = "YUV420",
98 .fourcc = V4L2_PIX_FMT_NV12,
99 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
100 .nc = 3,
101 .depth = 12,
102 .colplanes = 2,
103 .h_align = 4,
104 .v_align = 4,
105 .flags = MXC_JPEG_FMT_TYPE_RAW,
106 },
107 {
108 .name = "YUV422",
109 .fourcc = V4L2_PIX_FMT_YUYV,
110 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
111 .nc = 3,
112 .depth = 16,
113 .colplanes = 1,
114 .h_align = 4,
115 .v_align = 3,
116 .flags = MXC_JPEG_FMT_TYPE_RAW,
117 },
118 {
119 .name = "YUV444",
120 .fourcc = V4L2_PIX_FMT_YUV24,
121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
122 .nc = 3,
123 .depth = 24,
124 .colplanes = 1,
125 .h_align = 3,
126 .v_align = 3,
127 .flags = MXC_JPEG_FMT_TYPE_RAW,
128 },
129 {
130 .name = "Gray",
131 .fourcc = V4L2_PIX_FMT_GREY,
132 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
133 .nc = 1,
134 .depth = 8,
135 .colplanes = 1,
136 .h_align = 3,
137 .v_align = 3,
138 .flags = MXC_JPEG_FMT_TYPE_RAW,
139 },
140};
141
142#define MXC_JPEG_NUM_FORMATS ARRAY_SIZE(mxc_formats)
143
144static const int mxc_decode_mode = MXC_JPEG_DECODE;
145static const int mxc_encode_mode = MXC_JPEG_ENCODE;
146
147static const struct of_device_id mxc_jpeg_match[] = {
148 {
149 .compatible = "nxp,imx8qxp-jpgdec",
150 .data = &mxc_decode_mode,
151 },
152 {
153 .compatible = "nxp,imx8qxp-jpgenc",
154 .data = &mxc_encode_mode,
155 },
156 { },
157};
158
159
160
161
162
163static const unsigned char jpeg_soi[] = {
164 0xFF, 0xD8
165};
166
167static const unsigned char jpeg_app0[] = {
168 0xFF, 0xE0,
169 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00,
170 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
171 0x00, 0x00
172};
173
174static const unsigned char jpeg_app14[] = {
175 0xFF, 0xEE,
176 0x00, 0x0E, 0x41, 0x64, 0x6F, 0x62, 0x65,
177 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00
178};
179
180static const unsigned char jpeg_dqt[] = {
181 0xFF, 0xDB,
182 0x00, 0x84, 0x00, 0x10, 0x0B, 0x0C, 0x0E,
183 0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E, 0x12,
184 0x11, 0x10, 0x13, 0x18, 0x28, 0x1A, 0x18,
185 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1D,
186 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33,
187 0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40,
188 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6D,
189 0x51, 0x57, 0x5F, 0x62, 0x67, 0x68, 0x67,
190 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64, 0x78,
191 0x5C, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12,
192 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A, 0x1A,
193 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
194 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
195 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
196 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
197 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
198 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
199 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
200 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
201};
202
203static const unsigned char jpeg_sof_maximal[] = {
204 0xFF, 0xC0,
205 0x00, 0x14, 0x08, 0x00, 0x40, 0x00, 0x40,
206 0x04, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01,
207 0x03, 0x11, 0x01, 0x04, 0x11, 0x01
208};
209
210static const unsigned char jpeg_dht[] = {
211 0xFF, 0xC4,
212 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01,
213 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
215 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
216 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01,
217 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05,
218 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
219 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
220 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
221 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91,
222 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15,
223 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
224 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
225 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
226 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
227 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
228 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
229 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
230 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76,
231 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85,
232 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
233 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
234 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
235 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
236 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
237 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
238 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
239 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
240 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
241 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
242 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01,
243 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
245 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
246 0x0B, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,
247 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
248 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
249 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
250 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13,
251 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
252 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52,
253 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
254 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18,
255 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
256 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43,
257 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
258 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
259 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
260 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
261 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85,
262 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
263 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
264 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
265 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
266 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
267 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
268 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
269 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
270 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5,
271 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
272};
273
274static const unsigned char jpeg_dri[] = {
275 0xFF, 0xDD,
276 0x00, 0x04, 0x00, 0x20
277};
278
279static const unsigned char jpeg_sos_maximal[] = {
280 0xFF, 0xDA,
281 0x00, 0x0C, 0x04, 0x01, 0x00, 0x02, 0x11, 0x03,
282 0x11, 0x04, 0x11, 0x00, 0x3F, 0x00
283};
284
285static const unsigned char jpeg_eoi[] = {
286 0xFF, 0xD9
287};
288
289struct mxc_jpeg_src_buf {
290
291 struct vb2_v4l2_buffer b;
292 struct list_head list;
293
294
295 bool dht_needed;
296 bool jpeg_parse_error;
297};
298
299static inline struct mxc_jpeg_src_buf *vb2_to_mxc_buf(struct vb2_buffer *vb)
300{
301 return container_of(to_vb2_v4l2_buffer(vb),
302 struct mxc_jpeg_src_buf, b);
303}
304
305static unsigned int debug;
306module_param(debug, int, 0644);
307MODULE_PARM_DESC(debug, "Debug level (0-3)");
308
309static void _bswap16(u16 *a)
310{
311 *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
312}
313
314static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf,
315 unsigned long len)
316{
317 unsigned int plane_no;
318 u32 dma_addr;
319 void *vaddr;
320 unsigned long payload;
321
322 if (debug < 3)
323 return;
324
325 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) {
326 payload = vb2_get_plane_payload(buf, plane_no);
327 if (len == 0)
328 len = payload;
329 dma_addr = vb2_dma_contig_plane_dma_addr(buf, plane_no);
330 vaddr = vb2_plane_vaddr(buf, plane_no);
331 v4l2_dbg(3, debug, &jpeg->v4l2_dev,
332 "plane %d (vaddr=%p dma_addr=%x payload=%ld):",
333 plane_no, vaddr, dma_addr, payload);
334 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
335 vaddr, len, false);
336 }
337}
338
339static inline struct mxc_jpeg_ctx *mxc_jpeg_fh_to_ctx(struct v4l2_fh *fh)
340{
341 return container_of(fh, struct mxc_jpeg_ctx, fh);
342}
343
344static int enum_fmt(const struct mxc_jpeg_fmt *mxc_formats, int n,
345 struct v4l2_fmtdesc *f, u32 type)
346{
347 int i, num = 0;
348
349 for (i = 0; i < n; ++i) {
350 if (mxc_formats[i].flags == type) {
351
352 if (num == f->index)
353 break;
354
355
356
357 ++num;
358 }
359 }
360
361
362 if (i >= n)
363 return -EINVAL;
364
365 strscpy(f->description, mxc_formats[i].name, sizeof(f->description));
366 f->pixelformat = mxc_formats[i].fourcc;
367
368 return 0;
369}
370
371static const struct mxc_jpeg_fmt *mxc_jpeg_find_format(struct mxc_jpeg_ctx *ctx,
372 u32 pixelformat)
373{
374 unsigned int k;
375
376 for (k = 0; k < MXC_JPEG_NUM_FORMATS; k++) {
377 const struct mxc_jpeg_fmt *fmt = &mxc_formats[k];
378
379 if (fmt->fourcc == pixelformat)
380 return fmt;
381 }
382 return NULL;
383}
384
385static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc)
386{
387 switch (fourcc) {
388 case V4L2_PIX_FMT_GREY:
389 return MXC_JPEG_GRAY;
390 case V4L2_PIX_FMT_YUYV:
391 return MXC_JPEG_YUV422;
392 case V4L2_PIX_FMT_NV12:
393 return MXC_JPEG_YUV420;
394 case V4L2_PIX_FMT_YUV24:
395 return MXC_JPEG_YUV444;
396 case V4L2_PIX_FMT_RGB24:
397 return MXC_JPEG_RGB;
398 case V4L2_PIX_FMT_ARGB32:
399 return MXC_JPEG_ARGB;
400 default:
401 return MXC_JPEG_INVALID;
402 }
403}
404
405static struct mxc_jpeg_q_data *mxc_jpeg_get_q_data(struct mxc_jpeg_ctx *ctx,
406 enum v4l2_buf_type type)
407{
408 if (V4L2_TYPE_IS_OUTPUT(type))
409 return &ctx->out_q;
410 return &ctx->cap_q;
411}
412
413static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc,
414 struct vb2_buffer *raw_buf,
415 struct vb2_buffer *jpeg_buf, int offset)
416{
417 int img_fmt = desc->stm_ctrl & STM_CTRL_IMAGE_FORMAT_MASK;
418
419 desc->buf_base0 = vb2_dma_contig_plane_dma_addr(raw_buf, 0);
420 desc->buf_base1 = 0;
421 if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) {
422 WARN_ON(raw_buf->num_planes < 2);
423 desc->buf_base1 = vb2_dma_contig_plane_dma_addr(raw_buf, 1);
424 }
425 desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(jpeg_buf, 0) +
426 offset;
427}
428
429static void notify_eos(struct mxc_jpeg_ctx *ctx)
430{
431 const struct v4l2_event ev = {
432 .type = V4L2_EVENT_EOS
433 };
434
435 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event EOS reached");
436 v4l2_event_queue_fh(&ctx->fh, &ev);
437}
438
439static void notify_src_chg(struct mxc_jpeg_ctx *ctx)
440{
441 const struct v4l2_event ev = {
442 .type = V4L2_EVENT_SOURCE_CHANGE,
443 .u.src_change.changes =
444 V4L2_EVENT_SRC_CH_RESOLUTION,
445 };
446
447 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event SRC_CH_RESOLUTION");
448 v4l2_event_queue_fh(&ctx->fh, &ev);
449}
450
451static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n)
452{
453 int free_slot = 0;
454
455 while (slot_data[free_slot].used && free_slot < n)
456 free_slot++;
457
458 return free_slot;
459}
460
461static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg,
462 unsigned int slot)
463{
464 struct mxc_jpeg_desc *desc;
465 struct mxc_jpeg_desc *cfg_desc;
466 void *cfg_stm;
467
468 if (jpeg->slot_data[slot].desc)
469 goto skip_alloc;
470
471
472 desc = dma_alloc_coherent(jpeg->dev,
473 sizeof(struct mxc_jpeg_desc),
474 &jpeg->slot_data[slot].desc_handle,
475 GFP_ATOMIC);
476 if (!desc)
477 goto err;
478 jpeg->slot_data[slot].desc = desc;
479
480
481 cfg_desc = dma_alloc_coherent(jpeg->dev,
482 sizeof(struct mxc_jpeg_desc),
483 &jpeg->slot_data[slot].cfg_desc_handle,
484 GFP_ATOMIC);
485 if (!cfg_desc)
486 goto err;
487 jpeg->slot_data[slot].cfg_desc = cfg_desc;
488
489
490 cfg_stm = dma_alloc_coherent(jpeg->dev,
491 MXC_JPEG_MAX_CFG_STREAM,
492 &jpeg->slot_data[slot].cfg_stream_handle,
493 GFP_ATOMIC);
494 if (!cfg_stm)
495 goto err;
496 jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
497
498skip_alloc:
499 jpeg->slot_data[slot].used = true;
500
501 return true;
502err:
503 dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot);
504
505 return false;
506}
507
508static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg,
509 unsigned int slot)
510{
511 if (slot >= MXC_MAX_SLOTS) {
512 dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot);
513 return;
514 }
515
516
517 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
518 jpeg->slot_data[slot].desc,
519 jpeg->slot_data[slot].desc_handle);
520
521
522 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
523 jpeg->slot_data[slot].cfg_desc,
524 jpeg->slot_data[slot].cfg_desc_handle);
525
526
527 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
528 jpeg->slot_data[slot].cfg_stream_vaddr,
529 jpeg->slot_data[slot].cfg_stream_handle);
530
531 jpeg->slot_data[slot].used = false;
532}
533
534static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
535{
536 struct mxc_jpeg_dev *jpeg = priv;
537 struct mxc_jpeg_ctx *ctx;
538 void __iomem *reg = jpeg->base_reg;
539 struct device *dev = jpeg->dev;
540 struct vb2_v4l2_buffer *src_buf, *dst_buf;
541 struct mxc_jpeg_src_buf *jpeg_src_buf;
542 enum vb2_buffer_state buf_state;
543 u32 dec_ret, com_status;
544 unsigned long payload;
545 struct mxc_jpeg_q_data *q_data;
546 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
547 unsigned int slot;
548
549 spin_lock(&jpeg->hw_lock);
550
551 com_status = readl(reg + COM_STATUS);
552 slot = COM_STATUS_CUR_SLOT(com_status);
553 dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot);
554
555 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
556 if (!ctx) {
557 dev_err(dev,
558 "Instance released before the end of transaction.\n");
559
560 mxc_jpeg_sw_reset(reg);
561
562 writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
563 goto job_unlock;
564 }
565
566 if (slot != ctx->slot) {
567
568 dev_warn(dev, "IRQ slot %d != context slot %d.\n",
569 slot, ctx->slot);
570 goto job_unlock;
571 }
572
573 dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
574 writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
575
576 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
577 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
578 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
579
580 if (dec_ret & SLOT_STATUS_ENC_CONFIG_ERR) {
581 u32 ret = readl(reg + CAST_STATUS12);
582
583 dev_err(dev, "Encoder/decoder error, status=0x%08x", ret);
584 mxc_jpeg_sw_reset(reg);
585 buf_state = VB2_BUF_STATE_ERROR;
586 goto buffers_done;
587 }
588
589 if (!(dec_ret & SLOT_STATUS_FRMDONE))
590 goto job_unlock;
591
592 if (jpeg->mode == MXC_JPEG_ENCODE &&
593 ctx->enc_state == MXC_JPEG_ENC_CONF) {
594 ctx->enc_state = MXC_JPEG_ENCODING;
595 dev_dbg(dev, "Encoder config finished. Start encoding...\n");
596 mxc_jpeg_enc_mode_go(dev, reg);
597 goto job_unlock;
598 }
599 if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed) {
600 jpeg_src_buf->dht_needed = false;
601 dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
602 goto job_unlock;
603 }
604 if (jpeg->mode == MXC_JPEG_ENCODE) {
605 payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
606 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
607 dev_dbg(dev, "Encoding finished, payload size: %ld\n",
608 payload);
609 } else {
610 q_data = mxc_jpeg_get_q_data(ctx, cap_type);
611 payload = q_data->sizeimage[0];
612 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
613 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
614 if (q_data->fmt->colplanes == 2) {
615 payload = q_data->sizeimage[1];
616 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload);
617 }
618 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n",
619 vb2_get_plane_payload(&dst_buf->vb2_buf, 0),
620 vb2_get_plane_payload(&dst_buf->vb2_buf, 1));
621 }
622
623
624 dev_dbg(dev, "src_buf preview: ");
625 print_mxc_buf(jpeg, &src_buf->vb2_buf, 32);
626 dev_dbg(dev, "dst_buf preview: ");
627 print_mxc_buf(jpeg, &dst_buf->vb2_buf, 32);
628 buf_state = VB2_BUF_STATE_DONE;
629
630buffers_done:
631 jpeg->slot_data[slot].used = false;
632 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
633 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
634 v4l2_m2m_buf_done(src_buf, buf_state);
635 v4l2_m2m_buf_done(dst_buf, buf_state);
636 spin_unlock(&jpeg->hw_lock);
637 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
638 return IRQ_HANDLED;
639job_unlock:
640 spin_unlock(&jpeg->hw_lock);
641 return IRQ_HANDLED;
642}
643
644static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof,
645 u32 fourcc,
646 u16 w, u16 h)
647{
648 int sof_length;
649
650 sof->precision = 8;
651 sof->height = h;
652 _bswap16(&sof->height);
653 sof->width = w;
654 _bswap16(&sof->width);
655
656 switch (fourcc) {
657 case V4L2_PIX_FMT_NV12:
658 sof->components_no = 3;
659 sof->comp[0].v = 0x2;
660 sof->comp[0].h = 0x2;
661 break;
662 case V4L2_PIX_FMT_YUYV:
663 sof->components_no = 3;
664 sof->comp[0].v = 0x1;
665 sof->comp[0].h = 0x2;
666 break;
667 case V4L2_PIX_FMT_YUV24:
668 case V4L2_PIX_FMT_RGB24:
669 default:
670 sof->components_no = 3;
671 break;
672 case V4L2_PIX_FMT_ARGB32:
673 sof->components_no = 4;
674 break;
675 case V4L2_PIX_FMT_GREY:
676 sof->components_no = 1;
677 break;
678 }
679 sof_length = 8 + 3 * sof->components_no;
680 sof->length = sof_length;
681 _bswap16(&sof->length);
682
683 return sof_length;
684}
685
686static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos,
687 u32 fourcc)
688{
689 int sos_length;
690 u8 *sof_u8 = (u8 *)sos;
691
692 switch (fourcc) {
693 case V4L2_PIX_FMT_NV12:
694 sos->components_no = 3;
695 break;
696 case V4L2_PIX_FMT_YUYV:
697 sos->components_no = 3;
698 break;
699 case V4L2_PIX_FMT_YUV24:
700 case V4L2_PIX_FMT_RGB24:
701 default:
702 sos->components_no = 3;
703 break;
704 case V4L2_PIX_FMT_ARGB32:
705 sos->components_no = 4;
706 break;
707 case V4L2_PIX_FMT_GREY:
708 sos->components_no = 1;
709 break;
710 }
711 sos_length = 6 + 2 * sos->components_no;
712 sos->length = sos_length;
713 _bswap16(&sos->length);
714
715
716 sof_u8[sos_length - 1] = 0x0;
717 sof_u8[sos_length - 2] = 0x3f;
718 sof_u8[sos_length - 3] = 0x0;
719
720 return sos_length;
721}
722
723static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr,
724 u32 fourcc,
725 u16 w, u16 h)
726{
727 unsigned int offset = 0;
728 u8 *cfg = (u8 *)cfg_stream_vaddr;
729 struct mxc_jpeg_sof *sof;
730 struct mxc_jpeg_sos *sos;
731
732 memcpy(cfg + offset, jpeg_soi, ARRAY_SIZE(jpeg_soi));
733 offset += ARRAY_SIZE(jpeg_soi);
734
735 if (fourcc == V4L2_PIX_FMT_RGB24 ||
736 fourcc == V4L2_PIX_FMT_ARGB32) {
737 memcpy(cfg + offset, jpeg_app14, sizeof(jpeg_app14));
738 offset += sizeof(jpeg_app14);
739 } else {
740 memcpy(cfg + offset, jpeg_app0, sizeof(jpeg_app0));
741 offset += sizeof(jpeg_app0);
742 }
743
744 memcpy(cfg + offset, jpeg_dqt, sizeof(jpeg_dqt));
745 offset += sizeof(jpeg_dqt);
746
747 memcpy(cfg + offset, jpeg_sof_maximal, sizeof(jpeg_sof_maximal));
748 offset += 2;
749 sof = (struct mxc_jpeg_sof *)(cfg + offset);
750 offset += mxc_jpeg_fixup_sof(sof, fourcc, w, h);
751
752 memcpy(cfg + offset, jpeg_dht, sizeof(jpeg_dht));
753 offset += sizeof(jpeg_dht);
754
755 memcpy(cfg + offset, jpeg_dri, sizeof(jpeg_dri));
756 offset += sizeof(jpeg_dri);
757
758 memcpy(cfg + offset, jpeg_sos_maximal, sizeof(jpeg_sos_maximal));
759 offset += 2;
760 sos = (struct mxc_jpeg_sos *)(cfg + offset);
761 offset += mxc_jpeg_fixup_sos(sos, fourcc);
762
763 memcpy(cfg + offset, jpeg_eoi, sizeof(jpeg_eoi));
764 offset += sizeof(jpeg_eoi);
765
766 return offset;
767}
768
769static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
770 struct mxc_jpeg_ctx *ctx,
771 struct vb2_buffer *src_buf,
772 struct vb2_buffer *dst_buf)
773{
774 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
775 struct mxc_jpeg_q_data *q_data_cap;
776 enum mxc_jpeg_image_format img_fmt;
777 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
778 void __iomem *reg = jpeg->base_reg;
779 unsigned int slot = ctx->slot;
780 struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
781 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
782 dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
783 dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
784 dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle;
785 unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size;
786 void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr;
787 struct mxc_jpeg_src_buf *jpeg_src_buf;
788
789 jpeg_src_buf = vb2_to_mxc_buf(src_buf);
790
791
792 desc->next_descpt_ptr = 0;
793 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
794 desc->imgsize = q_data_cap->w_adjusted << 16 | q_data_cap->h_adjusted;
795 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc);
796 desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF);
797 desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt);
798 desc->line_pitch = q_data_cap->bytesperline[0];
799 mxc_jpeg_addrs(desc, dst_buf, src_buf, 0);
800 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(src_buf, 0), 1024));
801 print_descriptor_info(jpeg->dev, desc);
802
803 if (!jpeg_src_buf->dht_needed) {
804
805 mxc_jpeg_set_desc(desc_handle, reg, slot);
806 return;
807 }
808
809
810
811
812
813 *cfg_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
814 V4L2_PIX_FMT_YUYV,
815 MXC_JPEG_MIN_WIDTH,
816 MXC_JPEG_MIN_HEIGHT);
817 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
818 cfg_desc->buf_base0 = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
819 cfg_desc->buf_base1 = 0;
820 cfg_desc->imgsize = MXC_JPEG_MIN_WIDTH << 16;
821 cfg_desc->imgsize |= MXC_JPEG_MIN_HEIGHT;
822 cfg_desc->line_pitch = MXC_JPEG_MIN_WIDTH * 2;
823 cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422);
824 cfg_desc->stm_bufbase = cfg_stream_handle;
825 cfg_desc->stm_bufsize = ALIGN(*cfg_size, 1024);
826 print_descriptor_info(jpeg->dev, cfg_desc);
827
828
829 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
830}
831
832static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
833 struct mxc_jpeg_ctx *ctx,
834 struct vb2_buffer *src_buf,
835 struct vb2_buffer *dst_buf)
836{
837 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
838 void __iomem *reg = jpeg->base_reg;
839 unsigned int slot = ctx->slot;
840 struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
841 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
842 dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
843 dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
844 void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr;
845 struct mxc_jpeg_q_data *q_data;
846 enum mxc_jpeg_image_format img_fmt;
847 int w, h;
848
849 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type);
850
851 jpeg->slot_data[slot].cfg_stream_size =
852 mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
853 q_data->fmt->fourcc,
854 q_data->w_adjusted,
855 q_data->h_adjusted);
856
857
858 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
859
860 cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle;
861 cfg_desc->buf_base1 = 0;
862 cfg_desc->line_pitch = 0;
863 cfg_desc->stm_bufbase = 0;
864 cfg_desc->stm_bufsize = 0x0;
865 cfg_desc->imgsize = 0;
866 cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1);
867
868 desc->next_descpt_ptr = 0;
869
870
871 w = q_data->w_adjusted;
872 h = q_data->h_adjusted;
873 mxc_jpeg_set_res(desc, w, h);
874 mxc_jpeg_set_line_pitch(desc, w * (q_data->fmt->depth / 8));
875 mxc_jpeg_set_bufsize(desc, desc->line_pitch * h);
876 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc);
877 if (img_fmt == MXC_JPEG_INVALID)
878 dev_err(jpeg->dev, "No valid image format detected\n");
879 desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) |
880 STM_CTRL_IMAGE_FORMAT(img_fmt);
881 mxc_jpeg_addrs(desc, src_buf, dst_buf, 0);
882 dev_dbg(jpeg->dev, "cfg_desc:\n");
883 print_descriptor_info(jpeg->dev, cfg_desc);
884 dev_dbg(jpeg->dev, "enc desc:\n");
885 print_descriptor_info(jpeg->dev, desc);
886 print_wrapper_info(jpeg->dev, reg);
887 print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE);
888
889
890 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
891}
892
893static void mxc_jpeg_device_run(void *priv)
894{
895 struct mxc_jpeg_ctx *ctx = priv;
896 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
897 void __iomem *reg = jpeg->base_reg;
898 struct device *dev = jpeg->dev;
899 struct vb2_v4l2_buffer *src_buf, *dst_buf;
900 unsigned long flags;
901 struct mxc_jpeg_q_data *q_data_cap, *q_data_out;
902 struct mxc_jpeg_src_buf *jpeg_src_buf;
903
904 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
905 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
906 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
907 if (!src_buf || !dst_buf) {
908 dev_err(dev, "Null src or dst buf\n");
909 goto end;
910 }
911
912 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
913 if (!q_data_cap)
914 goto end;
915 q_data_out = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
916 if (!q_data_out)
917 goto end;
918 src_buf->sequence = q_data_out->sequence++;
919 dst_buf->sequence = q_data_cap->sequence++;
920
921 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
922
923 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
924 if (jpeg_src_buf->jpeg_parse_error) {
925 jpeg->slot_data[ctx->slot].used = false;
926 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
927 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
928 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
929 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
930 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
931 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
932
933 return;
934 }
935
936
937
938
939
940 mxc_jpeg_sw_reset(reg);
941 mxc_jpeg_enable(reg);
942 mxc_jpeg_set_l_endian(reg, 1);
943
944 ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS);
945 if (ctx->slot >= MXC_MAX_SLOTS) {
946 dev_err(dev, "No more free slots\n");
947 goto end;
948 }
949 if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) {
950 dev_err(dev, "Cannot allocate slot data\n");
951 goto end;
952 }
953
954 mxc_jpeg_enable_slot(reg, ctx->slot);
955 mxc_jpeg_enable_irq(reg, ctx->slot);
956
957 if (jpeg->mode == MXC_JPEG_ENCODE) {
958 dev_dbg(dev, "Encoding on slot %d\n", ctx->slot);
959 ctx->enc_state = MXC_JPEG_ENC_CONF;
960 mxc_jpeg_config_enc_desc(&dst_buf->vb2_buf, ctx,
961 &src_buf->vb2_buf, &dst_buf->vb2_buf);
962 mxc_jpeg_enc_mode_conf(dev, reg);
963 } else {
964 dev_dbg(dev, "Decoding on slot %d\n", ctx->slot);
965 print_mxc_buf(jpeg, &src_buf->vb2_buf, 0);
966 mxc_jpeg_config_dec_desc(&dst_buf->vb2_buf, ctx,
967 &src_buf->vb2_buf, &dst_buf->vb2_buf);
968 mxc_jpeg_dec_mode_go(dev, reg);
969 }
970end:
971 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
972}
973
974static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
975 struct v4l2_decoder_cmd *cmd)
976{
977 struct v4l2_fh *fh = file->private_data;
978 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
979 struct device *dev = ctx->mxc_jpeg->dev;
980 int ret;
981
982 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
983 if (ret < 0)
984 return ret;
985
986 if (cmd->cmd == V4L2_DEC_CMD_STOP) {
987 dev_dbg(dev, "Received V4L2_DEC_CMD_STOP");
988 if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
989
990 notify_eos(ctx);
991 } else {
992
993 ctx->stopping = 1;
994 }
995 }
996
997 return 0;
998}
999
1000static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
1001 struct v4l2_encoder_cmd *cmd)
1002{
1003 struct v4l2_fh *fh = file->private_data;
1004 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
1005 struct device *dev = ctx->mxc_jpeg->dev;
1006 int ret;
1007
1008 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
1009 if (ret < 0)
1010 return ret;
1011
1012 if (cmd->cmd == V4L2_ENC_CMD_STOP) {
1013 dev_dbg(dev, "Received V4L2_ENC_CMD_STOP");
1014 if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
1015
1016 notify_eos(ctx);
1017 } else {
1018
1019 ctx->stopping = 1;
1020 }
1021 }
1022
1023 return 0;
1024}
1025
1026static int mxc_jpeg_queue_setup(struct vb2_queue *q,
1027 unsigned int *nbuffers,
1028 unsigned int *nplanes,
1029 unsigned int sizes[],
1030 struct device *alloc_ctxs[])
1031{
1032 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1033 struct mxc_jpeg_q_data *q_data = NULL;
1034 int i;
1035
1036 q_data = mxc_jpeg_get_q_data(ctx, q->type);
1037 if (!q_data)
1038 return -EINVAL;
1039
1040
1041 if (*nplanes) {
1042 for (i = 0; i < *nplanes; i++) {
1043 if (sizes[i] < q_data->sizeimage[i])
1044 return -EINVAL;
1045 }
1046 return 0;
1047 }
1048
1049
1050 *nplanes = q_data->fmt->colplanes;
1051 for (i = 0; i < *nplanes; i++)
1052 sizes[i] = q_data->sizeimage[i];
1053
1054 return 0;
1055}
1056
1057static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1058{
1059 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1060 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
1061
1062 dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
1063 q_data->sequence = 0;
1064
1065 return 0;
1066}
1067
1068static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
1069{
1070 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1071 struct vb2_v4l2_buffer *vbuf;
1072
1073 dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx);
1074
1075
1076 for (;;) {
1077 if (V4L2_TYPE_IS_OUTPUT(q->type))
1078 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1079 else
1080 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1081 if (!vbuf)
1082 return;
1083 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1084 }
1085}
1086
1087static int mxc_jpeg_valid_comp_id(struct device *dev,
1088 struct mxc_jpeg_sof *sof,
1089 struct mxc_jpeg_sos *sos)
1090{
1091 int valid = 1;
1092 int i;
1093
1094
1095
1096
1097
1098 for (i = 0; i < sof->components_no; i++)
1099 if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) {
1100 valid = 0;
1101 dev_err(dev, "Component %d has invalid ID: %d",
1102 i, sof->comp[i].id);
1103 }
1104 if (!valid)
1105
1106 for (i = 0; i < sof->components_no; i++) {
1107 dev_warn(dev, "Component %d ID patched to: %d",
1108 i, i + 1);
1109 sof->comp[i].id = i + 1;
1110 sos->comp[i].id = i + 1;
1111 }
1112
1113 return valid;
1114}
1115
1116static u32 mxc_jpeg_get_image_format(struct device *dev,
1117 const struct v4l2_jpeg_header *header)
1118{
1119 int i;
1120 u32 fourcc = 0;
1121
1122 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++)
1123 if (mxc_formats[i].subsampling == header->frame.subsampling &&
1124 mxc_formats[i].nc == header->frame.num_components) {
1125 fourcc = mxc_formats[i].fourcc;
1126 break;
1127 }
1128 if (fourcc == 0) {
1129 dev_err(dev, "Could not identify image format nc=%d, subsampling=%d\n",
1130 header->frame.num_components,
1131 header->frame.subsampling);
1132 return fourcc;
1133 }
1134
1135
1136
1137
1138
1139 if (fourcc == V4L2_PIX_FMT_YUV24 || fourcc == V4L2_PIX_FMT_RGB24) {
1140 if (header->app14_tf == V4L2_JPEG_APP14_TF_CMYK_RGB)
1141 fourcc = V4L2_PIX_FMT_RGB24;
1142 else
1143 fourcc = V4L2_PIX_FMT_YUV24;
1144 }
1145
1146 return fourcc;
1147}
1148
1149static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
1150 u32 precision)
1151{
1152
1153 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1154
1155 q->bytesperline[0] = 0;
1156 q->bytesperline[1] = 0;
1157 } else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12) {
1158
1159
1160
1161
1162 q->bytesperline[0] = q->w * (precision / 8) *
1163 (q->fmt->depth / 8);
1164 q->bytesperline[1] = q->bytesperline[0];
1165 } else {
1166
1167 q->bytesperline[0] = q->w * (precision / 8) *
1168 (q->fmt->depth / 8);
1169 q->bytesperline[1] = 0;
1170 }
1171}
1172
1173static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
1174{
1175 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1176
1177 if (!q->sizeimage[0])
1178 q->sizeimage[0] = 6 * q->w * q->h;
1179 q->sizeimage[1] = 0;
1180
1181 if (q->sizeimage[0] > MXC_JPEG_MAX_SIZEIMAGE)
1182 q->sizeimage[0] = MXC_JPEG_MAX_SIZEIMAGE;
1183
1184
1185 q->sizeimage[0] = ALIGN(q->sizeimage[0], 1024);
1186 } else {
1187 q->sizeimage[0] = q->bytesperline[0] * q->h;
1188 q->sizeimage[1] = 0;
1189 if (q->fmt->fourcc == V4L2_PIX_FMT_NV12)
1190 q->sizeimage[1] = q->sizeimage[0] / 2;
1191 }
1192}
1193
1194static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
1195 u8 *src_addr, u32 size, bool *dht_needed)
1196{
1197 struct device *dev = ctx->mxc_jpeg->dev;
1198 struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
1199 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1200 bool src_chg = false;
1201 u32 fourcc;
1202 struct v4l2_jpeg_header header;
1203 struct mxc_jpeg_sof *psof = NULL;
1204 struct mxc_jpeg_sos *psos = NULL;
1205 int ret;
1206
1207 memset(&header, 0, sizeof(header));
1208 ret = v4l2_jpeg_parse_header((void *)src_addr, size, &header);
1209 if (ret < 0) {
1210 dev_err(dev, "Error parsing JPEG stream markers\n");
1211 return ret;
1212 }
1213
1214
1215 *dht_needed = (header.num_dht == 0);
1216
1217 q_data_out = mxc_jpeg_get_q_data(ctx,
1218 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1219 if (q_data_out->w == 0 && q_data_out->h == 0) {
1220 dev_warn(dev, "Invalid user resolution 0x0");
1221 dev_warn(dev, "Keeping resolution from JPEG: %dx%d",
1222 header.frame.width, header.frame.height);
1223 q_data_out->w = header.frame.width;
1224 q_data_out->h = header.frame.height;
1225 } else if (header.frame.width != q_data_out->w ||
1226 header.frame.height != q_data_out->h) {
1227 dev_err(dev,
1228 "Resolution mismatch: %dx%d (JPEG) versus %dx%d(user)",
1229 header.frame.width, header.frame.height,
1230 q_data_out->w, q_data_out->h);
1231 return -EINVAL;
1232 }
1233 if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) {
1234 dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n",
1235 header.frame.width, header.frame.height);
1236 return -EINVAL;
1237 }
1238 if (header.frame.width > MXC_JPEG_MAX_WIDTH ||
1239 header.frame.height > MXC_JPEG_MAX_HEIGHT) {
1240 dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
1241 header.frame.width, header.frame.height);
1242 return -EINVAL;
1243 }
1244 if (header.frame.width < MXC_JPEG_MIN_WIDTH ||
1245 header.frame.height < MXC_JPEG_MIN_HEIGHT) {
1246 dev_err(dev, "JPEG width or height should be > 64: %dx%d\n",
1247 header.frame.width, header.frame.height);
1248 return -EINVAL;
1249 }
1250 if (header.frame.num_components > V4L2_JPEG_MAX_COMPONENTS) {
1251 dev_err(dev, "JPEG number of components should be <=%d",
1252 V4L2_JPEG_MAX_COMPONENTS);
1253 return -EINVAL;
1254 }
1255
1256 psof = (struct mxc_jpeg_sof *)header.sof.start;
1257 psos = (struct mxc_jpeg_sos *)header.sos.start;
1258 if (!mxc_jpeg_valid_comp_id(dev, psof, psos))
1259 dev_warn(dev, "JPEG component ids should be 0-3 or 1-4");
1260
1261 fourcc = mxc_jpeg_get_image_format(dev, &header);
1262 if (fourcc == 0)
1263 return -EINVAL;
1264
1265
1266
1267
1268
1269 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
1270 if (q_data_cap->w != header.frame.width ||
1271 q_data_cap->h != header.frame.height)
1272 src_chg = true;
1273 q_data_cap->w = header.frame.width;
1274 q_data_cap->h = header.frame.height;
1275 q_data_cap->fmt = mxc_jpeg_find_format(ctx, fourcc);
1276 q_data_cap->w_adjusted = q_data_cap->w;
1277 q_data_cap->h_adjusted = q_data_cap->h;
1278
1279
1280
1281
1282 v4l_bound_align_image(&q_data_cap->w_adjusted,
1283 q_data_cap->w_adjusted,
1284 MXC_JPEG_MAX_WIDTH,
1285 q_data_cap->fmt->h_align,
1286 &q_data_cap->h_adjusted,
1287 q_data_cap->h_adjusted,
1288 MXC_JPEG_MAX_HEIGHT,
1289 q_data_cap->fmt->v_align,
1290 0);
1291 dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
1292 q_data_cap->w, q_data_cap->h,
1293 q_data_cap->w_adjusted, q_data_cap->h_adjusted,
1294 (fourcc & 0xff),
1295 (fourcc >> 8) & 0xff,
1296 (fourcc >> 16) & 0xff,
1297 (fourcc >> 24) & 0xff);
1298
1299
1300 mxc_jpeg_bytesperline(q_data_cap, header.frame.precision);
1301 mxc_jpeg_sizeimage(q_data_cap);
1302
1303
1304
1305
1306
1307
1308 if (src_chg)
1309 notify_src_chg(ctx);
1310
1311 return 0;
1312}
1313
1314static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
1315{
1316 int ret;
1317 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1318 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1319 struct mxc_jpeg_src_buf *jpeg_src_buf;
1320
1321 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1322 goto end;
1323
1324
1325 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
1326 goto end;
1327
1328 jpeg_src_buf = vb2_to_mxc_buf(vb);
1329 jpeg_src_buf->jpeg_parse_error = false;
1330 ret = mxc_jpeg_parse(ctx,
1331 (u8 *)vb2_plane_vaddr(vb, 0),
1332 vb2_get_plane_payload(vb, 0),
1333 &jpeg_src_buf->dht_needed);
1334 if (ret)
1335 jpeg_src_buf->jpeg_parse_error = true;
1336
1337end:
1338 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1339}
1340
1341static int mxc_jpeg_buf_out_validate(struct vb2_buffer *vb)
1342{
1343 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1344
1345 vbuf->field = V4L2_FIELD_NONE;
1346
1347 return 0;
1348}
1349
1350static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
1351{
1352 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1353 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1354 struct mxc_jpeg_q_data *q_data = NULL;
1355 struct device *dev = ctx->mxc_jpeg->dev;
1356 unsigned long sizeimage;
1357 int i;
1358
1359 vbuf->field = V4L2_FIELD_NONE;
1360
1361 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
1362 if (!q_data)
1363 return -EINVAL;
1364 for (i = 0; i < q_data->fmt->colplanes; i++) {
1365 sizeimage = q_data->sizeimage[i];
1366 if (vb2_plane_size(vb, i) < sizeimage) {
1367 dev_err(dev, "plane %d too small (%lu < %lu)",
1368 i, vb2_plane_size(vb, i), sizeimage);
1369 return -EINVAL;
1370 }
1371 vb2_set_plane_payload(vb, i, sizeimage);
1372 }
1373 return 0;
1374}
1375
1376static const struct vb2_ops mxc_jpeg_qops = {
1377 .queue_setup = mxc_jpeg_queue_setup,
1378 .wait_prepare = vb2_ops_wait_prepare,
1379 .wait_finish = vb2_ops_wait_finish,
1380 .buf_out_validate = mxc_jpeg_buf_out_validate,
1381 .buf_prepare = mxc_jpeg_buf_prepare,
1382 .start_streaming = mxc_jpeg_start_streaming,
1383 .stop_streaming = mxc_jpeg_stop_streaming,
1384 .buf_queue = mxc_jpeg_buf_queue,
1385};
1386
1387static int mxc_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
1388 struct vb2_queue *dst_vq)
1389{
1390 struct mxc_jpeg_ctx *ctx = priv;
1391 int ret;
1392
1393 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1394 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1395 src_vq->drv_priv = ctx;
1396 src_vq->buf_struct_size = sizeof(struct mxc_jpeg_src_buf);
1397 src_vq->ops = &mxc_jpeg_qops;
1398 src_vq->mem_ops = &vb2_dma_contig_memops;
1399 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1400 src_vq->lock = &ctx->mxc_jpeg->lock;
1401 src_vq->dev = ctx->mxc_jpeg->dev;
1402 src_vq->allow_zero_bytesused = 1;
1403
1404 ret = vb2_queue_init(src_vq);
1405 if (ret)
1406 return ret;
1407
1408 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1409 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1410 dst_vq->drv_priv = ctx;
1411 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1412 dst_vq->ops = &mxc_jpeg_qops;
1413 dst_vq->mem_ops = &vb2_dma_contig_memops;
1414 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1415 dst_vq->lock = &ctx->mxc_jpeg->lock;
1416 dst_vq->dev = ctx->mxc_jpeg->dev;
1417
1418 ret = vb2_queue_init(dst_vq);
1419 return ret;
1420}
1421
1422static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx)
1423{
1424 struct mxc_jpeg_q_data *out_q = &ctx->out_q;
1425 struct mxc_jpeg_q_data *cap_q = &ctx->cap_q;
1426 struct mxc_jpeg_q_data *q[2] = {out_q, cap_q};
1427 int i;
1428
1429 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
1430 out_q->fmt = mxc_jpeg_find_format(ctx, MXC_JPEG_DEFAULT_PFMT);
1431 cap_q->fmt = mxc_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG);
1432 } else {
1433 out_q->fmt = mxc_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG);
1434 cap_q->fmt = mxc_jpeg_find_format(ctx, MXC_JPEG_DEFAULT_PFMT);
1435 }
1436
1437 for (i = 0; i < 2; i++) {
1438 q[i]->w = MXC_JPEG_DEFAULT_WIDTH;
1439 q[i]->h = MXC_JPEG_DEFAULT_HEIGHT;
1440 q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH;
1441 q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT;
1442 mxc_jpeg_bytesperline(q[i], 8);
1443 mxc_jpeg_sizeimage(q[i]);
1444 }
1445}
1446
1447static int mxc_jpeg_open(struct file *file)
1448{
1449 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
1450 struct video_device *mxc_vfd = video_devdata(file);
1451 struct device *dev = mxc_jpeg->dev;
1452 struct mxc_jpeg_ctx *ctx;
1453 int ret = 0;
1454
1455 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1456 if (!ctx)
1457 return -ENOMEM;
1458
1459 if (mutex_lock_interruptible(&mxc_jpeg->lock)) {
1460 ret = -ERESTARTSYS;
1461 goto free;
1462 }
1463
1464 v4l2_fh_init(&ctx->fh, mxc_vfd);
1465 file->private_data = &ctx->fh;
1466 v4l2_fh_add(&ctx->fh);
1467
1468 ctx->mxc_jpeg = mxc_jpeg;
1469
1470 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx,
1471 mxc_jpeg_queue_init);
1472
1473 if (IS_ERR(ctx->fh.m2m_ctx)) {
1474 ret = PTR_ERR(ctx->fh.m2m_ctx);
1475 goto error;
1476 }
1477
1478 mxc_jpeg_set_default_params(ctx);
1479 ctx->slot = MXC_MAX_SLOTS;
1480
1481 if (mxc_jpeg->mode == MXC_JPEG_DECODE)
1482 dev_dbg(dev, "Opened JPEG decoder instance %p\n", ctx);
1483 else
1484 dev_dbg(dev, "Opened JPEG encoder instance %p\n", ctx);
1485 mutex_unlock(&mxc_jpeg->lock);
1486
1487 return 0;
1488
1489error:
1490 v4l2_fh_del(&ctx->fh);
1491 v4l2_fh_exit(&ctx->fh);
1492 mutex_unlock(&mxc_jpeg->lock);
1493free:
1494 kfree(ctx);
1495 return ret;
1496}
1497
1498static int mxc_jpeg_querycap(struct file *file, void *priv,
1499 struct v4l2_capability *cap)
1500{
1501 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
1502
1503 strscpy(cap->driver, MXC_JPEG_NAME " codec", sizeof(cap->driver));
1504 strscpy(cap->card, MXC_JPEG_NAME " codec", sizeof(cap->card));
1505 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1506 dev_name(mxc_jpeg->dev));
1507 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
1508 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1509
1510 return 0;
1511}
1512
1513static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1514 struct v4l2_fmtdesc *f)
1515{
1516 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
1517
1518 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE)
1519 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
1520 MXC_JPEG_FMT_TYPE_ENC);
1521 else
1522 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
1523 MXC_JPEG_FMT_TYPE_RAW);
1524}
1525
1526static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1527 struct v4l2_fmtdesc *f)
1528{
1529 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
1530
1531 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
1532 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
1533 MXC_JPEG_FMT_TYPE_ENC);
1534 else
1535 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
1536 MXC_JPEG_FMT_TYPE_RAW);
1537}
1538
1539static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fmt,
1540 struct mxc_jpeg_ctx *ctx, int q_type)
1541{
1542 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
1543 struct v4l2_plane_pix_format *pfmt;
1544 u32 w = (pix_mp->width < MXC_JPEG_MAX_WIDTH) ?
1545 pix_mp->width : MXC_JPEG_MAX_WIDTH;
1546 u32 h = (pix_mp->height < MXC_JPEG_MAX_HEIGHT) ?
1547 pix_mp->height : MXC_JPEG_MAX_HEIGHT;
1548 int i;
1549 struct mxc_jpeg_q_data tmp_q;
1550
1551 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
1552 pix_mp->field = V4L2_FIELD_NONE;
1553 pix_mp->num_planes = fmt->colplanes;
1554 pix_mp->pixelformat = fmt->fourcc;
1555
1556
1557
1558
1559
1560
1561 v4l_bound_align_image(&w,
1562 MXC_JPEG_MIN_WIDTH,
1563 w,
1564 fmt->h_align,
1565 &h,
1566 MXC_JPEG_MIN_HEIGHT,
1567 h,
1568 MXC_JPEG_H_ALIGN,
1569 0);
1570 pix_mp->width = w;
1571 pix_mp->height = h;
1572
1573
1574 tmp_q.w = w;
1575 tmp_q.h = h;
1576 tmp_q.fmt = fmt;
1577 for (i = 0; i < pix_mp->num_planes; i++) {
1578 pfmt = &pix_mp->plane_fmt[i];
1579 tmp_q.bytesperline[i] = pfmt->bytesperline;
1580 tmp_q.sizeimage[i] = pfmt->sizeimage;
1581 }
1582
1583
1584 mxc_jpeg_bytesperline(&tmp_q, 8);
1585 mxc_jpeg_sizeimage(&tmp_q);
1586
1587
1588 for (i = 0; i < pix_mp->num_planes; i++) {
1589 pfmt = &pix_mp->plane_fmt[i];
1590 memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
1591 pfmt->bytesperline = tmp_q.bytesperline[i];
1592 pfmt->sizeimage = tmp_q.sizeimage[i];
1593 }
1594
1595
1596 pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
1597 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601;
1598 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB;
1599
1600
1601
1602
1603
1604 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE;
1605
1606 return 0;
1607}
1608
1609static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1610 struct v4l2_format *f)
1611{
1612 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
1613 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1614 struct device *dev = jpeg->dev;
1615 const struct mxc_jpeg_fmt *fmt;
1616 u32 fourcc = f->fmt.pix_mp.pixelformat;
1617
1618 int q_type = (jpeg->mode == MXC_JPEG_DECODE) ?
1619 MXC_JPEG_FMT_TYPE_RAW : MXC_JPEG_FMT_TYPE_ENC;
1620
1621 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
1622 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type);
1623 return -EINVAL;
1624 }
1625
1626 fmt = mxc_jpeg_find_format(ctx, fourcc);
1627 if (!fmt || fmt->flags != q_type) {
1628 dev_warn(dev, "Format not supported: %c%c%c%c, use the default.\n",
1629 (fourcc & 0xff),
1630 (fourcc >> 8) & 0xff,
1631 (fourcc >> 16) & 0xff,
1632 (fourcc >> 24) & 0xff);
1633 f->fmt.pix_mp.pixelformat = (jpeg->mode == MXC_JPEG_DECODE) ?
1634 MXC_JPEG_DEFAULT_PFMT : V4L2_PIX_FMT_JPEG;
1635 fmt = mxc_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat);
1636 }
1637 return mxc_jpeg_try_fmt(f, fmt, ctx, q_type);
1638}
1639
1640static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1641 struct v4l2_format *f)
1642{
1643 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
1644 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1645 struct device *dev = jpeg->dev;
1646 const struct mxc_jpeg_fmt *fmt;
1647 u32 fourcc = f->fmt.pix_mp.pixelformat;
1648
1649 int q_type = (jpeg->mode == MXC_JPEG_ENCODE) ?
1650 MXC_JPEG_FMT_TYPE_RAW : MXC_JPEG_FMT_TYPE_ENC;
1651
1652 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
1653 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type);
1654 return -EINVAL;
1655 }
1656
1657 fmt = mxc_jpeg_find_format(ctx, fourcc);
1658 if (!fmt || fmt->flags != q_type) {
1659 dev_warn(dev, "Format not supported: %c%c%c%c, use the default.\n",
1660 (fourcc & 0xff),
1661 (fourcc >> 8) & 0xff,
1662 (fourcc >> 16) & 0xff,
1663 (fourcc >> 24) & 0xff);
1664 f->fmt.pix_mp.pixelformat = (jpeg->mode == MXC_JPEG_ENCODE) ?
1665 MXC_JPEG_DEFAULT_PFMT : V4L2_PIX_FMT_JPEG;
1666 fmt = mxc_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat);
1667 }
1668 return mxc_jpeg_try_fmt(f, fmt, ctx, q_type);
1669}
1670
1671static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
1672 struct v4l2_format *f)
1673{
1674 struct vb2_queue *vq;
1675 struct mxc_jpeg_q_data *q_data = NULL;
1676 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
1677 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1678 int i;
1679
1680 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
1681 if (!vq)
1682 return -EINVAL;
1683
1684 q_data = mxc_jpeg_get_q_data(ctx, f->type);
1685
1686 if (vb2_is_busy(vq)) {
1687 v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
1688 return -EBUSY;
1689 }
1690
1691 q_data->fmt = mxc_jpeg_find_format(ctx, pix_mp->pixelformat);
1692 q_data->w = pix_mp->width;
1693 q_data->h = pix_mp->height;
1694
1695 q_data->w_adjusted = q_data->w;
1696 q_data->h_adjusted = q_data->h;
1697 if (jpeg->mode == MXC_JPEG_DECODE) {
1698
1699
1700
1701
1702 v4l_bound_align_image(&q_data->w_adjusted,
1703 q_data->w_adjusted,
1704 MXC_JPEG_MAX_WIDTH,
1705 q_data->fmt->h_align,
1706 &q_data->h_adjusted,
1707 q_data->h_adjusted,
1708 MXC_JPEG_MAX_HEIGHT,
1709 q_data->fmt->v_align,
1710 0);
1711 } else {
1712
1713
1714
1715
1716 v4l_bound_align_image(&q_data->w_adjusted,
1717 MXC_JPEG_MIN_WIDTH,
1718 q_data->w_adjusted,
1719 q_data->fmt->h_align,
1720 &q_data->h_adjusted,
1721 MXC_JPEG_MIN_HEIGHT,
1722 q_data->h_adjusted,
1723 q_data->fmt->v_align,
1724 0);
1725 }
1726
1727 for (i = 0; i < pix_mp->num_planes; i++) {
1728 q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
1729 q_data->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
1730 }
1731
1732 return 0;
1733}
1734
1735static int mxc_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1736 struct v4l2_format *f)
1737{
1738 int ret;
1739
1740 ret = mxc_jpeg_try_fmt_vid_cap(file, priv, f);
1741 if (ret)
1742 return ret;
1743
1744 return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
1745}
1746
1747static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1748 struct v4l2_format *f)
1749{
1750 int ret;
1751
1752 ret = mxc_jpeg_try_fmt_vid_out(file, priv, f);
1753 if (ret)
1754 return ret;
1755
1756 return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
1757}
1758
1759static int mxc_jpeg_g_fmt_vid(struct file *file, void *priv,
1760 struct v4l2_format *f)
1761{
1762 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
1763 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1764 struct device *dev = jpeg->dev;
1765 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
1766 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
1767 int i;
1768
1769 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
1770 dev_err(dev, "G_FMT with Invalid type: %d\n", f->type);
1771 return -EINVAL;
1772 }
1773
1774 pix_mp->pixelformat = q_data->fmt->fourcc;
1775 pix_mp->width = q_data->w;
1776 pix_mp->height = q_data->h;
1777 pix_mp->field = V4L2_FIELD_NONE;
1778
1779
1780 pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
1781 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601;
1782 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB;
1783 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE;
1784
1785 pix_mp->num_planes = q_data->fmt->colplanes;
1786 for (i = 0; i < pix_mp->num_planes; i++) {
1787 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
1788 pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
1789 }
1790
1791 return 0;
1792}
1793
1794static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
1795 const struct v4l2_event_subscription *sub)
1796{
1797 switch (sub->type) {
1798 case V4L2_EVENT_EOS:
1799 return v4l2_event_subscribe(fh, sub, 0, NULL);
1800 case V4L2_EVENT_SOURCE_CHANGE:
1801 return v4l2_src_change_event_subscribe(fh, sub);
1802 default:
1803 return -EINVAL;
1804 }
1805}
1806
1807static int mxc_jpeg_dqbuf(struct file *file, void *priv,
1808 struct v4l2_buffer *buf)
1809{
1810 struct v4l2_fh *fh = file->private_data;
1811 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
1812 struct device *dev = ctx->mxc_jpeg->dev;
1813 int num_src_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx);
1814 int ret;
1815
1816 dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index);
1817 if (ctx->stopping == 1 && num_src_ready == 0) {
1818
1819 notify_eos(ctx);
1820 ctx->stopping = 0;
1821 }
1822
1823 ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
1824
1825 return ret;
1826}
1827
1828static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
1829 .vidioc_querycap = mxc_jpeg_querycap,
1830 .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap,
1831 .vidioc_enum_fmt_vid_out = mxc_jpeg_enum_fmt_vid_out,
1832
1833 .vidioc_try_fmt_vid_cap_mplane = mxc_jpeg_try_fmt_vid_cap,
1834 .vidioc_try_fmt_vid_out_mplane = mxc_jpeg_try_fmt_vid_out,
1835
1836 .vidioc_s_fmt_vid_cap_mplane = mxc_jpeg_s_fmt_vid_cap,
1837 .vidioc_s_fmt_vid_out_mplane = mxc_jpeg_s_fmt_vid_out,
1838
1839 .vidioc_g_fmt_vid_cap_mplane = mxc_jpeg_g_fmt_vid,
1840 .vidioc_g_fmt_vid_out_mplane = mxc_jpeg_g_fmt_vid,
1841
1842 .vidioc_subscribe_event = mxc_jpeg_subscribe_event,
1843 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1844
1845 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
1846 .vidioc_decoder_cmd = mxc_jpeg_decoder_cmd,
1847 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
1848 .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd,
1849
1850 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1851 .vidioc_dqbuf = mxc_jpeg_dqbuf,
1852
1853 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
1854 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
1855 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1856 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1857 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
1858 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1859 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1860};
1861
1862static int mxc_jpeg_release(struct file *file)
1863{
1864 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
1865 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data);
1866 struct device *dev = mxc_jpeg->dev;
1867
1868 mutex_lock(&mxc_jpeg->lock);
1869 if (mxc_jpeg->mode == MXC_JPEG_DECODE)
1870 dev_dbg(dev, "Release JPEG decoder instance on slot %d.",
1871 ctx->slot);
1872 else
1873 dev_dbg(dev, "Release JPEG encoder instance on slot %d.",
1874 ctx->slot);
1875 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1876 v4l2_fh_del(&ctx->fh);
1877 v4l2_fh_exit(&ctx->fh);
1878 kfree(ctx);
1879 mutex_unlock(&mxc_jpeg->lock);
1880
1881 return 0;
1882}
1883
1884static const struct v4l2_file_operations mxc_jpeg_fops = {
1885 .owner = THIS_MODULE,
1886 .open = mxc_jpeg_open,
1887 .release = mxc_jpeg_release,
1888 .poll = v4l2_m2m_fop_poll,
1889 .unlocked_ioctl = video_ioctl2,
1890 .mmap = v4l2_m2m_fop_mmap,
1891};
1892
1893static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = {
1894 .device_run = mxc_jpeg_device_run,
1895};
1896
1897static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg)
1898{
1899 int i;
1900
1901 for (i = 0; i < jpeg->num_domains; i++) {
1902 if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i]))
1903 device_link_del(jpeg->pd_link[i]);
1904 if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i]))
1905 dev_pm_domain_detach(jpeg->pd_dev[i], true);
1906 jpeg->pd_dev[i] = NULL;
1907 jpeg->pd_link[i] = NULL;
1908 }
1909}
1910
1911static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg)
1912{
1913 struct device *dev = jpeg->dev;
1914 struct device_node *np = jpeg->pdev->dev.of_node;
1915 int i;
1916 int ret;
1917
1918 jpeg->num_domains = of_count_phandle_with_args(np, "power-domains",
1919 "#power-domain-cells");
1920 if (jpeg->num_domains < 0) {
1921 dev_err(dev, "No power domains defined for jpeg node\n");
1922 return jpeg->num_domains;
1923 }
1924
1925 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains,
1926 sizeof(*jpeg->pd_dev), GFP_KERNEL);
1927 if (!jpeg->pd_dev)
1928 return -ENOMEM;
1929
1930 jpeg->pd_link = devm_kmalloc_array(dev, jpeg->num_domains,
1931 sizeof(*jpeg->pd_link), GFP_KERNEL);
1932 if (!jpeg->pd_link)
1933 return -ENOMEM;
1934
1935 for (i = 0; i < jpeg->num_domains; i++) {
1936 jpeg->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
1937 if (IS_ERR(jpeg->pd_dev[i])) {
1938 ret = PTR_ERR(jpeg->pd_dev[i]);
1939 goto fail;
1940 }
1941
1942 jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i],
1943 DL_FLAG_STATELESS |
1944 DL_FLAG_PM_RUNTIME |
1945 DL_FLAG_RPM_ACTIVE);
1946 if (!jpeg->pd_link[i]) {
1947 ret = -EINVAL;
1948 goto fail;
1949 }
1950 }
1951
1952 return 0;
1953fail:
1954 mxc_jpeg_detach_pm_domains(jpeg);
1955 return ret;
1956}
1957
1958static int mxc_jpeg_probe(struct platform_device *pdev)
1959{
1960 struct mxc_jpeg_dev *jpeg;
1961 struct device *dev = &pdev->dev;
1962 struct resource *res;
1963 int dec_irq;
1964 int ret;
1965 int mode;
1966 const struct of_device_id *of_id;
1967 unsigned int slot;
1968
1969 of_id = of_match_node(mxc_jpeg_match, dev->of_node);
1970 mode = *(const int *)of_id->data;
1971
1972 jpeg = devm_kzalloc(dev, sizeof(struct mxc_jpeg_dev), GFP_KERNEL);
1973 if (!jpeg)
1974 return -ENOMEM;
1975
1976 mutex_init(&jpeg->lock);
1977 spin_lock_init(&jpeg->hw_lock);
1978
1979 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1980 if (ret) {
1981 dev_err(&pdev->dev, "No suitable DMA available.\n");
1982 goto err_irq;
1983 }
1984
1985 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1986 jpeg->base_reg = devm_ioremap_resource(&pdev->dev, res);
1987 if (IS_ERR(jpeg->base_reg))
1988 return PTR_ERR(jpeg->base_reg);
1989
1990 for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
1991 dec_irq = platform_get_irq(pdev, slot);
1992 if (dec_irq < 0) {
1993 dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq);
1994 ret = dec_irq;
1995 goto err_irq;
1996 }
1997 ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
1998 0, pdev->name, jpeg);
1999 if (ret) {
2000 dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
2001 dec_irq, ret);
2002 goto err_irq;
2003 }
2004 }
2005
2006 jpeg->pdev = pdev;
2007 jpeg->dev = dev;
2008 jpeg->mode = mode;
2009
2010 ret = mxc_jpeg_attach_pm_domains(jpeg);
2011 if (ret < 0) {
2012 dev_err(dev, "failed to attach power domains %d\n", ret);
2013 return ret;
2014 }
2015
2016
2017 ret = v4l2_device_register(dev, &jpeg->v4l2_dev);
2018 if (ret) {
2019 dev_err(dev, "failed to register v4l2 device\n");
2020 goto err_register;
2021 }
2022 jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops);
2023 if (IS_ERR(jpeg->m2m_dev)) {
2024 dev_err(dev, "failed to register v4l2 device\n");
2025 ret = PTR_ERR(jpeg->m2m_dev);
2026 goto err_m2m;
2027 }
2028
2029 jpeg->dec_vdev = video_device_alloc();
2030 if (!jpeg->dec_vdev) {
2031 dev_err(dev, "failed to register v4l2 device\n");
2032 ret = -ENOMEM;
2033 goto err_vdev_alloc;
2034 }
2035 if (mode == MXC_JPEG_ENCODE)
2036 snprintf(jpeg->dec_vdev->name,
2037 sizeof(jpeg->dec_vdev->name),
2038 "%s-enc", MXC_JPEG_NAME);
2039 else
2040 snprintf(jpeg->dec_vdev->name,
2041 sizeof(jpeg->dec_vdev->name),
2042 "%s-dec", MXC_JPEG_NAME);
2043
2044 jpeg->dec_vdev->fops = &mxc_jpeg_fops;
2045 jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops;
2046 jpeg->dec_vdev->minor = -1;
2047 jpeg->dec_vdev->release = video_device_release;
2048 jpeg->dec_vdev->lock = &jpeg->lock;
2049 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
2050 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
2051 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
2052 V4L2_CAP_VIDEO_M2M_MPLANE;
2053 if (mode == MXC_JPEG_ENCODE) {
2054 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD);
2055 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD);
2056 } else {
2057 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_ENCODER_CMD);
2058 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_ENCODER_CMD);
2059 }
2060 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, -1);
2061 if (ret) {
2062 dev_err(dev, "failed to register video device\n");
2063 goto err_vdev_register;
2064 }
2065 video_set_drvdata(jpeg->dec_vdev, jpeg);
2066 if (mode == MXC_JPEG_ENCODE)
2067 v4l2_info(&jpeg->v4l2_dev,
2068 "encoder device registered as /dev/video%d (%d,%d)\n",
2069 jpeg->dec_vdev->num, VIDEO_MAJOR,
2070 jpeg->dec_vdev->minor);
2071 else
2072 v4l2_info(&jpeg->v4l2_dev,
2073 "decoder device registered as /dev/video%d (%d,%d)\n",
2074 jpeg->dec_vdev->num, VIDEO_MAJOR,
2075 jpeg->dec_vdev->minor);
2076
2077 platform_set_drvdata(pdev, jpeg);
2078
2079 return 0;
2080
2081err_vdev_register:
2082 video_device_release(jpeg->dec_vdev);
2083
2084err_vdev_alloc:
2085 v4l2_m2m_release(jpeg->m2m_dev);
2086
2087err_m2m:
2088 v4l2_device_unregister(&jpeg->v4l2_dev);
2089
2090err_register:
2091err_irq:
2092 return ret;
2093}
2094
2095static int mxc_jpeg_remove(struct platform_device *pdev)
2096{
2097 unsigned int slot;
2098 struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev);
2099
2100 for (slot = 0; slot < MXC_MAX_SLOTS; slot++)
2101 mxc_jpeg_free_slot_data(jpeg, slot);
2102
2103 video_unregister_device(jpeg->dec_vdev);
2104 v4l2_m2m_release(jpeg->m2m_dev);
2105 v4l2_device_unregister(&jpeg->v4l2_dev);
2106 mxc_jpeg_detach_pm_domains(jpeg);
2107
2108 return 0;
2109}
2110
2111MODULE_DEVICE_TABLE(of, mxc_jpeg_match);
2112
2113static struct platform_driver mxc_jpeg_driver = {
2114 .probe = mxc_jpeg_probe,
2115 .remove = mxc_jpeg_remove,
2116 .driver = {
2117 .name = "mxc-jpeg",
2118 .of_match_table = mxc_jpeg_match,
2119 },
2120};
2121module_platform_driver(mxc_jpeg_driver);
2122
2123MODULE_AUTHOR("Zhengyu Shen <zhengyu.shen_1@nxp.com>");
2124MODULE_AUTHOR("Mirela Rabulea <mirela.rabulea@nxp.com>");
2125MODULE_DESCRIPTION("V4L2 driver for i.MX8 QXP/QM JPEG encoder/decoder");
2126MODULE_LICENSE("GPL v2");
2127