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