1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <asm/unaligned.h>
21#include <linux/clk.h>
22#include <linux/err.h>
23#include <linux/interrupt.h>
24#include <linux/io.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/of.h>
28#include <linux/of_device.h>
29#include <linux/platform_device.h>
30#include <linux/slab.h>
31#include <linux/spinlock.h>
32#include <linux/string.h>
33#include <linux/videodev2.h>
34#include <media/v4l2-ctrls.h>
35#include <media/v4l2-device.h>
36#include <media/v4l2-event.h>
37#include <media/v4l2-fh.h>
38#include <media/v4l2-mem2mem.h>
39#include <media/v4l2-ioctl.h>
40#include <media/videobuf2-v4l2.h>
41#include <media/videobuf2-dma-contig.h>
42
43
44#define DRV_NAME "rcar_jpu"
45
46
47
48
49
50#define JPU_JPEG_HDR_SIZE (ALIGN(0x258, L1_CACHE_BYTES))
51#define JPU_JPEG_MAX_BYTES_PER_PIXEL 2
52#define JPU_JPEG_MIN_SIZE 25
53#define JPU_JPEG_QTBL_SIZE 0x40
54#define JPU_JPEG_HDCTBL_SIZE 0x1c
55#define JPU_JPEG_HACTBL_SIZE 0xb2
56#define JPU_JPEG_HEIGHT_OFFSET 0x91
57#define JPU_JPEG_WIDTH_OFFSET 0x93
58#define JPU_JPEG_SUBS_OFFSET 0x97
59#define JPU_JPEG_QTBL_LUM_OFFSET 0x07
60#define JPU_JPEG_QTBL_CHR_OFFSET 0x4c
61#define JPU_JPEG_HDCTBL_LUM_OFFSET 0xa4
62#define JPU_JPEG_HACTBL_LUM_OFFSET 0xc5
63#define JPU_JPEG_HDCTBL_CHR_OFFSET 0x17c
64#define JPU_JPEG_HACTBL_CHR_OFFSET 0x19d
65#define JPU_JPEG_PADDING_OFFSET 0x24f
66#define JPU_JPEG_LUM 0x00
67#define JPU_JPEG_CHR 0x01
68#define JPU_JPEG_DC 0x00
69#define JPU_JPEG_AC 0x10
70
71#define JPU_JPEG_422 0x21
72#define JPU_JPEG_420 0x22
73
74#define JPU_JPEG_DEFAULT_422_PIX_FMT V4L2_PIX_FMT_NV16M
75#define JPU_JPEG_DEFAULT_420_PIX_FMT V4L2_PIX_FMT_NV12M
76
77
78#define TEM 0x01
79#define SOF0 0xc0
80#define RST 0xd0
81#define SOI 0xd8
82#define EOI 0xd9
83#define DHP 0xde
84#define DHT 0xc4
85#define COM 0xfe
86#define DQT 0xdb
87#define DRI 0xdd
88#define APP0 0xe0
89
90#define JPU_RESET_TIMEOUT 100
91#define JPU_JOB_TIMEOUT 300
92#define JPU_MAX_QUALITY 4
93#define JPU_WIDTH_MIN 16
94#define JPU_HEIGHT_MIN 16
95#define JPU_WIDTH_MAX 4096
96#define JPU_HEIGHT_MAX 4096
97#define JPU_MEMALIGN 8
98
99
100#define JPU_FMT_TYPE_OUTPUT 0
101#define JPU_FMT_TYPE_CAPTURE 1
102#define JPU_ENC_CAPTURE (1 << 0)
103#define JPU_ENC_OUTPUT (1 << 1)
104#define JPU_DEC_CAPTURE (1 << 2)
105#define JPU_DEC_OUTPUT (1 << 3)
106
107
108
109
110
111
112#define JCMOD 0x00
113#define JCMOD_PCTR (1 << 7)
114#define JCMOD_MSKIP_ENABLE (1 << 5)
115#define JCMOD_DSP_ENC (0 << 3)
116#define JCMOD_DSP_DEC (1 << 3)
117#define JCMOD_REDU (7 << 0)
118#define JCMOD_REDU_422 (1 << 0)
119#define JCMOD_REDU_420 (2 << 0)
120
121
122#define JCCMD 0x04
123#define JCCMD_SRST (1 << 12)
124#define JCCMD_JEND (1 << 2)
125#define JCCMD_JSRT (1 << 0)
126
127
128#define JCQTN 0x0c
129#define JCQTN_SHIFT(t) (((t) - 1) << 1)
130
131
132#define JCHTN 0x10
133#define JCHTN_AC_SHIFT(t) (((t) << 1) - 1)
134#define JCHTN_DC_SHIFT(t) (((t) - 1) << 1)
135
136#define JCVSZU 0x1c
137#define JCVSZD 0x20
138#define JCHSZU 0x24
139#define JCHSZD 0x28
140#define JCSZ_MASK 0xff
141
142#define JCDTCU 0x2c
143#define JCDTCM 0x30
144#define JCDTCD 0x34
145
146
147#define JINTE 0x38
148#define JINTE_ERR (7 << 5)
149#define JINTE_TRANSF_COMPL (1 << 10)
150
151
152#define JINTS 0x3c
153#define JINTS_MASK 0x7c68
154#define JINTS_ERR (1 << 5)
155#define JINTS_PROCESS_COMPL (1 << 6)
156#define JINTS_TRANSF_COMPL (1 << 10)
157
158#define JCDERR 0x40
159#define JCDERR_MASK 0xf
160
161
162#define JIFECNT 0x70
163#define JIFECNT_INFT_422 0
164#define JIFECNT_INFT_420 1
165#define JIFECNT_SWAP_WB (3 << 4)
166
167#define JIFESYA1 0x74
168#define JIFESCA1 0x78
169#define JIFESYA2 0x7c
170#define JIFESCA2 0x80
171#define JIFESMW 0x84
172#define JIFESVSZ 0x88
173#define JIFESHSZ 0x8c
174#define JIFEDA1 0x90
175#define JIFEDA2 0x94
176
177
178#define JIFDCNT 0xa0
179#define JIFDCNT_SWAP_WB (3 << 1)
180
181#define JIFDSA1 0xa4
182#define JIFDDMW 0xb0
183#define JIFDDVSZ 0xb4
184#define JIFDDHSZ 0xb8
185#define JIFDDYA1 0xbc
186#define JIFDDCA1 0xc0
187
188#define JCQTBL(n) (0x10000 + (n) * 0x40)
189#define JCHTBD(n) (0x10100 + (n) * 0x100)
190#define JCHTBA(n) (0x10120 + (n) * 0x100)
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208struct jpu {
209 struct mutex mutex;
210 spinlock_t lock;
211 struct v4l2_device v4l2_dev;
212 struct video_device vfd_encoder;
213 struct video_device vfd_decoder;
214 struct v4l2_m2m_dev *m2m_dev;
215 struct jpu_ctx *curr;
216 wait_queue_head_t irq_queue;
217
218 void __iomem *regs;
219 unsigned int irq;
220 struct clk *clk;
221 struct device *dev;
222 int ref_count;
223};
224
225
226
227
228
229
230
231struct jpu_buffer {
232 struct v4l2_m2m_buffer buf;
233 unsigned short compr_quality;
234 unsigned char subsampling;
235};
236
237
238
239
240
241
242
243
244
245
246
247
248struct jpu_fmt {
249 u32 fourcc;
250 u32 colorspace;
251 u8 bpp[2];
252 u8 h_align;
253 u8 v_align;
254 u8 subsampling;
255 u8 num_planes;
256 u16 types;
257};
258
259
260
261
262
263
264
265struct jpu_q_data {
266 struct jpu_fmt *fmtinfo;
267 struct v4l2_pix_format_mplane format;
268 unsigned int sequence;
269};
270
271
272
273
274
275
276
277
278
279
280
281struct jpu_ctx {
282 struct jpu *jpu;
283 bool encoder;
284 unsigned short compr_quality;
285 struct jpu_q_data out_q;
286 struct jpu_q_data cap_q;
287 struct v4l2_fh fh;
288 struct v4l2_ctrl_handler ctrl_handler;
289};
290
291
292
293
294
295
296struct jpeg_buffer {
297 void *end;
298 void *curr;
299};
300
301static struct jpu_fmt jpu_formats[] = {
302 { V4L2_PIX_FMT_JPEG, V4L2_COLORSPACE_JPEG,
303 {0, 0}, 0, 0, 0, 1, JPU_ENC_CAPTURE | JPU_DEC_OUTPUT },
304 { V4L2_PIX_FMT_NV16M, V4L2_COLORSPACE_SRGB,
305 {8, 8}, 2, 2, JPU_JPEG_422, 2, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE },
306 { V4L2_PIX_FMT_NV12M, V4L2_COLORSPACE_SRGB,
307 {8, 4}, 2, 2, JPU_JPEG_420, 2, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE },
308 { V4L2_PIX_FMT_NV16, V4L2_COLORSPACE_SRGB,
309 {16, 0}, 2, 2, JPU_JPEG_422, 1, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE },
310 { V4L2_PIX_FMT_NV12, V4L2_COLORSPACE_SRGB,
311 {12, 0}, 2, 2, JPU_JPEG_420, 1, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE },
312};
313
314static const u8 zigzag[] = {
315 0x03, 0x02, 0x0b, 0x13, 0x0a, 0x01, 0x00, 0x09,
316 0x12, 0x1b, 0x23, 0x1a, 0x11, 0x08, 0x07, 0x06,
317 0x0f, 0x10, 0x19, 0x22, 0x2b, 0x33, 0x2a, 0x21,
318 0x18, 0x17, 0x0e, 0x05, 0x04, 0x0d, 0x16, 0x1f,
319 0x20, 0x29, 0x32, 0x3b, 0x3a, 0x31, 0x28, 0x27,
320 0x1e, 0x15, 0x0e, 0x14, 0x10, 0x26, 0x2f, 0x30,
321 0x39, 0x38, 0x37, 0x2e, 0x25, 0x1c, 0x24, 0x2b,
322 0x36, 0x3f, 0x3e, 0x35, 0x2c, 0x34, 0x3d, 0x3c
323};
324
325#define QTBL_SIZE (ALIGN(JPU_JPEG_QTBL_SIZE, \
326 sizeof(unsigned int)) / sizeof(unsigned int))
327#define HDCTBL_SIZE (ALIGN(JPU_JPEG_HDCTBL_SIZE, \
328 sizeof(unsigned int)) / sizeof(unsigned int))
329#define HACTBL_SIZE (ALIGN(JPU_JPEG_HACTBL_SIZE, \
330 sizeof(unsigned int)) / sizeof(unsigned int))
331
332
333
334
335
336
337#define JPU_JPEG_HDR_BLOB { \
338 0xff, SOI, 0xff, DQT, 0x00, JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_LUM, \
339 [JPU_JPEG_QTBL_LUM_OFFSET ... \
340 JPU_JPEG_QTBL_LUM_OFFSET + JPU_JPEG_QTBL_SIZE - 1] = 0x00, \
341 0xff, DQT, 0x00, JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_CHR, \
342 [JPU_JPEG_QTBL_CHR_OFFSET ... JPU_JPEG_QTBL_CHR_OFFSET + \
343 JPU_JPEG_QTBL_SIZE - 1] = 0x00, 0xff, SOF0, 0x00, 0x11, 0x08, \
344 [JPU_JPEG_HEIGHT_OFFSET ... JPU_JPEG_HEIGHT_OFFSET + 1] = 0x00, \
345 [JPU_JPEG_WIDTH_OFFSET ... JPU_JPEG_WIDTH_OFFSET + 1] = 0x00, \
346 0x03, 0x01, [JPU_JPEG_SUBS_OFFSET] = 0x00, JPU_JPEG_LUM, \
347 0x02, 0x11, JPU_JPEG_CHR, 0x03, 0x11, JPU_JPEG_CHR, \
348 0xff, DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, JPU_JPEG_LUM|JPU_JPEG_DC, \
349 [JPU_JPEG_HDCTBL_LUM_OFFSET ... \
350 JPU_JPEG_HDCTBL_LUM_OFFSET + JPU_JPEG_HDCTBL_SIZE - 1] = 0x00, \
351 0xff, DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, JPU_JPEG_LUM|JPU_JPEG_AC, \
352 [JPU_JPEG_HACTBL_LUM_OFFSET ... \
353 JPU_JPEG_HACTBL_LUM_OFFSET + JPU_JPEG_HACTBL_SIZE - 1] = 0x00, \
354 0xff, DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, JPU_JPEG_CHR|JPU_JPEG_DC, \
355 [JPU_JPEG_HDCTBL_CHR_OFFSET ... \
356 JPU_JPEG_HDCTBL_CHR_OFFSET + JPU_JPEG_HDCTBL_SIZE - 1] = 0x00, \
357 0xff, DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, JPU_JPEG_CHR|JPU_JPEG_AC, \
358 [JPU_JPEG_HACTBL_CHR_OFFSET ... \
359 JPU_JPEG_HACTBL_CHR_OFFSET + JPU_JPEG_HACTBL_SIZE - 1] = 0x00, \
360 [JPU_JPEG_PADDING_OFFSET ... JPU_JPEG_HDR_SIZE - 1] = 0xff \
361}
362
363static unsigned char jpeg_hdrs[JPU_MAX_QUALITY][JPU_JPEG_HDR_SIZE] = {
364 [0 ... JPU_MAX_QUALITY - 1] = JPU_JPEG_HDR_BLOB
365};
366
367static const unsigned int qtbl_lum[JPU_MAX_QUALITY][QTBL_SIZE] = {
368 {
369 0x14101927, 0x322e3e44, 0x10121726, 0x26354144,
370 0x19171f26, 0x35414444, 0x27262635, 0x41444444,
371 0x32263541, 0x44444444, 0x2e354144, 0x44444444,
372 0x3e414444, 0x44444444, 0x44444444, 0x44444444
373 },
374 {
375 0x100b0b10, 0x171b1f1e, 0x0b0c0c0f, 0x1417171e,
376 0x0b0c0d10, 0x171a232f, 0x100f1017, 0x1a252f40,
377 0x1714171a, 0x27334040, 0x1b171a25, 0x33404040,
378 0x1f17232f, 0x40404040, 0x1e1e2f40, 0x40404040
379 },
380 {
381 0x0c08080c, 0x11151817, 0x0809090b, 0x0f131217,
382 0x08090a0c, 0x13141b24, 0x0c0b0c15, 0x141c2435,
383 0x110f1314, 0x1e27333b, 0x1513141c, 0x27333b3b,
384 0x18121b24, 0x333b3b3b, 0x17172435, 0x3b3b3b3b
385 },
386 {
387 0x08060608, 0x0c0e1011, 0x06060608, 0x0a0d0c0f,
388 0x06060708, 0x0d0e1218, 0x0808080e, 0x0d131823,
389 0x0c0a0d0d, 0x141a2227, 0x0e0d0e13, 0x1a222727,
390 0x100c1318, 0x22272727, 0x110f1823, 0x27272727
391 }
392};
393
394static const unsigned int qtbl_chr[JPU_MAX_QUALITY][QTBL_SIZE] = {
395 {
396 0x15192026, 0x36444444, 0x191c1826, 0x36444444,
397 0x2018202b, 0x42444444, 0x26262b35, 0x44444444,
398 0x36424444, 0x44444444, 0x44444444, 0x44444444,
399 0x44444444, 0x44444444, 0x44444444, 0x44444444
400 },
401 {
402 0x110f1115, 0x141a2630, 0x0f131211, 0x141a232b,
403 0x11121416, 0x1a1e2e35, 0x1511161c, 0x1e273540,
404 0x14141a1e, 0x27304040, 0x1a1a1e27, 0x303f4040,
405 0x26232e35, 0x40404040, 0x302b3540, 0x40404040
406 },
407 {
408 0x0d0b0d10, 0x14141d25, 0x0b0e0e0e, 0x10141a20,
409 0x0d0e0f11, 0x14172328, 0x100e1115, 0x171e2832,
410 0x14101417, 0x1e25323b, 0x1414171e, 0x25303b3b,
411 0x1d1a2328, 0x323b3b3b, 0x25202832, 0x3b3b3b3b
412 },
413 {
414 0x0908090b, 0x0e111318, 0x080a090b, 0x0e0d1116,
415 0x09090d0e, 0x0d0f171a, 0x0b0b0e0e, 0x0f141a21,
416 0x0e0e0d0f, 0x14182127, 0x110d0f14, 0x18202727,
417 0x1311171a, 0x21272727, 0x18161a21, 0x27272727
418 }
419};
420
421static const unsigned int hdctbl_lum[HDCTBL_SIZE] = {
422 0x00010501, 0x01010101, 0x01000000, 0x00000000,
423 0x00010203, 0x04050607, 0x08090a0b
424};
425
426static const unsigned int hdctbl_chr[HDCTBL_SIZE] = {
427 0x00010501, 0x01010101, 0x01000000, 0x00000000,
428 0x00010203, 0x04050607, 0x08090a0b
429};
430
431static const unsigned int hactbl_lum[HACTBL_SIZE] = {
432 0x00020103, 0x03020403, 0x05050404, 0x0000017d, 0x01020300, 0x04110512,
433 0x21314106, 0x13516107, 0x22711432, 0x8191a108, 0x2342b1c1, 0x1552d1f0,
434 0x24336272, 0x82090a16, 0x1718191a, 0x25262728, 0x292a3435, 0x36373839,
435 0x3a434445, 0x46474849, 0x4a535455, 0x56575859, 0x5a636465, 0x66676869,
436 0x6a737475, 0x76777879, 0x7a838485, 0x86878889, 0x8a929394, 0x95969798,
437 0x999aa2a3, 0xa4a5a6a7, 0xa8a9aab2, 0xb3b4b5b6, 0xb7b8b9ba, 0xc2c3c4c5,
438 0xc6c7c8c9, 0xcad2d3d4, 0xd5d6d7d8, 0xd9dae1e2, 0xe3e4e5e6, 0xe7e8e9ea,
439 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fa0000
440};
441
442static const unsigned int hactbl_chr[HACTBL_SIZE] = {
443 0x00020103, 0x03020403, 0x05050404, 0x0000017d, 0x01020300, 0x04110512,
444 0x21314106, 0x13516107, 0x22711432, 0x8191a108, 0x2342b1c1, 0x1552d1f0,
445 0x24336272, 0x82090a16, 0x1718191a, 0x25262728, 0x292a3435, 0x36373839,
446 0x3a434445, 0x46474849, 0x4a535455, 0x56575859, 0x5a636465, 0x66676869,
447 0x6a737475, 0x76777879, 0x7a838485, 0x86878889, 0x8a929394, 0x95969798,
448 0x999aa2a3, 0xa4a5a6a7, 0xa8a9aab2, 0xb3b4b5b6, 0xb7b8b9ba, 0xc2c3c4c5,
449 0xc6c7c8c9, 0xcad2d3d4, 0xd5d6d7d8, 0xd9dae1e2, 0xe3e4e5e6, 0xe7e8e9ea,
450 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fa0000
451};
452
453static const char *error_to_text[16] = {
454 "Normal",
455 "SOI not detected",
456 "SOF1 to SOFF detected",
457 "Subsampling not detected",
458 "SOF accuracy error",
459 "DQT accuracy error",
460 "Component error 1",
461 "Component error 2",
462 "SOF0, DQT, and DHT not detected when SOS detected",
463 "SOS not detected",
464 "EOI not detected",
465 "Restart interval data number error detected",
466 "Image size error",
467 "Last MCU data number error",
468 "Block data number error",
469 "Unknown"
470};
471
472static struct jpu_buffer *vb2_to_jpu_buffer(struct vb2_v4l2_buffer *vb)
473{
474 struct v4l2_m2m_buffer *b =
475 container_of(vb, struct v4l2_m2m_buffer, vb);
476
477 return container_of(b, struct jpu_buffer, buf);
478}
479
480static u32 jpu_read(struct jpu *jpu, unsigned int reg)
481{
482 return ioread32(jpu->regs + reg);
483}
484
485static void jpu_write(struct jpu *jpu, u32 val, unsigned int reg)
486{
487 iowrite32(val, jpu->regs + reg);
488}
489
490static struct jpu_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
491{
492 return container_of(c->handler, struct jpu_ctx, ctrl_handler);
493}
494
495static struct jpu_ctx *fh_to_ctx(struct v4l2_fh *fh)
496{
497 return container_of(fh, struct jpu_ctx, fh);
498}
499
500static void jpu_set_tbl(struct jpu *jpu, u32 reg, const unsigned int *tbl,
501 unsigned int len) {
502 unsigned int i;
503
504 for (i = 0; i < len; i++)
505 jpu_write(jpu, tbl[i], reg + (i << 2));
506}
507
508static void jpu_set_qtbl(struct jpu *jpu, unsigned short quality)
509{
510 jpu_set_tbl(jpu, JCQTBL(0), qtbl_lum[quality], QTBL_SIZE);
511 jpu_set_tbl(jpu, JCQTBL(1), qtbl_chr[quality], QTBL_SIZE);
512}
513
514static void jpu_set_htbl(struct jpu *jpu)
515{
516 jpu_set_tbl(jpu, JCHTBD(0), hdctbl_lum, HDCTBL_SIZE);
517 jpu_set_tbl(jpu, JCHTBA(0), hactbl_lum, HACTBL_SIZE);
518 jpu_set_tbl(jpu, JCHTBD(1), hdctbl_chr, HDCTBL_SIZE);
519 jpu_set_tbl(jpu, JCHTBA(1), hactbl_chr, HACTBL_SIZE);
520}
521
522static int jpu_wait_reset(struct jpu *jpu)
523{
524 unsigned long timeout;
525
526 timeout = jiffies + msecs_to_jiffies(JPU_RESET_TIMEOUT);
527
528 while (jpu_read(jpu, JCCMD) & JCCMD_SRST) {
529 if (time_after(jiffies, timeout)) {
530 dev_err(jpu->dev, "timed out in reset\n");
531 return -ETIMEDOUT;
532 }
533 schedule();
534 }
535
536 return 0;
537}
538
539static int jpu_reset(struct jpu *jpu)
540{
541 jpu_write(jpu, JCCMD_SRST, JCCMD);
542 return jpu_wait_reset(jpu);
543}
544
545
546
547
548
549
550static void put_qtbl(u8 *p, const u8 *qtbl)
551{
552 unsigned int i;
553
554 for (i = 0; i < ARRAY_SIZE(zigzag); i++)
555 p[i] = *(qtbl + zigzag[i]);
556}
557
558static void put_htbl(u8 *p, const u8 *htbl, unsigned int len)
559{
560 unsigned int i, j;
561
562 for (i = 0; i < len; i += 4)
563 for (j = 0; j < 4 && (i + j) < len; ++j)
564 p[i + j] = htbl[i + 3 - j];
565}
566
567static void jpu_generate_hdr(unsigned short quality, unsigned char *p)
568{
569 put_qtbl(p + JPU_JPEG_QTBL_LUM_OFFSET, (const u8 *)qtbl_lum[quality]);
570 put_qtbl(p + JPU_JPEG_QTBL_CHR_OFFSET, (const u8 *)qtbl_chr[quality]);
571
572 put_htbl(p + JPU_JPEG_HDCTBL_LUM_OFFSET, (const u8 *)hdctbl_lum,
573 JPU_JPEG_HDCTBL_SIZE);
574 put_htbl(p + JPU_JPEG_HACTBL_LUM_OFFSET, (const u8 *)hactbl_lum,
575 JPU_JPEG_HACTBL_SIZE);
576
577 put_htbl(p + JPU_JPEG_HDCTBL_CHR_OFFSET, (const u8 *)hdctbl_chr,
578 JPU_JPEG_HDCTBL_SIZE);
579 put_htbl(p + JPU_JPEG_HACTBL_CHR_OFFSET, (const u8 *)hactbl_chr,
580 JPU_JPEG_HACTBL_SIZE);
581}
582
583static int get_byte(struct jpeg_buffer *buf)
584{
585 if (buf->curr >= buf->end)
586 return -1;
587
588 return *(u8 *)buf->curr++;
589}
590
591static int get_word_be(struct jpeg_buffer *buf, unsigned int *word)
592{
593 if (buf->end - buf->curr < 2)
594 return -1;
595
596 *word = get_unaligned_be16(buf->curr);
597 buf->curr += 2;
598
599 return 0;
600}
601
602static void skip(struct jpeg_buffer *buf, unsigned long len)
603{
604 buf->curr += min((unsigned long)(buf->end - buf->curr), len);
605}
606
607static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width,
608 unsigned int *height)
609{
610 struct jpeg_buffer jpeg_buffer;
611 unsigned int word;
612 bool soi = false;
613
614 jpeg_buffer.end = buffer + size;
615 jpeg_buffer.curr = buffer;
616
617
618
619
620
621 if (size < JPU_JPEG_MIN_SIZE || *(u8 *)(buffer + size - 1) != EOI)
622 return 0;
623
624 for (;;) {
625 int c;
626
627
628 do
629 c = get_byte(&jpeg_buffer);
630 while (c == 0xff || c == 0);
631
632 if (!soi && c == SOI) {
633 soi = true;
634 continue;
635 } else if (soi != (c != SOI))
636 return 0;
637
638 switch (c) {
639 case SOF0:
640 skip(&jpeg_buffer, 3);
641 if (get_word_be(&jpeg_buffer, height) ||
642 get_word_be(&jpeg_buffer, width) ||
643 get_byte(&jpeg_buffer) != 3)
644 return 0;
645
646 skip(&jpeg_buffer, 1);
647 return get_byte(&jpeg_buffer);
648 case DHT:
649 case DQT:
650 case COM:
651 case DRI:
652 case APP0 ... APP0 + 0x0f:
653 if (get_word_be(&jpeg_buffer, &word))
654 return 0;
655 skip(&jpeg_buffer, (long)word - 2);
656 case 0:
657 break;
658 default:
659 return 0;
660 }
661 }
662
663 return 0;
664}
665
666static int jpu_querycap(struct file *file, void *priv,
667 struct v4l2_capability *cap)
668{
669 struct jpu_ctx *ctx = fh_to_ctx(priv);
670
671 if (ctx->encoder)
672 strscpy(cap->card, DRV_NAME " encoder", sizeof(cap->card));
673 else
674 strscpy(cap->card, DRV_NAME " decoder", sizeof(cap->card));
675
676 strscpy(cap->driver, DRV_NAME, sizeof(cap->driver));
677 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
678 dev_name(ctx->jpu->dev));
679 cap->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
680 cap->capabilities = V4L2_CAP_DEVICE_CAPS | cap->device_caps;
681 memset(cap->reserved, 0, sizeof(cap->reserved));
682
683 return 0;
684}
685
686static struct jpu_fmt *jpu_find_format(bool encoder, u32 pixelformat,
687 unsigned int fmt_type)
688{
689 unsigned int i, fmt_flag;
690
691 if (encoder)
692 fmt_flag = fmt_type == JPU_FMT_TYPE_OUTPUT ? JPU_ENC_OUTPUT :
693 JPU_ENC_CAPTURE;
694 else
695 fmt_flag = fmt_type == JPU_FMT_TYPE_OUTPUT ? JPU_DEC_OUTPUT :
696 JPU_DEC_CAPTURE;
697
698 for (i = 0; i < ARRAY_SIZE(jpu_formats); i++) {
699 struct jpu_fmt *fmt = &jpu_formats[i];
700
701 if (fmt->fourcc == pixelformat && fmt->types & fmt_flag)
702 return fmt;
703 }
704
705 return NULL;
706}
707
708static int jpu_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
709{
710 unsigned int i, num = 0;
711
712 for (i = 0; i < ARRAY_SIZE(jpu_formats); ++i) {
713 if (jpu_formats[i].types & type) {
714 if (num == f->index)
715 break;
716 ++num;
717 }
718 }
719
720 if (i >= ARRAY_SIZE(jpu_formats))
721 return -EINVAL;
722
723 f->pixelformat = jpu_formats[i].fourcc;
724
725 return 0;
726}
727
728static int jpu_enum_fmt_cap(struct file *file, void *priv,
729 struct v4l2_fmtdesc *f)
730{
731 struct jpu_ctx *ctx = fh_to_ctx(priv);
732
733 return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_CAPTURE :
734 JPU_DEC_CAPTURE);
735}
736
737static int jpu_enum_fmt_out(struct file *file, void *priv,
738 struct v4l2_fmtdesc *f)
739{
740 struct jpu_ctx *ctx = fh_to_ctx(priv);
741
742 return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_OUTPUT : JPU_DEC_OUTPUT);
743}
744
745static struct jpu_q_data *jpu_get_q_data(struct jpu_ctx *ctx,
746 enum v4l2_buf_type type)
747{
748 if (V4L2_TYPE_IS_OUTPUT(type))
749 return &ctx->out_q;
750 else
751 return &ctx->cap_q;
752}
753
754static void jpu_bound_align_image(u32 *w, unsigned int w_min,
755 unsigned int w_max, unsigned int w_align,
756 u32 *h, unsigned int h_min,
757 unsigned int h_max, unsigned int h_align)
758{
759 unsigned int width, height, w_step, h_step;
760
761 width = *w;
762 height = *h;
763
764 w_step = 1U << w_align;
765 h_step = 1U << h_align;
766 v4l_bound_align_image(w, w_min, w_max, w_align, h, h_min, h_max,
767 h_align, 3);
768
769 if (*w < width && *w + w_step < w_max)
770 *w += w_step;
771 if (*h < height && *h + h_step < h_max)
772 *h += h_step;
773}
774
775static int __jpu_try_fmt(struct jpu_ctx *ctx, struct jpu_fmt **fmtinfo,
776 struct v4l2_pix_format_mplane *pix,
777 enum v4l2_buf_type type)
778{
779 struct jpu_fmt *fmt;
780 unsigned int f_type, w, h;
781
782 f_type = V4L2_TYPE_IS_OUTPUT(type) ? JPU_FMT_TYPE_OUTPUT :
783 JPU_FMT_TYPE_CAPTURE;
784
785 fmt = jpu_find_format(ctx->encoder, pix->pixelformat, f_type);
786 if (!fmt) {
787 unsigned int pixelformat;
788
789 dev_dbg(ctx->jpu->dev, "unknown format; set default format\n");
790 if (ctx->encoder)
791 pixelformat = f_type == JPU_FMT_TYPE_OUTPUT ?
792 V4L2_PIX_FMT_NV16M : V4L2_PIX_FMT_JPEG;
793 else
794 pixelformat = f_type == JPU_FMT_TYPE_CAPTURE ?
795 V4L2_PIX_FMT_NV16M : V4L2_PIX_FMT_JPEG;
796 fmt = jpu_find_format(ctx->encoder, pixelformat, f_type);
797 }
798
799 pix->pixelformat = fmt->fourcc;
800 pix->colorspace = fmt->colorspace;
801 pix->field = V4L2_FIELD_NONE;
802 pix->num_planes = fmt->num_planes;
803 memset(pix->reserved, 0, sizeof(pix->reserved));
804
805 jpu_bound_align_image(&pix->width, JPU_WIDTH_MIN, JPU_WIDTH_MAX,
806 fmt->h_align, &pix->height, JPU_HEIGHT_MIN,
807 JPU_HEIGHT_MAX, fmt->v_align);
808
809 w = pix->width;
810 h = pix->height;
811
812 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
813
814 if (pix->plane_fmt[0].sizeimage <= 0 || ctx->encoder)
815 pix->plane_fmt[0].sizeimage = JPU_JPEG_HDR_SIZE +
816 (JPU_JPEG_MAX_BYTES_PER_PIXEL * w * h);
817 pix->plane_fmt[0].bytesperline = 0;
818 memset(pix->plane_fmt[0].reserved, 0,
819 sizeof(pix->plane_fmt[0].reserved));
820 } else {
821 unsigned int i, bpl = 0;
822
823 for (i = 0; i < pix->num_planes; ++i)
824 bpl = max(bpl, pix->plane_fmt[i].bytesperline);
825
826 bpl = clamp_t(unsigned int, bpl, w, JPU_WIDTH_MAX);
827 bpl = round_up(bpl, JPU_MEMALIGN);
828
829 for (i = 0; i < pix->num_planes; ++i) {
830 pix->plane_fmt[i].bytesperline = bpl;
831 pix->plane_fmt[i].sizeimage = bpl * h * fmt->bpp[i] / 8;
832 memset(pix->plane_fmt[i].reserved, 0,
833 sizeof(pix->plane_fmt[i].reserved));
834 }
835 }
836
837 if (fmtinfo)
838 *fmtinfo = fmt;
839
840 return 0;
841}
842
843static int jpu_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
844{
845 struct jpu_ctx *ctx = fh_to_ctx(priv);
846
847 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
848 return -EINVAL;
849
850 return __jpu_try_fmt(ctx, NULL, &f->fmt.pix_mp, f->type);
851}
852
853static int jpu_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
854{
855 struct vb2_queue *vq;
856 struct jpu_ctx *ctx = fh_to_ctx(priv);
857 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
858 struct jpu_fmt *fmtinfo;
859 struct jpu_q_data *q_data;
860 int ret;
861
862 vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
863 if (!vq)
864 return -EINVAL;
865
866 if (vb2_is_busy(vq)) {
867 v4l2_err(&ctx->jpu->v4l2_dev, "%s queue busy\n", __func__);
868 return -EBUSY;
869 }
870
871 ret = __jpu_try_fmt(ctx, &fmtinfo, &f->fmt.pix_mp, f->type);
872 if (ret < 0)
873 return ret;
874
875 q_data = jpu_get_q_data(ctx, f->type);
876
877 q_data->format = f->fmt.pix_mp;
878 q_data->fmtinfo = fmtinfo;
879
880 return 0;
881}
882
883static int jpu_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
884{
885 struct jpu_q_data *q_data;
886 struct jpu_ctx *ctx = fh_to_ctx(priv);
887
888 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
889 return -EINVAL;
890
891 q_data = jpu_get_q_data(ctx, f->type);
892 f->fmt.pix_mp = q_data->format;
893
894 return 0;
895}
896
897
898
899
900static int jpu_s_ctrl(struct v4l2_ctrl *ctrl)
901{
902 struct jpu_ctx *ctx = ctrl_to_ctx(ctrl);
903 unsigned long flags;
904
905 spin_lock_irqsave(&ctx->jpu->lock, flags);
906 if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY)
907 ctx->compr_quality = ctrl->val;
908 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
909
910 return 0;
911}
912
913static const struct v4l2_ctrl_ops jpu_ctrl_ops = {
914 .s_ctrl = jpu_s_ctrl,
915};
916
917static int jpu_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
918{
919 struct jpu_ctx *ctx = fh_to_ctx(priv);
920 struct jpu_q_data *src_q_data, *dst_q_data, *orig, adj, *ref;
921 enum v4l2_buf_type adj_type;
922
923 src_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
924 dst_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
925
926 if (ctx->encoder) {
927 adj = *src_q_data;
928 orig = src_q_data;
929 ref = dst_q_data;
930 adj_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
931 } else {
932 adj = *dst_q_data;
933 orig = dst_q_data;
934 ref = src_q_data;
935 adj_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
936 }
937
938 adj.format.width = ref->format.width;
939 adj.format.height = ref->format.height;
940
941 __jpu_try_fmt(ctx, NULL, &adj.format, adj_type);
942
943 if (adj.format.width != orig->format.width ||
944 adj.format.height != orig->format.height) {
945 dev_err(ctx->jpu->dev, "src and dst formats do not match.\n");
946
947 return -EINVAL;
948 }
949
950 return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type);
951}
952
953static const struct v4l2_ioctl_ops jpu_ioctl_ops = {
954 .vidioc_querycap = jpu_querycap,
955
956 .vidioc_enum_fmt_vid_cap_mplane = jpu_enum_fmt_cap,
957 .vidioc_enum_fmt_vid_out_mplane = jpu_enum_fmt_out,
958 .vidioc_g_fmt_vid_cap_mplane = jpu_g_fmt,
959 .vidioc_g_fmt_vid_out_mplane = jpu_g_fmt,
960 .vidioc_try_fmt_vid_cap_mplane = jpu_try_fmt,
961 .vidioc_try_fmt_vid_out_mplane = jpu_try_fmt,
962 .vidioc_s_fmt_vid_cap_mplane = jpu_s_fmt,
963 .vidioc_s_fmt_vid_out_mplane = jpu_s_fmt,
964
965 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
966 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
967 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
968 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
969 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
970 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
971
972 .vidioc_streamon = jpu_streamon,
973 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
974
975 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
976 .vidioc_unsubscribe_event = v4l2_event_unsubscribe
977};
978
979static int jpu_controls_create(struct jpu_ctx *ctx)
980{
981 struct v4l2_ctrl *ctrl;
982 int ret;
983
984 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
985
986 ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler, &jpu_ctrl_ops,
987 V4L2_CID_JPEG_COMPRESSION_QUALITY,
988 0, JPU_MAX_QUALITY - 1, 1, 0);
989
990 if (ctx->ctrl_handler.error) {
991 ret = ctx->ctrl_handler.error;
992 goto error_free;
993 }
994
995 if (!ctx->encoder)
996 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
997 V4L2_CTRL_FLAG_READ_ONLY;
998
999 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1000 if (ret < 0)
1001 goto error_free;
1002
1003 return 0;
1004
1005error_free:
1006 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1007 return ret;
1008}
1009
1010
1011
1012
1013
1014
1015static int jpu_queue_setup(struct vb2_queue *vq,
1016 unsigned int *nbuffers, unsigned int *nplanes,
1017 unsigned int sizes[], struct device *alloc_devs[])
1018{
1019 struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
1020 struct jpu_q_data *q_data;
1021 unsigned int i;
1022
1023 q_data = jpu_get_q_data(ctx, vq->type);
1024
1025 if (*nplanes) {
1026 if (*nplanes != q_data->format.num_planes)
1027 return -EINVAL;
1028
1029 for (i = 0; i < *nplanes; i++) {
1030 unsigned int q_size = q_data->format.plane_fmt[i].sizeimage;
1031
1032 if (sizes[i] < q_size)
1033 return -EINVAL;
1034 }
1035 return 0;
1036 }
1037
1038 *nplanes = q_data->format.num_planes;
1039
1040 for (i = 0; i < *nplanes; i++)
1041 sizes[i] = q_data->format.plane_fmt[i].sizeimage;
1042
1043 return 0;
1044}
1045
1046static int jpu_buf_prepare(struct vb2_buffer *vb)
1047{
1048 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1049 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1050 struct jpu_q_data *q_data;
1051 unsigned int i;
1052
1053 q_data = jpu_get_q_data(ctx, vb->vb2_queue->type);
1054
1055 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1056 if (vbuf->field == V4L2_FIELD_ANY)
1057 vbuf->field = V4L2_FIELD_NONE;
1058 if (vbuf->field != V4L2_FIELD_NONE) {
1059 dev_err(ctx->jpu->dev, "%s field isn't supported\n",
1060 __func__);
1061 return -EINVAL;
1062 }
1063 }
1064
1065 for (i = 0; i < q_data->format.num_planes; i++) {
1066 unsigned long size = q_data->format.plane_fmt[i].sizeimage;
1067
1068 if (vb2_plane_size(vb, i) < size) {
1069 dev_err(ctx->jpu->dev,
1070 "%s: data will not fit into plane (%lu < %lu)\n",
1071 __func__, vb2_plane_size(vb, i), size);
1072 return -EINVAL;
1073 }
1074
1075
1076 if (!ctx->encoder && !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
1077 vb2_set_plane_payload(vb, i, size);
1078 }
1079
1080 return 0;
1081}
1082
1083static void jpu_buf_queue(struct vb2_buffer *vb)
1084{
1085 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1086 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1087
1088 if (!ctx->encoder && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1089 struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf);
1090 struct jpu_q_data *q_data, adjust;
1091 void *buffer = vb2_plane_vaddr(vb, 0);
1092 unsigned long buf_size = vb2_get_plane_payload(vb, 0);
1093 unsigned int width, height;
1094
1095 u8 subsampling = jpu_parse_hdr(buffer, buf_size, &width,
1096 &height);
1097
1098
1099 if (subsampling != JPU_JPEG_422 && subsampling != JPU_JPEG_420)
1100 goto format_error;
1101
1102 q_data = &ctx->out_q;
1103
1104 adjust = *q_data;
1105 adjust.format.width = width;
1106 adjust.format.height = height;
1107
1108 __jpu_try_fmt(ctx, &adjust.fmtinfo, &adjust.format,
1109 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1110
1111 if (adjust.format.width != q_data->format.width ||
1112 adjust.format.height != q_data->format.height)
1113 goto format_error;
1114
1115
1116
1117
1118
1119 jpu_buf->subsampling = subsampling;
1120 }
1121
1122 if (ctx->fh.m2m_ctx)
1123 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1124
1125 return;
1126
1127format_error:
1128 dev_err(ctx->jpu->dev, "incompatible or corrupted JPEG data\n");
1129 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1130}
1131
1132static void jpu_buf_finish(struct vb2_buffer *vb)
1133{
1134 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1135 struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf);
1136 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1137 struct jpu_q_data *q_data = &ctx->out_q;
1138 enum v4l2_buf_type type = vb->vb2_queue->type;
1139 u8 *buffer;
1140
1141 if (vb->state == VB2_BUF_STATE_DONE)
1142 vbuf->sequence = jpu_get_q_data(ctx, type)->sequence++;
1143
1144 if (!ctx->encoder || vb->state != VB2_BUF_STATE_DONE ||
1145 V4L2_TYPE_IS_OUTPUT(type))
1146 return;
1147
1148 buffer = vb2_plane_vaddr(vb, 0);
1149
1150 memcpy(buffer, jpeg_hdrs[jpu_buf->compr_quality], JPU_JPEG_HDR_SIZE);
1151 *(__be16 *)(buffer + JPU_JPEG_HEIGHT_OFFSET) =
1152 cpu_to_be16(q_data->format.height);
1153 *(__be16 *)(buffer + JPU_JPEG_WIDTH_OFFSET) =
1154 cpu_to_be16(q_data->format.width);
1155 *(buffer + JPU_JPEG_SUBS_OFFSET) = q_data->fmtinfo->subsampling;
1156}
1157
1158static int jpu_start_streaming(struct vb2_queue *vq, unsigned count)
1159{
1160 struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
1161 struct jpu_q_data *q_data = jpu_get_q_data(ctx, vq->type);
1162
1163 q_data->sequence = 0;
1164 return 0;
1165}
1166
1167static void jpu_stop_streaming(struct vb2_queue *vq)
1168{
1169 struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
1170 struct vb2_v4l2_buffer *vb;
1171 unsigned long flags;
1172
1173 for (;;) {
1174 if (V4L2_TYPE_IS_OUTPUT(vq->type))
1175 vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1176 else
1177 vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1178 if (vb == NULL)
1179 return;
1180 spin_lock_irqsave(&ctx->jpu->lock, flags);
1181 v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
1182 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1183 }
1184}
1185
1186static const struct vb2_ops jpu_qops = {
1187 .queue_setup = jpu_queue_setup,
1188 .buf_prepare = jpu_buf_prepare,
1189 .buf_queue = jpu_buf_queue,
1190 .buf_finish = jpu_buf_finish,
1191 .start_streaming = jpu_start_streaming,
1192 .stop_streaming = jpu_stop_streaming,
1193 .wait_prepare = vb2_ops_wait_prepare,
1194 .wait_finish = vb2_ops_wait_finish,
1195};
1196
1197static int jpu_queue_init(void *priv, struct vb2_queue *src_vq,
1198 struct vb2_queue *dst_vq)
1199{
1200 struct jpu_ctx *ctx = priv;
1201 int ret;
1202
1203 memset(src_vq, 0, sizeof(*src_vq));
1204 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1205 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1206 src_vq->drv_priv = ctx;
1207 src_vq->buf_struct_size = sizeof(struct jpu_buffer);
1208 src_vq->ops = &jpu_qops;
1209 src_vq->mem_ops = &vb2_dma_contig_memops;
1210 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1211 src_vq->lock = &ctx->jpu->mutex;
1212 src_vq->dev = ctx->jpu->v4l2_dev.dev;
1213
1214 ret = vb2_queue_init(src_vq);
1215 if (ret)
1216 return ret;
1217
1218 memset(dst_vq, 0, sizeof(*dst_vq));
1219 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1220 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1221 dst_vq->drv_priv = ctx;
1222 dst_vq->buf_struct_size = sizeof(struct jpu_buffer);
1223 dst_vq->ops = &jpu_qops;
1224 dst_vq->mem_ops = &vb2_dma_contig_memops;
1225 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1226 dst_vq->lock = &ctx->jpu->mutex;
1227 dst_vq->dev = ctx->jpu->v4l2_dev.dev;
1228
1229 return vb2_queue_init(dst_vq);
1230}
1231
1232
1233
1234
1235
1236
1237static int jpu_open(struct file *file)
1238{
1239 struct jpu *jpu = video_drvdata(file);
1240 struct video_device *vfd = video_devdata(file);
1241 struct jpu_ctx *ctx;
1242 int ret;
1243
1244 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1245 if (!ctx)
1246 return -ENOMEM;
1247
1248 v4l2_fh_init(&ctx->fh, vfd);
1249 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
1250 file->private_data = &ctx->fh;
1251 v4l2_fh_add(&ctx->fh);
1252
1253 ctx->jpu = jpu;
1254 ctx->encoder = vfd == &jpu->vfd_encoder;
1255
1256 __jpu_try_fmt(ctx, &ctx->out_q.fmtinfo, &ctx->out_q.format,
1257 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1258 __jpu_try_fmt(ctx, &ctx->cap_q.fmtinfo, &ctx->cap_q.format,
1259 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1260
1261 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpu->m2m_dev, ctx, jpu_queue_init);
1262 if (IS_ERR(ctx->fh.m2m_ctx)) {
1263 ret = PTR_ERR(ctx->fh.m2m_ctx);
1264 goto v4l_prepare_rollback;
1265 }
1266
1267 ret = jpu_controls_create(ctx);
1268 if (ret < 0)
1269 goto v4l_prepare_rollback;
1270
1271 if (mutex_lock_interruptible(&jpu->mutex)) {
1272 ret = -ERESTARTSYS;
1273 goto v4l_prepare_rollback;
1274 }
1275
1276 if (jpu->ref_count == 0) {
1277 ret = clk_prepare_enable(jpu->clk);
1278 if (ret < 0)
1279 goto device_prepare_rollback;
1280
1281 ret = jpu_reset(jpu);
1282 if (ret)
1283 goto jpu_reset_rollback;
1284 }
1285
1286 jpu->ref_count++;
1287
1288 mutex_unlock(&jpu->mutex);
1289 return 0;
1290
1291jpu_reset_rollback:
1292 clk_disable_unprepare(jpu->clk);
1293device_prepare_rollback:
1294 mutex_unlock(&jpu->mutex);
1295v4l_prepare_rollback:
1296 v4l2_fh_del(&ctx->fh);
1297 v4l2_fh_exit(&ctx->fh);
1298 kfree(ctx);
1299 return ret;
1300}
1301
1302static int jpu_release(struct file *file)
1303{
1304 struct jpu *jpu = video_drvdata(file);
1305 struct jpu_ctx *ctx = fh_to_ctx(file->private_data);
1306
1307 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1308 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1309 v4l2_fh_del(&ctx->fh);
1310 v4l2_fh_exit(&ctx->fh);
1311 kfree(ctx);
1312
1313 mutex_lock(&jpu->mutex);
1314 if (--jpu->ref_count == 0)
1315 clk_disable_unprepare(jpu->clk);
1316 mutex_unlock(&jpu->mutex);
1317
1318 return 0;
1319}
1320
1321static const struct v4l2_file_operations jpu_fops = {
1322 .owner = THIS_MODULE,
1323 .open = jpu_open,
1324 .release = jpu_release,
1325 .unlocked_ioctl = video_ioctl2,
1326 .poll = v4l2_m2m_fop_poll,
1327 .mmap = v4l2_m2m_fop_mmap,
1328};
1329
1330
1331
1332
1333
1334
1335static void jpu_cleanup(struct jpu_ctx *ctx, bool reset)
1336{
1337
1338 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1339 unsigned long flags;
1340
1341 spin_lock_irqsave(&ctx->jpu->lock, flags);
1342
1343 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1344 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1345
1346 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1347 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1348
1349
1350 if (reset)
1351 jpu_write(ctx->jpu, JCCMD_SRST, JCCMD);
1352
1353 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1354
1355 v4l2_m2m_job_finish(ctx->jpu->m2m_dev, ctx->fh.m2m_ctx);
1356}
1357
1358static void jpu_device_run(void *priv)
1359{
1360 struct jpu_ctx *ctx = priv;
1361 struct jpu *jpu = ctx->jpu;
1362 struct jpu_buffer *jpu_buf;
1363 struct jpu_q_data *q_data;
1364 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1365 unsigned int w, h, bpl;
1366 unsigned char num_planes, subsampling;
1367 unsigned long flags;
1368
1369
1370 if (jpu_wait_reset(jpu)) {
1371 jpu_cleanup(ctx, true);
1372 return;
1373 }
1374
1375 spin_lock_irqsave(&ctx->jpu->lock, flags);
1376
1377 jpu->curr = ctx;
1378
1379 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1380 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1381
1382 if (ctx->encoder) {
1383 jpu_buf = vb2_to_jpu_buffer(dst_buf);
1384 q_data = &ctx->out_q;
1385 } else {
1386 jpu_buf = vb2_to_jpu_buffer(src_buf);
1387 q_data = &ctx->cap_q;
1388 }
1389
1390 w = q_data->format.width;
1391 h = q_data->format.height;
1392 bpl = q_data->format.plane_fmt[0].bytesperline;
1393 num_planes = q_data->fmtinfo->num_planes;
1394 subsampling = q_data->fmtinfo->subsampling;
1395
1396 if (ctx->encoder) {
1397 unsigned long src_1_addr, src_2_addr, dst_addr;
1398 unsigned int redu, inft;
1399
1400 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1401 src_1_addr =
1402 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
1403 if (num_planes > 1)
1404 src_2_addr = vb2_dma_contig_plane_dma_addr(
1405 &src_buf->vb2_buf, 1);
1406 else
1407 src_2_addr = src_1_addr + w * h;
1408
1409 jpu_buf->compr_quality = ctx->compr_quality;
1410
1411 if (subsampling == JPU_JPEG_420) {
1412 redu = JCMOD_REDU_420;
1413 inft = JIFECNT_INFT_420;
1414 } else {
1415 redu = JCMOD_REDU_422;
1416 inft = JIFECNT_INFT_422;
1417 }
1418
1419
1420 jpu_write(jpu, JCMOD_DSP_ENC | JCMOD_PCTR | redu |
1421 JCMOD_MSKIP_ENABLE, JCMOD);
1422
1423 jpu_write(jpu, JIFECNT_SWAP_WB | inft, JIFECNT);
1424 jpu_write(jpu, JIFDCNT_SWAP_WB, JIFDCNT);
1425 jpu_write(jpu, JINTE_TRANSF_COMPL, JINTE);
1426
1427
1428 jpu_write(jpu, src_1_addr, JIFESYA1);
1429 jpu_write(jpu, src_2_addr, JIFESCA1);
1430
1431
1432 jpu_write(jpu, bpl, JIFESMW);
1433
1434 jpu_write(jpu, (w >> 8) & JCSZ_MASK, JCHSZU);
1435 jpu_write(jpu, w & JCSZ_MASK, JCHSZD);
1436
1437 jpu_write(jpu, (h >> 8) & JCSZ_MASK, JCVSZU);
1438 jpu_write(jpu, h & JCSZ_MASK, JCVSZD);
1439
1440 jpu_write(jpu, w, JIFESHSZ);
1441 jpu_write(jpu, h, JIFESVSZ);
1442
1443 jpu_write(jpu, dst_addr + JPU_JPEG_HDR_SIZE, JIFEDA1);
1444
1445 jpu_write(jpu, 0 << JCQTN_SHIFT(1) | 1 << JCQTN_SHIFT(2) |
1446 1 << JCQTN_SHIFT(3), JCQTN);
1447
1448 jpu_write(jpu, 0 << JCHTN_AC_SHIFT(1) | 0 << JCHTN_DC_SHIFT(1) |
1449 1 << JCHTN_AC_SHIFT(2) | 1 << JCHTN_DC_SHIFT(2) |
1450 1 << JCHTN_AC_SHIFT(3) | 1 << JCHTN_DC_SHIFT(3),
1451 JCHTN);
1452
1453 jpu_set_qtbl(jpu, ctx->compr_quality);
1454 jpu_set_htbl(jpu);
1455 } else {
1456 unsigned long src_addr, dst_1_addr, dst_2_addr;
1457
1458 if (jpu_buf->subsampling != subsampling) {
1459 dev_err(ctx->jpu->dev,
1460 "src and dst formats do not match.\n");
1461 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1462 jpu_cleanup(ctx, false);
1463 return;
1464 }
1465
1466 src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
1467 dst_1_addr =
1468 vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1469 if (q_data->fmtinfo->num_planes > 1)
1470 dst_2_addr = vb2_dma_contig_plane_dma_addr(
1471 &dst_buf->vb2_buf, 1);
1472 else
1473 dst_2_addr = dst_1_addr + w * h;
1474
1475
1476 jpu_write(jpu, JCMOD_DSP_DEC | JCMOD_PCTR, JCMOD);
1477 jpu_write(jpu, JIFECNT_SWAP_WB, JIFECNT);
1478 jpu_write(jpu, JIFDCNT_SWAP_WB, JIFDCNT);
1479
1480
1481 jpu_write(jpu, JINTE_TRANSF_COMPL | JINTE_ERR, JINTE);
1482
1483
1484 jpu_write(jpu, src_addr, JIFDSA1);
1485 jpu_write(jpu, dst_1_addr, JIFDDYA1);
1486 jpu_write(jpu, dst_2_addr, JIFDDCA1);
1487
1488 jpu_write(jpu, bpl, JIFDDMW);
1489 }
1490
1491
1492 jpu_write(jpu, JCCMD_JSRT, JCCMD);
1493
1494 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1495}
1496
1497static int jpu_job_ready(void *priv)
1498{
1499 return 1;
1500}
1501
1502static void jpu_job_abort(void *priv)
1503{
1504 struct jpu_ctx *ctx = priv;
1505
1506 if (!wait_event_timeout(ctx->jpu->irq_queue, !ctx->jpu->curr,
1507 msecs_to_jiffies(JPU_JOB_TIMEOUT)))
1508 jpu_cleanup(ctx, true);
1509}
1510
1511static const struct v4l2_m2m_ops jpu_m2m_ops = {
1512 .device_run = jpu_device_run,
1513 .job_ready = jpu_job_ready,
1514 .job_abort = jpu_job_abort,
1515};
1516
1517
1518
1519
1520
1521
1522static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
1523{
1524 struct jpu *jpu = dev_id;
1525 struct jpu_ctx *curr_ctx;
1526 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1527 unsigned int int_status;
1528
1529 int_status = jpu_read(jpu, JINTS);
1530
1531
1532 if (!((JINTS_TRANSF_COMPL | JINTS_PROCESS_COMPL | JINTS_ERR) &
1533 int_status))
1534 return IRQ_NONE;
1535
1536
1537 jpu_write(jpu, ~(int_status & JINTS_MASK), JINTS);
1538 if (int_status & (JINTS_ERR | JINTS_PROCESS_COMPL))
1539 jpu_write(jpu, JCCMD_JEND, JCCMD);
1540
1541 spin_lock(&jpu->lock);
1542
1543 if ((int_status & JINTS_PROCESS_COMPL) &&
1544 !(int_status & JINTS_TRANSF_COMPL))
1545 goto handled;
1546
1547 curr_ctx = v4l2_m2m_get_curr_priv(jpu->m2m_dev);
1548 if (!curr_ctx) {
1549
1550 dev_err(jpu->dev, "no active context for m2m\n");
1551 goto handled;
1552 }
1553
1554 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1555 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1556
1557 if (int_status & JINTS_TRANSF_COMPL) {
1558 if (curr_ctx->encoder) {
1559 unsigned long payload_size = jpu_read(jpu, JCDTCU) << 16
1560 | jpu_read(jpu, JCDTCM) << 8
1561 | jpu_read(jpu, JCDTCD);
1562 vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
1563 payload_size + JPU_JPEG_HDR_SIZE);
1564 }
1565
1566 dst_buf->field = src_buf->field;
1567 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
1568 if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE)
1569 dst_buf->timecode = src_buf->timecode;
1570 dst_buf->flags = src_buf->flags &
1571 (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
1572 V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME |
1573 V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
1574
1575 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1576 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1577 } else if (int_status & JINTS_ERR) {
1578 unsigned char error = jpu_read(jpu, JCDERR) & JCDERR_MASK;
1579
1580 dev_dbg(jpu->dev, "processing error: %#X: %s\n", error,
1581 error_to_text[error]);
1582
1583 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1584 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1585 }
1586
1587 jpu->curr = NULL;
1588
1589
1590 jpu_write(jpu, JCCMD_SRST, JCCMD);
1591 spin_unlock(&jpu->lock);
1592
1593 v4l2_m2m_job_finish(jpu->m2m_dev, curr_ctx->fh.m2m_ctx);
1594
1595
1596 wake_up(&jpu->irq_queue);
1597
1598 return IRQ_HANDLED;
1599
1600handled:
1601 spin_unlock(&jpu->lock);
1602 return IRQ_HANDLED;
1603}
1604
1605
1606
1607
1608
1609
1610static const struct of_device_id jpu_dt_ids[] = {
1611 { .compatible = "renesas,jpu-r8a7790" },
1612 { .compatible = "renesas,jpu-r8a7791" },
1613 { .compatible = "renesas,jpu-r8a7792" },
1614 { .compatible = "renesas,jpu-r8a7793" },
1615 { .compatible = "renesas,rcar-gen2-jpu" },
1616 { },
1617};
1618MODULE_DEVICE_TABLE(of, jpu_dt_ids);
1619
1620static int jpu_probe(struct platform_device *pdev)
1621{
1622 struct jpu *jpu;
1623 struct resource *res;
1624 int ret;
1625 unsigned int i;
1626
1627 jpu = devm_kzalloc(&pdev->dev, sizeof(*jpu), GFP_KERNEL);
1628 if (!jpu)
1629 return -ENOMEM;
1630
1631 init_waitqueue_head(&jpu->irq_queue);
1632 mutex_init(&jpu->mutex);
1633 spin_lock_init(&jpu->lock);
1634 jpu->dev = &pdev->dev;
1635
1636
1637 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1638 jpu->regs = devm_ioremap_resource(&pdev->dev, res);
1639 if (IS_ERR(jpu->regs))
1640 return PTR_ERR(jpu->regs);
1641
1642
1643 jpu->irq = ret = platform_get_irq(pdev, 0);
1644 if (ret < 0) {
1645 dev_err(&pdev->dev, "cannot find IRQ\n");
1646 return ret;
1647 }
1648
1649 ret = devm_request_irq(&pdev->dev, jpu->irq, jpu_irq_handler, 0,
1650 dev_name(&pdev->dev), jpu);
1651 if (ret) {
1652 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpu->irq);
1653 return ret;
1654 }
1655
1656
1657 jpu->clk = devm_clk_get(&pdev->dev, NULL);
1658 if (IS_ERR(jpu->clk)) {
1659 dev_err(&pdev->dev, "cannot get clock\n");
1660 return PTR_ERR(jpu->clk);
1661 }
1662
1663
1664 ret = v4l2_device_register(&pdev->dev, &jpu->v4l2_dev);
1665 if (ret) {
1666 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1667 return ret;
1668 }
1669
1670
1671 jpu->m2m_dev = v4l2_m2m_init(&jpu_m2m_ops);
1672 if (IS_ERR(jpu->m2m_dev)) {
1673 v4l2_err(&jpu->v4l2_dev, "Failed to init mem2mem device\n");
1674 ret = PTR_ERR(jpu->m2m_dev);
1675 goto device_register_rollback;
1676 }
1677
1678
1679 for (i = 0; i < JPU_MAX_QUALITY; i++)
1680 jpu_generate_hdr(i, (unsigned char *)jpeg_hdrs[i]);
1681
1682 strscpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name));
1683 jpu->vfd_encoder.fops = &jpu_fops;
1684 jpu->vfd_encoder.ioctl_ops = &jpu_ioctl_ops;
1685 jpu->vfd_encoder.minor = -1;
1686 jpu->vfd_encoder.release = video_device_release_empty;
1687 jpu->vfd_encoder.lock = &jpu->mutex;
1688 jpu->vfd_encoder.v4l2_dev = &jpu->v4l2_dev;
1689 jpu->vfd_encoder.vfl_dir = VFL_DIR_M2M;
1690
1691 ret = video_register_device(&jpu->vfd_encoder, VFL_TYPE_GRABBER, -1);
1692 if (ret) {
1693 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");
1694 goto m2m_init_rollback;
1695 }
1696
1697 video_set_drvdata(&jpu->vfd_encoder, jpu);
1698
1699 strscpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name));
1700 jpu->vfd_decoder.fops = &jpu_fops;
1701 jpu->vfd_decoder.ioctl_ops = &jpu_ioctl_ops;
1702 jpu->vfd_decoder.minor = -1;
1703 jpu->vfd_decoder.release = video_device_release_empty;
1704 jpu->vfd_decoder.lock = &jpu->mutex;
1705 jpu->vfd_decoder.v4l2_dev = &jpu->v4l2_dev;
1706 jpu->vfd_decoder.vfl_dir = VFL_DIR_M2M;
1707
1708 ret = video_register_device(&jpu->vfd_decoder, VFL_TYPE_GRABBER, -1);
1709 if (ret) {
1710 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");
1711 goto enc_vdev_register_rollback;
1712 }
1713
1714 video_set_drvdata(&jpu->vfd_decoder, jpu);
1715 platform_set_drvdata(pdev, jpu);
1716
1717 v4l2_info(&jpu->v4l2_dev, "encoder device registered as /dev/video%d\n",
1718 jpu->vfd_encoder.num);
1719 v4l2_info(&jpu->v4l2_dev, "decoder device registered as /dev/video%d\n",
1720 jpu->vfd_decoder.num);
1721
1722 return 0;
1723
1724enc_vdev_register_rollback:
1725 video_unregister_device(&jpu->vfd_encoder);
1726
1727m2m_init_rollback:
1728 v4l2_m2m_release(jpu->m2m_dev);
1729
1730device_register_rollback:
1731 v4l2_device_unregister(&jpu->v4l2_dev);
1732
1733 return ret;
1734}
1735
1736static int jpu_remove(struct platform_device *pdev)
1737{
1738 struct jpu *jpu = platform_get_drvdata(pdev);
1739
1740 video_unregister_device(&jpu->vfd_decoder);
1741 video_unregister_device(&jpu->vfd_encoder);
1742 v4l2_m2m_release(jpu->m2m_dev);
1743 v4l2_device_unregister(&jpu->v4l2_dev);
1744
1745 return 0;
1746}
1747
1748#ifdef CONFIG_PM_SLEEP
1749static int jpu_suspend(struct device *dev)
1750{
1751 struct jpu *jpu = dev_get_drvdata(dev);
1752
1753 if (jpu->ref_count == 0)
1754 return 0;
1755
1756 clk_disable_unprepare(jpu->clk);
1757
1758 return 0;
1759}
1760
1761static int jpu_resume(struct device *dev)
1762{
1763 struct jpu *jpu = dev_get_drvdata(dev);
1764
1765 if (jpu->ref_count == 0)
1766 return 0;
1767
1768 clk_prepare_enable(jpu->clk);
1769
1770 return 0;
1771}
1772#endif
1773
1774static const struct dev_pm_ops jpu_pm_ops = {
1775 SET_SYSTEM_SLEEP_PM_OPS(jpu_suspend, jpu_resume)
1776};
1777
1778static struct platform_driver jpu_driver = {
1779 .probe = jpu_probe,
1780 .remove = jpu_remove,
1781 .driver = {
1782 .of_match_table = jpu_dt_ids,
1783 .name = DRV_NAME,
1784 .pm = &jpu_pm_ops,
1785 },
1786};
1787
1788module_platform_driver(jpu_driver);
1789
1790MODULE_ALIAS("platform:" DRV_NAME);
1791MODULE_AUTHOR("Mikhail Ulianov <mikhail.ulyanov@cogentembedded.com>");
1792MODULE_DESCRIPTION("Renesas R-Car JPEG processing unit driver");
1793MODULE_LICENSE("GPL v2");
1794