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