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 break;
652 case 0:
653 break;
654 default:
655 return 0;
656 }
657 }
658
659 return 0;
660}
661
662static int jpu_querycap(struct file *file, void *priv,
663 struct v4l2_capability *cap)
664{
665 struct jpu_ctx *ctx = fh_to_ctx(priv);
666
667 if (ctx->encoder)
668 strscpy(cap->card, DRV_NAME " encoder", sizeof(cap->card));
669 else
670 strscpy(cap->card, DRV_NAME " decoder", sizeof(cap->card));
671
672 strscpy(cap->driver, DRV_NAME, sizeof(cap->driver));
673 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
674 dev_name(ctx->jpu->dev));
675 memset(cap->reserved, 0, sizeof(cap->reserved));
676
677 return 0;
678}
679
680static struct jpu_fmt *jpu_find_format(bool encoder, u32 pixelformat,
681 unsigned int fmt_type)
682{
683 unsigned int i, fmt_flag;
684
685 if (encoder)
686 fmt_flag = fmt_type == JPU_FMT_TYPE_OUTPUT ? JPU_ENC_OUTPUT :
687 JPU_ENC_CAPTURE;
688 else
689 fmt_flag = fmt_type == JPU_FMT_TYPE_OUTPUT ? JPU_DEC_OUTPUT :
690 JPU_DEC_CAPTURE;
691
692 for (i = 0; i < ARRAY_SIZE(jpu_formats); i++) {
693 struct jpu_fmt *fmt = &jpu_formats[i];
694
695 if (fmt->fourcc == pixelformat && fmt->types & fmt_flag)
696 return fmt;
697 }
698
699 return NULL;
700}
701
702static int jpu_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
703{
704 unsigned int i, num = 0;
705
706 for (i = 0; i < ARRAY_SIZE(jpu_formats); ++i) {
707 if (jpu_formats[i].types & type) {
708 if (num == f->index)
709 break;
710 ++num;
711 }
712 }
713
714 if (i >= ARRAY_SIZE(jpu_formats))
715 return -EINVAL;
716
717 f->pixelformat = jpu_formats[i].fourcc;
718
719 return 0;
720}
721
722static int jpu_enum_fmt_cap(struct file *file, void *priv,
723 struct v4l2_fmtdesc *f)
724{
725 struct jpu_ctx *ctx = fh_to_ctx(priv);
726
727 return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_CAPTURE :
728 JPU_DEC_CAPTURE);
729}
730
731static int jpu_enum_fmt_out(struct file *file, void *priv,
732 struct v4l2_fmtdesc *f)
733{
734 struct jpu_ctx *ctx = fh_to_ctx(priv);
735
736 return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_OUTPUT : JPU_DEC_OUTPUT);
737}
738
739static struct jpu_q_data *jpu_get_q_data(struct jpu_ctx *ctx,
740 enum v4l2_buf_type type)
741{
742 if (V4L2_TYPE_IS_OUTPUT(type))
743 return &ctx->out_q;
744 else
745 return &ctx->cap_q;
746}
747
748static void jpu_bound_align_image(u32 *w, unsigned int w_min,
749 unsigned int w_max, unsigned int w_align,
750 u32 *h, unsigned int h_min,
751 unsigned int h_max, unsigned int h_align)
752{
753 unsigned int width, height, w_step, h_step;
754
755 width = *w;
756 height = *h;
757
758 w_step = 1U << w_align;
759 h_step = 1U << h_align;
760 v4l_bound_align_image(w, w_min, w_max, w_align, h, h_min, h_max,
761 h_align, 3);
762
763 if (*w < width && *w + w_step < w_max)
764 *w += w_step;
765 if (*h < height && *h + h_step < h_max)
766 *h += h_step;
767}
768
769static int __jpu_try_fmt(struct jpu_ctx *ctx, struct jpu_fmt **fmtinfo,
770 struct v4l2_pix_format_mplane *pix,
771 enum v4l2_buf_type type)
772{
773 struct jpu_fmt *fmt;
774 unsigned int f_type, w, h;
775
776 f_type = V4L2_TYPE_IS_OUTPUT(type) ? JPU_FMT_TYPE_OUTPUT :
777 JPU_FMT_TYPE_CAPTURE;
778
779 fmt = jpu_find_format(ctx->encoder, pix->pixelformat, f_type);
780 if (!fmt) {
781 unsigned int pixelformat;
782
783 dev_dbg(ctx->jpu->dev, "unknown format; set default format\n");
784 if (ctx->encoder)
785 pixelformat = f_type == JPU_FMT_TYPE_OUTPUT ?
786 V4L2_PIX_FMT_NV16M : V4L2_PIX_FMT_JPEG;
787 else
788 pixelformat = f_type == JPU_FMT_TYPE_CAPTURE ?
789 V4L2_PIX_FMT_NV16M : V4L2_PIX_FMT_JPEG;
790 fmt = jpu_find_format(ctx->encoder, pixelformat, f_type);
791 }
792
793 pix->pixelformat = fmt->fourcc;
794 pix->colorspace = fmt->colorspace;
795 pix->field = V4L2_FIELD_NONE;
796 pix->num_planes = fmt->num_planes;
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 } else {
812 unsigned int i, bpl = 0;
813
814 for (i = 0; i < pix->num_planes; ++i)
815 bpl = max(bpl, pix->plane_fmt[i].bytesperline);
816
817 bpl = clamp_t(unsigned int, bpl, w, JPU_WIDTH_MAX);
818 bpl = round_up(bpl, JPU_MEMALIGN);
819
820 for (i = 0; i < pix->num_planes; ++i) {
821 pix->plane_fmt[i].bytesperline = bpl;
822 pix->plane_fmt[i].sizeimage = bpl * h * fmt->bpp[i] / 8;
823 }
824 }
825
826 if (fmtinfo)
827 *fmtinfo = fmt;
828
829 return 0;
830}
831
832static int jpu_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
833{
834 struct jpu_ctx *ctx = fh_to_ctx(priv);
835
836 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
837 return -EINVAL;
838
839 return __jpu_try_fmt(ctx, NULL, &f->fmt.pix_mp, f->type);
840}
841
842static int jpu_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
843{
844 struct vb2_queue *vq;
845 struct jpu_ctx *ctx = fh_to_ctx(priv);
846 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
847 struct jpu_fmt *fmtinfo;
848 struct jpu_q_data *q_data;
849 int ret;
850
851 vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
852 if (!vq)
853 return -EINVAL;
854
855 if (vb2_is_busy(vq)) {
856 v4l2_err(&ctx->jpu->v4l2_dev, "%s queue busy\n", __func__);
857 return -EBUSY;
858 }
859
860 ret = __jpu_try_fmt(ctx, &fmtinfo, &f->fmt.pix_mp, f->type);
861 if (ret < 0)
862 return ret;
863
864 q_data = jpu_get_q_data(ctx, f->type);
865
866 q_data->format = f->fmt.pix_mp;
867 q_data->fmtinfo = fmtinfo;
868
869 return 0;
870}
871
872static int jpu_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
873{
874 struct jpu_q_data *q_data;
875 struct jpu_ctx *ctx = fh_to_ctx(priv);
876
877 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
878 return -EINVAL;
879
880 q_data = jpu_get_q_data(ctx, f->type);
881 f->fmt.pix_mp = q_data->format;
882
883 return 0;
884}
885
886
887
888
889static int jpu_s_ctrl(struct v4l2_ctrl *ctrl)
890{
891 struct jpu_ctx *ctx = ctrl_to_ctx(ctrl);
892 unsigned long flags;
893
894 spin_lock_irqsave(&ctx->jpu->lock, flags);
895 if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY)
896 ctx->compr_quality = ctrl->val;
897 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
898
899 return 0;
900}
901
902static const struct v4l2_ctrl_ops jpu_ctrl_ops = {
903 .s_ctrl = jpu_s_ctrl,
904};
905
906static int jpu_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
907{
908 struct jpu_ctx *ctx = fh_to_ctx(priv);
909 struct jpu_q_data *src_q_data, *dst_q_data, *orig, adj, *ref;
910 enum v4l2_buf_type adj_type;
911
912 src_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
913 dst_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
914
915 if (ctx->encoder) {
916 adj = *src_q_data;
917 orig = src_q_data;
918 ref = dst_q_data;
919 adj_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
920 } else {
921 adj = *dst_q_data;
922 orig = dst_q_data;
923 ref = src_q_data;
924 adj_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
925 }
926
927 adj.format.width = ref->format.width;
928 adj.format.height = ref->format.height;
929
930 __jpu_try_fmt(ctx, NULL, &adj.format, adj_type);
931
932 if (adj.format.width != orig->format.width ||
933 adj.format.height != orig->format.height) {
934 dev_err(ctx->jpu->dev, "src and dst formats do not match.\n");
935
936 return -EINVAL;
937 }
938
939 return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type);
940}
941
942static const struct v4l2_ioctl_ops jpu_ioctl_ops = {
943 .vidioc_querycap = jpu_querycap,
944
945 .vidioc_enum_fmt_vid_cap = jpu_enum_fmt_cap,
946 .vidioc_enum_fmt_vid_out = jpu_enum_fmt_out,
947 .vidioc_g_fmt_vid_cap_mplane = jpu_g_fmt,
948 .vidioc_g_fmt_vid_out_mplane = jpu_g_fmt,
949 .vidioc_try_fmt_vid_cap_mplane = jpu_try_fmt,
950 .vidioc_try_fmt_vid_out_mplane = jpu_try_fmt,
951 .vidioc_s_fmt_vid_cap_mplane = jpu_s_fmt,
952 .vidioc_s_fmt_vid_out_mplane = jpu_s_fmt,
953
954 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
955 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
956 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
957 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
958 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
959 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
960
961 .vidioc_streamon = jpu_streamon,
962 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
963
964 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
965 .vidioc_unsubscribe_event = v4l2_event_unsubscribe
966};
967
968static int jpu_controls_create(struct jpu_ctx *ctx)
969{
970 struct v4l2_ctrl *ctrl;
971 int ret;
972
973 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
974
975 ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler, &jpu_ctrl_ops,
976 V4L2_CID_JPEG_COMPRESSION_QUALITY,
977 0, JPU_MAX_QUALITY - 1, 1, 0);
978
979 if (ctx->ctrl_handler.error) {
980 ret = ctx->ctrl_handler.error;
981 goto error_free;
982 }
983
984 if (!ctx->encoder)
985 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
986 V4L2_CTRL_FLAG_READ_ONLY;
987
988 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
989 if (ret < 0)
990 goto error_free;
991
992 return 0;
993
994error_free:
995 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
996 return ret;
997}
998
999
1000
1001
1002
1003
1004static int jpu_queue_setup(struct vb2_queue *vq,
1005 unsigned int *nbuffers, unsigned int *nplanes,
1006 unsigned int sizes[], struct device *alloc_devs[])
1007{
1008 struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
1009 struct jpu_q_data *q_data;
1010 unsigned int i;
1011
1012 q_data = jpu_get_q_data(ctx, vq->type);
1013
1014 if (*nplanes) {
1015 if (*nplanes != q_data->format.num_planes)
1016 return -EINVAL;
1017
1018 for (i = 0; i < *nplanes; i++) {
1019 unsigned int q_size = q_data->format.plane_fmt[i].sizeimage;
1020
1021 if (sizes[i] < q_size)
1022 return -EINVAL;
1023 }
1024 return 0;
1025 }
1026
1027 *nplanes = q_data->format.num_planes;
1028
1029 for (i = 0; i < *nplanes; i++)
1030 sizes[i] = q_data->format.plane_fmt[i].sizeimage;
1031
1032 return 0;
1033}
1034
1035static int jpu_buf_prepare(struct vb2_buffer *vb)
1036{
1037 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1038 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1039 struct jpu_q_data *q_data;
1040 unsigned int i;
1041
1042 q_data = jpu_get_q_data(ctx, vb->vb2_queue->type);
1043
1044 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1045 if (vbuf->field == V4L2_FIELD_ANY)
1046 vbuf->field = V4L2_FIELD_NONE;
1047 if (vbuf->field != V4L2_FIELD_NONE) {
1048 dev_err(ctx->jpu->dev, "%s field isn't supported\n",
1049 __func__);
1050 return -EINVAL;
1051 }
1052 }
1053
1054 for (i = 0; i < q_data->format.num_planes; i++) {
1055 unsigned long size = q_data->format.plane_fmt[i].sizeimage;
1056
1057 if (vb2_plane_size(vb, i) < size) {
1058 dev_err(ctx->jpu->dev,
1059 "%s: data will not fit into plane (%lu < %lu)\n",
1060 __func__, vb2_plane_size(vb, i), size);
1061 return -EINVAL;
1062 }
1063
1064
1065 if (!ctx->encoder && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type))
1066 vb2_set_plane_payload(vb, i, size);
1067 }
1068
1069 return 0;
1070}
1071
1072static void jpu_buf_queue(struct vb2_buffer *vb)
1073{
1074 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1075 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1076
1077 if (!ctx->encoder && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1078 struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf);
1079 struct jpu_q_data *q_data, adjust;
1080 void *buffer = vb2_plane_vaddr(vb, 0);
1081 unsigned long buf_size = vb2_get_plane_payload(vb, 0);
1082 unsigned int width, height;
1083
1084 u8 subsampling = jpu_parse_hdr(buffer, buf_size, &width,
1085 &height);
1086
1087
1088 if (subsampling != JPU_JPEG_422 && subsampling != JPU_JPEG_420)
1089 goto format_error;
1090
1091 q_data = &ctx->out_q;
1092
1093 adjust = *q_data;
1094 adjust.format.width = width;
1095 adjust.format.height = height;
1096
1097 __jpu_try_fmt(ctx, &adjust.fmtinfo, &adjust.format,
1098 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1099
1100 if (adjust.format.width != q_data->format.width ||
1101 adjust.format.height != q_data->format.height)
1102 goto format_error;
1103
1104
1105
1106
1107
1108 jpu_buf->subsampling = subsampling;
1109 }
1110
1111 if (ctx->fh.m2m_ctx)
1112 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1113
1114 return;
1115
1116format_error:
1117 dev_err(ctx->jpu->dev, "incompatible or corrupted JPEG data\n");
1118 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1119}
1120
1121static void jpu_buf_finish(struct vb2_buffer *vb)
1122{
1123 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1124 struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf);
1125 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1126 struct jpu_q_data *q_data = &ctx->out_q;
1127 enum v4l2_buf_type type = vb->vb2_queue->type;
1128 u8 *buffer;
1129
1130 if (vb->state == VB2_BUF_STATE_DONE)
1131 vbuf->sequence = jpu_get_q_data(ctx, type)->sequence++;
1132
1133 if (!ctx->encoder || vb->state != VB2_BUF_STATE_DONE ||
1134 V4L2_TYPE_IS_OUTPUT(type))
1135 return;
1136
1137 buffer = vb2_plane_vaddr(vb, 0);
1138
1139 memcpy(buffer, jpeg_hdrs[jpu_buf->compr_quality], JPU_JPEG_HDR_SIZE);
1140 *(__be16 *)(buffer + JPU_JPEG_HEIGHT_OFFSET) =
1141 cpu_to_be16(q_data->format.height);
1142 *(__be16 *)(buffer + JPU_JPEG_WIDTH_OFFSET) =
1143 cpu_to_be16(q_data->format.width);
1144 *(buffer + JPU_JPEG_SUBS_OFFSET) = q_data->fmtinfo->subsampling;
1145}
1146
1147static int jpu_start_streaming(struct vb2_queue *vq, unsigned count)
1148{
1149 struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
1150 struct jpu_q_data *q_data = jpu_get_q_data(ctx, vq->type);
1151
1152 q_data->sequence = 0;
1153 return 0;
1154}
1155
1156static void jpu_stop_streaming(struct vb2_queue *vq)
1157{
1158 struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
1159 struct vb2_v4l2_buffer *vb;
1160 unsigned long flags;
1161
1162 for (;;) {
1163 if (V4L2_TYPE_IS_OUTPUT(vq->type))
1164 vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1165 else
1166 vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1167 if (vb == NULL)
1168 return;
1169 spin_lock_irqsave(&ctx->jpu->lock, flags);
1170 v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
1171 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1172 }
1173}
1174
1175static const struct vb2_ops jpu_qops = {
1176 .queue_setup = jpu_queue_setup,
1177 .buf_prepare = jpu_buf_prepare,
1178 .buf_queue = jpu_buf_queue,
1179 .buf_finish = jpu_buf_finish,
1180 .start_streaming = jpu_start_streaming,
1181 .stop_streaming = jpu_stop_streaming,
1182 .wait_prepare = vb2_ops_wait_prepare,
1183 .wait_finish = vb2_ops_wait_finish,
1184};
1185
1186static int jpu_queue_init(void *priv, struct vb2_queue *src_vq,
1187 struct vb2_queue *dst_vq)
1188{
1189 struct jpu_ctx *ctx = priv;
1190 int ret;
1191
1192 memset(src_vq, 0, sizeof(*src_vq));
1193 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1194 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1195 src_vq->drv_priv = ctx;
1196 src_vq->buf_struct_size = sizeof(struct jpu_buffer);
1197 src_vq->ops = &jpu_qops;
1198 src_vq->mem_ops = &vb2_dma_contig_memops;
1199 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1200 src_vq->lock = &ctx->jpu->mutex;
1201 src_vq->dev = ctx->jpu->v4l2_dev.dev;
1202
1203 ret = vb2_queue_init(src_vq);
1204 if (ret)
1205 return ret;
1206
1207 memset(dst_vq, 0, sizeof(*dst_vq));
1208 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1209 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1210 dst_vq->drv_priv = ctx;
1211 dst_vq->buf_struct_size = sizeof(struct jpu_buffer);
1212 dst_vq->ops = &jpu_qops;
1213 dst_vq->mem_ops = &vb2_dma_contig_memops;
1214 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1215 dst_vq->lock = &ctx->jpu->mutex;
1216 dst_vq->dev = ctx->jpu->v4l2_dev.dev;
1217
1218 return vb2_queue_init(dst_vq);
1219}
1220
1221
1222
1223
1224
1225
1226static int jpu_open(struct file *file)
1227{
1228 struct jpu *jpu = video_drvdata(file);
1229 struct video_device *vfd = video_devdata(file);
1230 struct jpu_ctx *ctx;
1231 int ret;
1232
1233 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1234 if (!ctx)
1235 return -ENOMEM;
1236
1237 v4l2_fh_init(&ctx->fh, vfd);
1238 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
1239 file->private_data = &ctx->fh;
1240 v4l2_fh_add(&ctx->fh);
1241
1242 ctx->jpu = jpu;
1243 ctx->encoder = vfd == &jpu->vfd_encoder;
1244
1245 __jpu_try_fmt(ctx, &ctx->out_q.fmtinfo, &ctx->out_q.format,
1246 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1247 __jpu_try_fmt(ctx, &ctx->cap_q.fmtinfo, &ctx->cap_q.format,
1248 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1249
1250 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpu->m2m_dev, ctx, jpu_queue_init);
1251 if (IS_ERR(ctx->fh.m2m_ctx)) {
1252 ret = PTR_ERR(ctx->fh.m2m_ctx);
1253 goto v4l_prepare_rollback;
1254 }
1255
1256 ret = jpu_controls_create(ctx);
1257 if (ret < 0)
1258 goto v4l_prepare_rollback;
1259
1260 if (mutex_lock_interruptible(&jpu->mutex)) {
1261 ret = -ERESTARTSYS;
1262 goto v4l_prepare_rollback;
1263 }
1264
1265 if (jpu->ref_count == 0) {
1266 ret = clk_prepare_enable(jpu->clk);
1267 if (ret < 0)
1268 goto device_prepare_rollback;
1269
1270 ret = jpu_reset(jpu);
1271 if (ret)
1272 goto jpu_reset_rollback;
1273 }
1274
1275 jpu->ref_count++;
1276
1277 mutex_unlock(&jpu->mutex);
1278 return 0;
1279
1280jpu_reset_rollback:
1281 clk_disable_unprepare(jpu->clk);
1282device_prepare_rollback:
1283 mutex_unlock(&jpu->mutex);
1284v4l_prepare_rollback:
1285 v4l2_fh_del(&ctx->fh);
1286 v4l2_fh_exit(&ctx->fh);
1287 kfree(ctx);
1288 return ret;
1289}
1290
1291static int jpu_release(struct file *file)
1292{
1293 struct jpu *jpu = video_drvdata(file);
1294 struct jpu_ctx *ctx = fh_to_ctx(file->private_data);
1295
1296 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1297 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1298 v4l2_fh_del(&ctx->fh);
1299 v4l2_fh_exit(&ctx->fh);
1300 kfree(ctx);
1301
1302 mutex_lock(&jpu->mutex);
1303 if (--jpu->ref_count == 0)
1304 clk_disable_unprepare(jpu->clk);
1305 mutex_unlock(&jpu->mutex);
1306
1307 return 0;
1308}
1309
1310static const struct v4l2_file_operations jpu_fops = {
1311 .owner = THIS_MODULE,
1312 .open = jpu_open,
1313 .release = jpu_release,
1314 .unlocked_ioctl = video_ioctl2,
1315 .poll = v4l2_m2m_fop_poll,
1316 .mmap = v4l2_m2m_fop_mmap,
1317};
1318
1319
1320
1321
1322
1323
1324static void jpu_cleanup(struct jpu_ctx *ctx, bool reset)
1325{
1326
1327 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1328 unsigned long flags;
1329
1330 spin_lock_irqsave(&ctx->jpu->lock, flags);
1331
1332 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1333 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1334
1335 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1336 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1337
1338
1339 if (reset)
1340 jpu_write(ctx->jpu, JCCMD_SRST, JCCMD);
1341
1342 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1343
1344 v4l2_m2m_job_finish(ctx->jpu->m2m_dev, ctx->fh.m2m_ctx);
1345}
1346
1347static void jpu_device_run(void *priv)
1348{
1349 struct jpu_ctx *ctx = priv;
1350 struct jpu *jpu = ctx->jpu;
1351 struct jpu_buffer *jpu_buf;
1352 struct jpu_q_data *q_data;
1353 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1354 unsigned int w, h, bpl;
1355 unsigned char num_planes, subsampling;
1356 unsigned long flags;
1357
1358
1359 if (jpu_wait_reset(jpu)) {
1360 jpu_cleanup(ctx, true);
1361 return;
1362 }
1363
1364 spin_lock_irqsave(&ctx->jpu->lock, flags);
1365
1366 jpu->curr = ctx;
1367
1368 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1369 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1370
1371 if (ctx->encoder) {
1372 jpu_buf = vb2_to_jpu_buffer(dst_buf);
1373 q_data = &ctx->out_q;
1374 } else {
1375 jpu_buf = vb2_to_jpu_buffer(src_buf);
1376 q_data = &ctx->cap_q;
1377 }
1378
1379 w = q_data->format.width;
1380 h = q_data->format.height;
1381 bpl = q_data->format.plane_fmt[0].bytesperline;
1382 num_planes = q_data->fmtinfo->num_planes;
1383 subsampling = q_data->fmtinfo->subsampling;
1384
1385 if (ctx->encoder) {
1386 unsigned long src_1_addr, src_2_addr, dst_addr;
1387 unsigned int redu, inft;
1388
1389 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1390 src_1_addr =
1391 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
1392 if (num_planes > 1)
1393 src_2_addr = vb2_dma_contig_plane_dma_addr(
1394 &src_buf->vb2_buf, 1);
1395 else
1396 src_2_addr = src_1_addr + w * h;
1397
1398 jpu_buf->compr_quality = ctx->compr_quality;
1399
1400 if (subsampling == JPU_JPEG_420) {
1401 redu = JCMOD_REDU_420;
1402 inft = JIFECNT_INFT_420;
1403 } else {
1404 redu = JCMOD_REDU_422;
1405 inft = JIFECNT_INFT_422;
1406 }
1407
1408
1409 jpu_write(jpu, JCMOD_DSP_ENC | JCMOD_PCTR | redu |
1410 JCMOD_MSKIP_ENABLE, JCMOD);
1411
1412 jpu_write(jpu, JIFECNT_SWAP_WB | inft, JIFECNT);
1413 jpu_write(jpu, JIFDCNT_SWAP_WB, JIFDCNT);
1414 jpu_write(jpu, JINTE_TRANSF_COMPL, JINTE);
1415
1416
1417 jpu_write(jpu, src_1_addr, JIFESYA1);
1418 jpu_write(jpu, src_2_addr, JIFESCA1);
1419
1420
1421 jpu_write(jpu, bpl, JIFESMW);
1422
1423 jpu_write(jpu, (w >> 8) & JCSZ_MASK, JCHSZU);
1424 jpu_write(jpu, w & JCSZ_MASK, JCHSZD);
1425
1426 jpu_write(jpu, (h >> 8) & JCSZ_MASK, JCVSZU);
1427 jpu_write(jpu, h & JCSZ_MASK, JCVSZD);
1428
1429 jpu_write(jpu, w, JIFESHSZ);
1430 jpu_write(jpu, h, JIFESVSZ);
1431
1432 jpu_write(jpu, dst_addr + JPU_JPEG_HDR_SIZE, JIFEDA1);
1433
1434 jpu_write(jpu, 0 << JCQTN_SHIFT(1) | 1 << JCQTN_SHIFT(2) |
1435 1 << JCQTN_SHIFT(3), JCQTN);
1436
1437 jpu_write(jpu, 0 << JCHTN_AC_SHIFT(1) | 0 << JCHTN_DC_SHIFT(1) |
1438 1 << JCHTN_AC_SHIFT(2) | 1 << JCHTN_DC_SHIFT(2) |
1439 1 << JCHTN_AC_SHIFT(3) | 1 << JCHTN_DC_SHIFT(3),
1440 JCHTN);
1441
1442 jpu_set_qtbl(jpu, ctx->compr_quality);
1443 jpu_set_htbl(jpu);
1444 } else {
1445 unsigned long src_addr, dst_1_addr, dst_2_addr;
1446
1447 if (jpu_buf->subsampling != subsampling) {
1448 dev_err(ctx->jpu->dev,
1449 "src and dst formats do not match.\n");
1450 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1451 jpu_cleanup(ctx, false);
1452 return;
1453 }
1454
1455 src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
1456 dst_1_addr =
1457 vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1458 if (q_data->fmtinfo->num_planes > 1)
1459 dst_2_addr = vb2_dma_contig_plane_dma_addr(
1460 &dst_buf->vb2_buf, 1);
1461 else
1462 dst_2_addr = dst_1_addr + w * h;
1463
1464
1465 jpu_write(jpu, JCMOD_DSP_DEC | JCMOD_PCTR, JCMOD);
1466 jpu_write(jpu, JIFECNT_SWAP_WB, JIFECNT);
1467 jpu_write(jpu, JIFDCNT_SWAP_WB, JIFDCNT);
1468
1469
1470 jpu_write(jpu, JINTE_TRANSF_COMPL | JINTE_ERR, JINTE);
1471
1472
1473 jpu_write(jpu, src_addr, JIFDSA1);
1474 jpu_write(jpu, dst_1_addr, JIFDDYA1);
1475 jpu_write(jpu, dst_2_addr, JIFDDCA1);
1476
1477 jpu_write(jpu, bpl, JIFDDMW);
1478 }
1479
1480
1481 jpu_write(jpu, JCCMD_JSRT, JCCMD);
1482
1483 spin_unlock_irqrestore(&ctx->jpu->lock, flags);
1484}
1485
1486static const struct v4l2_m2m_ops jpu_m2m_ops = {
1487 .device_run = jpu_device_run,
1488};
1489
1490
1491
1492
1493
1494
1495static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
1496{
1497 struct jpu *jpu = dev_id;
1498 struct jpu_ctx *curr_ctx;
1499 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1500 unsigned int int_status;
1501
1502 int_status = jpu_read(jpu, JINTS);
1503
1504
1505 if (!((JINTS_TRANSF_COMPL | JINTS_PROCESS_COMPL | JINTS_ERR) &
1506 int_status))
1507 return IRQ_NONE;
1508
1509
1510 jpu_write(jpu, ~(int_status & JINTS_MASK), JINTS);
1511 if (int_status & (JINTS_ERR | JINTS_PROCESS_COMPL))
1512 jpu_write(jpu, JCCMD_JEND, JCCMD);
1513
1514 spin_lock(&jpu->lock);
1515
1516 if ((int_status & JINTS_PROCESS_COMPL) &&
1517 !(int_status & JINTS_TRANSF_COMPL))
1518 goto handled;
1519
1520 curr_ctx = v4l2_m2m_get_curr_priv(jpu->m2m_dev);
1521 if (!curr_ctx) {
1522
1523 dev_err(jpu->dev, "no active context for m2m\n");
1524 goto handled;
1525 }
1526
1527 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1528 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1529
1530 if (int_status & JINTS_TRANSF_COMPL) {
1531 if (curr_ctx->encoder) {
1532 unsigned long payload_size = jpu_read(jpu, JCDTCU) << 16
1533 | jpu_read(jpu, JCDTCM) << 8
1534 | jpu_read(jpu, JCDTCD);
1535 vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
1536 payload_size + JPU_JPEG_HDR_SIZE);
1537 }
1538
1539 dst_buf->field = src_buf->field;
1540 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
1541 if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE)
1542 dst_buf->timecode = src_buf->timecode;
1543 dst_buf->flags = src_buf->flags &
1544 (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
1545 V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME |
1546 V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
1547
1548 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1549 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1550 } else if (int_status & JINTS_ERR) {
1551 unsigned char error = jpu_read(jpu, JCDERR) & JCDERR_MASK;
1552
1553 dev_dbg(jpu->dev, "processing error: %#X: %s\n", error,
1554 error_to_text[error]);
1555
1556 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1557 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1558 }
1559
1560 jpu->curr = NULL;
1561
1562
1563 jpu_write(jpu, JCCMD_SRST, JCCMD);
1564 spin_unlock(&jpu->lock);
1565
1566 v4l2_m2m_job_finish(jpu->m2m_dev, curr_ctx->fh.m2m_ctx);
1567
1568 return IRQ_HANDLED;
1569
1570handled:
1571 spin_unlock(&jpu->lock);
1572 return IRQ_HANDLED;
1573}
1574
1575
1576
1577
1578
1579
1580static const struct of_device_id jpu_dt_ids[] = {
1581 { .compatible = "renesas,jpu-r8a7790" },
1582 { .compatible = "renesas,jpu-r8a7791" },
1583 { .compatible = "renesas,jpu-r8a7792" },
1584 { .compatible = "renesas,jpu-r8a7793" },
1585 { .compatible = "renesas,rcar-gen2-jpu" },
1586 { },
1587};
1588MODULE_DEVICE_TABLE(of, jpu_dt_ids);
1589
1590static int jpu_probe(struct platform_device *pdev)
1591{
1592 struct jpu *jpu;
1593 int ret;
1594 unsigned int i;
1595
1596 jpu = devm_kzalloc(&pdev->dev, sizeof(*jpu), GFP_KERNEL);
1597 if (!jpu)
1598 return -ENOMEM;
1599
1600 mutex_init(&jpu->mutex);
1601 spin_lock_init(&jpu->lock);
1602 jpu->dev = &pdev->dev;
1603
1604
1605 jpu->regs = devm_platform_ioremap_resource(pdev, 0);
1606 if (IS_ERR(jpu->regs))
1607 return PTR_ERR(jpu->regs);
1608
1609
1610 jpu->irq = ret = platform_get_irq(pdev, 0);
1611 if (ret < 0) {
1612 dev_err(&pdev->dev, "cannot find IRQ\n");
1613 return ret;
1614 }
1615
1616 ret = devm_request_irq(&pdev->dev, jpu->irq, jpu_irq_handler, 0,
1617 dev_name(&pdev->dev), jpu);
1618 if (ret) {
1619 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpu->irq);
1620 return ret;
1621 }
1622
1623
1624 jpu->clk = devm_clk_get(&pdev->dev, NULL);
1625 if (IS_ERR(jpu->clk)) {
1626 dev_err(&pdev->dev, "cannot get clock\n");
1627 return PTR_ERR(jpu->clk);
1628 }
1629
1630
1631 ret = v4l2_device_register(&pdev->dev, &jpu->v4l2_dev);
1632 if (ret) {
1633 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1634 return ret;
1635 }
1636
1637
1638 jpu->m2m_dev = v4l2_m2m_init(&jpu_m2m_ops);
1639 if (IS_ERR(jpu->m2m_dev)) {
1640 v4l2_err(&jpu->v4l2_dev, "Failed to init mem2mem device\n");
1641 ret = PTR_ERR(jpu->m2m_dev);
1642 goto device_register_rollback;
1643 }
1644
1645
1646 for (i = 0; i < JPU_MAX_QUALITY; i++)
1647 jpu_generate_hdr(i, (unsigned char *)jpeg_hdrs[i]);
1648
1649 strscpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name));
1650 jpu->vfd_encoder.fops = &jpu_fops;
1651 jpu->vfd_encoder.ioctl_ops = &jpu_ioctl_ops;
1652 jpu->vfd_encoder.minor = -1;
1653 jpu->vfd_encoder.release = video_device_release_empty;
1654 jpu->vfd_encoder.lock = &jpu->mutex;
1655 jpu->vfd_encoder.v4l2_dev = &jpu->v4l2_dev;
1656 jpu->vfd_encoder.vfl_dir = VFL_DIR_M2M;
1657 jpu->vfd_encoder.device_caps = V4L2_CAP_STREAMING |
1658 V4L2_CAP_VIDEO_M2M_MPLANE;
1659
1660 ret = video_register_device(&jpu->vfd_encoder, VFL_TYPE_VIDEO, -1);
1661 if (ret) {
1662 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");
1663 goto m2m_init_rollback;
1664 }
1665
1666 video_set_drvdata(&jpu->vfd_encoder, jpu);
1667
1668 strscpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name));
1669 jpu->vfd_decoder.fops = &jpu_fops;
1670 jpu->vfd_decoder.ioctl_ops = &jpu_ioctl_ops;
1671 jpu->vfd_decoder.minor = -1;
1672 jpu->vfd_decoder.release = video_device_release_empty;
1673 jpu->vfd_decoder.lock = &jpu->mutex;
1674 jpu->vfd_decoder.v4l2_dev = &jpu->v4l2_dev;
1675 jpu->vfd_decoder.vfl_dir = VFL_DIR_M2M;
1676 jpu->vfd_decoder.device_caps = V4L2_CAP_STREAMING |
1677 V4L2_CAP_VIDEO_M2M_MPLANE;
1678
1679 ret = video_register_device(&jpu->vfd_decoder, VFL_TYPE_VIDEO, -1);
1680 if (ret) {
1681 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");
1682 goto enc_vdev_register_rollback;
1683 }
1684
1685 video_set_drvdata(&jpu->vfd_decoder, jpu);
1686 platform_set_drvdata(pdev, jpu);
1687
1688 v4l2_info(&jpu->v4l2_dev, "encoder device registered as /dev/video%d\n",
1689 jpu->vfd_encoder.num);
1690 v4l2_info(&jpu->v4l2_dev, "decoder device registered as /dev/video%d\n",
1691 jpu->vfd_decoder.num);
1692
1693 return 0;
1694
1695enc_vdev_register_rollback:
1696 video_unregister_device(&jpu->vfd_encoder);
1697
1698m2m_init_rollback:
1699 v4l2_m2m_release(jpu->m2m_dev);
1700
1701device_register_rollback:
1702 v4l2_device_unregister(&jpu->v4l2_dev);
1703
1704 return ret;
1705}
1706
1707static int jpu_remove(struct platform_device *pdev)
1708{
1709 struct jpu *jpu = platform_get_drvdata(pdev);
1710
1711 video_unregister_device(&jpu->vfd_decoder);
1712 video_unregister_device(&jpu->vfd_encoder);
1713 v4l2_m2m_release(jpu->m2m_dev);
1714 v4l2_device_unregister(&jpu->v4l2_dev);
1715
1716 return 0;
1717}
1718
1719#ifdef CONFIG_PM_SLEEP
1720static int jpu_suspend(struct device *dev)
1721{
1722 struct jpu *jpu = dev_get_drvdata(dev);
1723
1724 if (jpu->ref_count == 0)
1725 return 0;
1726
1727 clk_disable_unprepare(jpu->clk);
1728
1729 return 0;
1730}
1731
1732static int jpu_resume(struct device *dev)
1733{
1734 struct jpu *jpu = dev_get_drvdata(dev);
1735
1736 if (jpu->ref_count == 0)
1737 return 0;
1738
1739 clk_prepare_enable(jpu->clk);
1740
1741 return 0;
1742}
1743#endif
1744
1745static const struct dev_pm_ops jpu_pm_ops = {
1746 SET_SYSTEM_SLEEP_PM_OPS(jpu_suspend, jpu_resume)
1747};
1748
1749static struct platform_driver jpu_driver = {
1750 .probe = jpu_probe,
1751 .remove = jpu_remove,
1752 .driver = {
1753 .of_match_table = jpu_dt_ids,
1754 .name = DRV_NAME,
1755 .pm = &jpu_pm_ops,
1756 },
1757};
1758
1759module_platform_driver(jpu_driver);
1760
1761MODULE_ALIAS("platform:" DRV_NAME);
1762MODULE_AUTHOR("Mikhail Ulianov <mikhail.ulyanov@cogentembedded.com>");
1763MODULE_DESCRIPTION("Renesas R-Car JPEG processing unit driver");
1764MODULE_LICENSE("GPL v2");
1765