]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/platform/coda/coda-jpeg.c
UBUNTU: Ubuntu-5.15.0-39.42
[mirror_ubuntu-jammy-kernel.git] / drivers / media / platform / coda / coda-jpeg.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
cb1d3a33
PZ
2/*
3 * Coda multi-standard codec IP - JPEG support functions
4 *
5 * Copyright (C) 2014 Philipp Zabel, Pengutronix
cb1d3a33
PZ
6 */
7
96f6f62c
PZ
8#include <asm/unaligned.h>
9#include <linux/irqreturn.h>
cb1d3a33 10#include <linux/kernel.h>
96f6f62c
PZ
11#include <linux/ktime.h>
12#include <linux/slab.h>
cb1d3a33 13#include <linux/swab.h>
96f6f62c
PZ
14#include <linux/videodev2.h>
15
16#include <media/v4l2-common.h>
17#include <media/v4l2-fh.h>
12310819 18#include <media/v4l2-jpeg.h>
96f6f62c
PZ
19#include <media/v4l2-mem2mem.h>
20#include <media/videobuf2-core.h>
21#include <media/videobuf2-dma-contig.h>
cb1d3a33
PZ
22
23#include "coda.h"
9a1a8f99 24#include "trace.h"
cb1d3a33 25
edc16cb1 26#define SOI_MARKER 0xffd8
12310819 27#define APP9_MARKER 0xffe9
96f6f62c
PZ
28#define DRI_MARKER 0xffdd
29#define DQT_MARKER 0xffdb
30#define DHT_MARKER 0xffc4
31#define SOF_MARKER 0xffc0
12310819 32#define SOS_MARKER 0xffda
edc16cb1
PZ
33#define EOI_MARKER 0xffd9
34
96f6f62c
PZ
35enum {
36 CODA9_JPEG_FORMAT_420,
37 CODA9_JPEG_FORMAT_422,
38 CODA9_JPEG_FORMAT_224,
39 CODA9_JPEG_FORMAT_444,
40 CODA9_JPEG_FORMAT_400,
41};
42
12310819
PZ
43struct coda_huff_tab {
44 u8 luma_dc[16 + 12];
45 u8 chroma_dc[16 + 12];
46 u8 luma_ac[16 + 162];
47 u8 chroma_ac[16 + 162];
48
49 /* DC Luma, DC Chroma, AC Luma, AC Chroma */
50 s16 min[4 * 16];
51 s16 max[4 * 16];
52 s8 ptr[4 * 16];
53};
54
96f6f62c
PZ
55#define CODA9_JPEG_ENC_HUFF_DATA_SIZE (256 + 256 + 16 + 16)
56
cb1d3a33
PZ
57/*
58 * Typical Huffman tables for 8-bit precision luminance and
59 * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3
60 */
61
ec4f021d
PZ
62static const unsigned char luma_dc[16 + 12] = {
63 /* bits */
cb1d3a33
PZ
64 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
65 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
ec4f021d 66 /* values */
cb1d3a33
PZ
67 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
68 0x08, 0x09, 0x0a, 0x0b,
69};
70
ec4f021d
PZ
71static const unsigned char chroma_dc[16 + 12] = {
72 /* bits */
cb1d3a33
PZ
73 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
74 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
ec4f021d 75 /* values */
cb1d3a33
PZ
76 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
77 0x08, 0x09, 0x0a, 0x0b,
78};
79
ec4f021d
PZ
80static const unsigned char luma_ac[16 + 162 + 2] = {
81 /* bits */
cb1d3a33
PZ
82 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
83 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
ec4f021d 84 /* values */
cb1d3a33
PZ
85 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
86 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
87 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
88 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
89 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
90 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
91 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
92 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
93 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
94 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
95 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
96 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
97 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
98 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
99 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
100 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
101 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
102 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
103 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
104 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
105 0xf9, 0xfa, /* padded to 32-bit */
106};
107
ec4f021d
PZ
108static const unsigned char chroma_ac[16 + 162 + 2] = {
109 /* bits */
cb1d3a33
PZ
110 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
111 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
ec4f021d 112 /* values */
cb1d3a33
PZ
113 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
114 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
115 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
116 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
117 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
118 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
119 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
120 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
121 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
122 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
123 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
124 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
125 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
126 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
127 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
128 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
129 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
130 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
131 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
132 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
133 0xf9, 0xfa, /* padded to 32-bit */
134};
135
136/*
137 * Quantization tables for luminance and chrominance components in
8b72c18d 138 * zig-zag scan order from the Freescale i.MX VPU libraries
cb1d3a33
PZ
139 */
140
141static unsigned char luma_q[64] = {
142 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05,
143 0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b,
144 0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a, 0x0a,
145 0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c,
146 0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c,
147 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
148 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
149 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
150};
151
152static unsigned char chroma_q[64] = {
153 0x07, 0x07, 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10,
154 0x10, 0x18, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14,
155 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c,
156 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c,
157 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c,
158 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
159 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
160 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
161};
162
96f6f62c
PZ
163static const unsigned char width_align[] = {
164 [CODA9_JPEG_FORMAT_420] = 16,
165 [CODA9_JPEG_FORMAT_422] = 16,
166 [CODA9_JPEG_FORMAT_224] = 8,
167 [CODA9_JPEG_FORMAT_444] = 8,
168 [CODA9_JPEG_FORMAT_400] = 8,
169};
170
171static const unsigned char height_align[] = {
172 [CODA9_JPEG_FORMAT_420] = 16,
173 [CODA9_JPEG_FORMAT_422] = 8,
174 [CODA9_JPEG_FORMAT_224] = 16,
175 [CODA9_JPEG_FORMAT_444] = 8,
176 [CODA9_JPEG_FORMAT_400] = 8,
177};
178
179static int coda9_jpeg_chroma_format(u32 pixfmt)
180{
181 switch (pixfmt) {
182 case V4L2_PIX_FMT_YUV420:
183 case V4L2_PIX_FMT_NV12:
184 return CODA9_JPEG_FORMAT_420;
185 case V4L2_PIX_FMT_YUV422P:
186 return CODA9_JPEG_FORMAT_422;
187 case V4L2_PIX_FMT_YUV444:
188 return CODA9_JPEG_FORMAT_444;
189 case V4L2_PIX_FMT_GREY:
190 return CODA9_JPEG_FORMAT_400;
191 }
192 return -EINVAL;
193}
194
cb1d3a33
PZ
195struct coda_memcpy_desc {
196 int offset;
197 const void *src;
198 size_t len;
199};
200
201static void coda_memcpy_parabuf(void *parabuf,
202 const struct coda_memcpy_desc *desc)
203{
204 u32 *dst = parabuf + desc->offset;
205 const u32 *src = desc->src;
206 int len = desc->len / 4;
207 int i;
208
209 for (i = 0; i < len; i += 2) {
210 dst[i + 1] = swab32(src[i]);
211 dst[i] = swab32(src[i + 1]);
212 }
213}
214
215int coda_jpeg_write_tables(struct coda_ctx *ctx)
216{
217 int i;
218 static const struct coda_memcpy_desc huff[8] = {
ec4f021d
PZ
219 { 0, luma_dc, sizeof(luma_dc) },
220 { 32, luma_ac, sizeof(luma_ac) },
221 { 216, chroma_dc, sizeof(chroma_dc) },
222 { 248, chroma_ac, sizeof(chroma_ac) },
cb1d3a33
PZ
223 };
224 struct coda_memcpy_desc qmat[3] = {
225 { 512, ctx->params.jpeg_qmat_tab[0], 64 },
226 { 576, ctx->params.jpeg_qmat_tab[1], 64 },
227 { 640, ctx->params.jpeg_qmat_tab[1], 64 },
228 };
229
230 /* Write huffman tables to parameter memory */
231 for (i = 0; i < ARRAY_SIZE(huff); i++)
232 coda_memcpy_parabuf(ctx->parabuf.vaddr, huff + i);
233
234 /* Write Q-matrix to parameter memory */
235 for (i = 0; i < ARRAY_SIZE(qmat); i++)
236 coda_memcpy_parabuf(ctx->parabuf.vaddr, qmat + i);
237
238 return 0;
239}
240
d4de047b 241bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
edc16cb1 242{
d4de047b
PZ
243 void *vaddr = vb2_plane_vaddr(vb, 0);
244 u16 soi, eoi;
245 int len, i;
246
247 soi = be16_to_cpup((__be16 *)vaddr);
248 if (soi != SOI_MARKER)
249 return false;
250
251 len = vb2_get_plane_payload(vb, 0);
252 vaddr += len - 2;
253 for (i = 0; i < 32; i++) {
254 eoi = be16_to_cpup((__be16 *)(vaddr - i));
255 if (eoi == EOI_MARKER) {
256 if (i > 0)
257 vb2_set_plane_payload(vb, 0, len - i);
258 return true;
259 }
260 }
edc16cb1 261
d4de047b 262 return false;
edc16cb1
PZ
263}
264
12310819
PZ
265static int coda9_jpeg_gen_dec_huff_tab(struct coda_ctx *ctx, int tab_num);
266
267int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb)
268{
269 struct coda_dev *dev = ctx->dev;
270 u8 *buf = vb2_plane_vaddr(vb, 0);
271 size_t len = vb2_get_plane_payload(vb, 0);
272 struct v4l2_jpeg_scan_header scan_header;
273 struct v4l2_jpeg_reference quantization_tables[4] = { };
274 struct v4l2_jpeg_reference huffman_tables[4] = { };
275 struct v4l2_jpeg_header header = {
276 .scan = &scan_header,
277 .quantization_tables = quantization_tables,
278 .huffman_tables = huffman_tables,
279 };
280 struct coda_q_data *q_data_src;
281 struct coda_huff_tab *huff_tab;
282 int i, j, ret;
283
284 ret = v4l2_jpeg_parse_header(buf, len, &header);
285 if (ret < 0) {
286 v4l2_err(&dev->v4l2_dev, "failed to parse header\n");
287 return ret;
288 }
289
290 ctx->params.jpeg_restart_interval = header.restart_interval;
291
292 /* check frame header */
293 if (header.frame.height > ctx->codec->max_h ||
294 header.frame.width > ctx->codec->max_w) {
295 v4l2_err(&dev->v4l2_dev, "invalid dimensions: %dx%d\n",
296 header.frame.width, header.frame.height);
297 return -EINVAL;
298 }
299
300 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
301 if (header.frame.height != q_data_src->height ||
302 header.frame.width != q_data_src->width) {
303 v4l2_err(&dev->v4l2_dev,
304 "dimensions don't match format: %dx%d\n",
305 header.frame.width, header.frame.height);
306 return -EINVAL;
307 }
308
309 if (header.frame.num_components != 3) {
310 v4l2_err(&dev->v4l2_dev,
311 "unsupported number of components: %d\n",
312 header.frame.num_components);
313 return -EINVAL;
314 }
315
316 /* install quantization tables */
317 if (quantization_tables[3].start) {
318 v4l2_err(&dev->v4l2_dev,
319 "only 3 quantization tables supported\n");
320 return -EINVAL;
321 }
322 for (i = 0; i < 3; i++) {
323 if (!quantization_tables[i].start)
324 continue;
325 if (quantization_tables[i].length != 64) {
326 v4l2_err(&dev->v4l2_dev,
327 "only 8-bit quantization tables supported\n");
328 continue;
329 }
20171723 330 if (!ctx->params.jpeg_qmat_tab[i]) {
12310819 331 ctx->params.jpeg_qmat_tab[i] = kmalloc(64, GFP_KERNEL);
20171723
CZ
332 if (!ctx->params.jpeg_qmat_tab[i])
333 return -ENOMEM;
334 }
12310819
PZ
335 memcpy(ctx->params.jpeg_qmat_tab[i],
336 quantization_tables[i].start, 64);
337 }
338
339 /* install Huffman tables */
340 for (i = 0; i < 4; i++) {
341 if (!huffman_tables[i].start) {
342 v4l2_err(&dev->v4l2_dev, "missing Huffman table\n");
343 return -EINVAL;
344 }
5c990fa0
AR
345 /* AC tables should be between 17 -> 178, DC between 17 -> 28 */
346 if (huffman_tables[i].length < 17 ||
347 huffman_tables[i].length > 178 ||
348 ((i & 2) == 0 && huffman_tables[i].length > 28)) {
12310819
PZ
349 v4l2_err(&dev->v4l2_dev,
350 "invalid Huffman table %d length: %zu\n",
351 i, huffman_tables[i].length);
352 return -EINVAL;
353 }
354 }
355 huff_tab = ctx->params.jpeg_huff_tab;
356 if (!huff_tab) {
357 huff_tab = kzalloc(sizeof(struct coda_huff_tab), GFP_KERNEL);
358 if (!huff_tab)
359 return -ENOMEM;
360 ctx->params.jpeg_huff_tab = huff_tab;
361 }
5c990fa0
AR
362
363 memset(huff_tab, 0, sizeof(*huff_tab));
364 memcpy(huff_tab->luma_dc, huffman_tables[0].start, huffman_tables[0].length);
365 memcpy(huff_tab->chroma_dc, huffman_tables[1].start, huffman_tables[1].length);
366 memcpy(huff_tab->luma_ac, huffman_tables[2].start, huffman_tables[2].length);
367 memcpy(huff_tab->chroma_ac, huffman_tables[3].start, huffman_tables[3].length);
12310819
PZ
368
369 /* check scan header */
370 for (i = 0; i < scan_header.num_components; i++) {
371 struct v4l2_jpeg_scan_component_spec *scan_component;
372
373 scan_component = &scan_header.component[i];
374 for (j = 0; j < header.frame.num_components; j++) {
375 if (header.frame.component[j].component_identifier ==
376 scan_component->component_selector)
377 break;
378 }
379 if (j == header.frame.num_components)
380 continue;
381
382 ctx->params.jpeg_huff_dc_index[j] =
383 scan_component->dc_entropy_coding_table_selector;
384 ctx->params.jpeg_huff_ac_index[j] =
385 scan_component->ac_entropy_coding_table_selector;
386 }
387
388 /* Generate Huffman table information */
389 for (i = 0; i < 4; i++)
390 coda9_jpeg_gen_dec_huff_tab(ctx, i);
391
392 /* start of entropy coded segment */
393 ctx->jpeg_ecs_offset = header.ecs_offset;
394
395 switch (header.frame.subsampling) {
396 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
397 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
398 ctx->params.jpeg_chroma_subsampling = header.frame.subsampling;
399 break;
400 default:
401 v4l2_err(&dev->v4l2_dev, "chroma subsampling not supported: %d",
402 header.frame.subsampling);
403 return -EINVAL;
404 }
405
406 return 0;
407}
408
409static inline void coda9_jpeg_write_huff_values(struct coda_dev *dev, u8 *bits,
410 int num_values)
411{
412 s8 *values = (s8 *)(bits + 16);
413 int huff_length, i;
414
415 for (huff_length = 0, i = 0; i < 16; i++)
416 huff_length += bits[i];
417 for (i = huff_length; i < num_values; i++)
418 values[i] = -1;
419 for (i = 0; i < num_values; i++)
420 coda_write(dev, (s32)values[i], CODA9_REG_JPEG_HUFF_DATA);
421}
422
423static int coda9_jpeg_dec_huff_setup(struct coda_ctx *ctx)
424{
425 struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab;
426 struct coda_dev *dev = ctx->dev;
427 s16 *huff_min = huff_tab->min;
428 s16 *huff_max = huff_tab->max;
429 s8 *huff_ptr = huff_tab->ptr;
430 int i;
431
432 /* MIN Tables */
433 coda_write(dev, 0x003, CODA9_REG_JPEG_HUFF_CTRL);
434 coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_ADDR);
435 for (i = 0; i < 4 * 16; i++)
436 coda_write(dev, (s32)huff_min[i], CODA9_REG_JPEG_HUFF_DATA);
437
438 /* MAX Tables */
439 coda_write(dev, 0x403, CODA9_REG_JPEG_HUFF_CTRL);
440 coda_write(dev, 0x440, CODA9_REG_JPEG_HUFF_ADDR);
441 for (i = 0; i < 4 * 16; i++)
442 coda_write(dev, (s32)huff_max[i], CODA9_REG_JPEG_HUFF_DATA);
443
444 /* PTR Tables */
445 coda_write(dev, 0x803, CODA9_REG_JPEG_HUFF_CTRL);
446 coda_write(dev, 0x880, CODA9_REG_JPEG_HUFF_ADDR);
447 for (i = 0; i < 4 * 16; i++)
448 coda_write(dev, (s32)huff_ptr[i], CODA9_REG_JPEG_HUFF_DATA);
449
450 /* VAL Tables: DC Luma, DC Chroma, AC Luma, AC Chroma */
451 coda_write(dev, 0xc03, CODA9_REG_JPEG_HUFF_CTRL);
452 coda9_jpeg_write_huff_values(dev, huff_tab->luma_dc, 12);
453 coda9_jpeg_write_huff_values(dev, huff_tab->chroma_dc, 12);
454 coda9_jpeg_write_huff_values(dev, huff_tab->luma_ac, 162);
455 coda9_jpeg_write_huff_values(dev, huff_tab->chroma_ac, 162);
456 coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_CTRL);
457 return 0;
458}
459
460static inline void coda9_jpeg_write_qmat_tab(struct coda_dev *dev,
461 u8 *qmat, int index)
462{
463 int i;
464
465 coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
466 for (i = 0; i < 64; i++)
467 coda_write(dev, qmat[i], CODA9_REG_JPEG_QMAT_DATA);
468 coda_write(dev, 0, CODA9_REG_JPEG_QMAT_CTRL);
469}
470
471static void coda9_jpeg_qmat_setup(struct coda_ctx *ctx)
472{
473 struct coda_dev *dev = ctx->dev;
474 int *qmat_index = ctx->params.jpeg_qmat_index;
475 u8 **qmat_tab = ctx->params.jpeg_qmat_tab;
476
477 coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[0]], 0x00);
478 coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[1]], 0x40);
479 coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[2]], 0x80);
480}
481
482static void coda9_jpeg_dec_bbc_gbu_setup(struct coda_ctx *ctx,
483 struct vb2_buffer *buf, u32 ecs_offset)
484{
485 struct coda_dev *dev = ctx->dev;
486 int page_ptr, word_ptr, bit_ptr;
487 u32 bbc_base_addr, end_addr;
488 int bbc_cur_pos;
489 int ret, val;
490
491 bbc_base_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
492 end_addr = bbc_base_addr + vb2_get_plane_payload(buf, 0);
493
494 page_ptr = ecs_offset / 256;
495 word_ptr = (ecs_offset % 256) / 4;
496 if (page_ptr & 1)
497 word_ptr += 64;
498 bit_ptr = (ecs_offset % 4) * 8;
499 if (word_ptr & 1)
500 bit_ptr += 32;
501 word_ptr &= ~0x1;
502
503 coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_WR_PTR);
504 coda_write(dev, bbc_base_addr, CODA9_REG_JPEG_BBC_BAS_ADDR);
505
506 /* Leave 3 256-byte page margin to avoid a BBC interrupt */
507 coda_write(dev, end_addr + 256 * 3 + 256, CODA9_REG_JPEG_BBC_END_ADDR);
508 val = DIV_ROUND_UP(vb2_plane_size(buf, 0), 256) + 3;
509 coda_write(dev, BIT(31) | val, CODA9_REG_JPEG_BBC_STRM_CTRL);
510
511 bbc_cur_pos = page_ptr;
512 coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
513 coda_write(dev, bbc_base_addr + (bbc_cur_pos << 8),
514 CODA9_REG_JPEG_BBC_EXT_ADDR);
515 coda_write(dev, (bbc_cur_pos & 1) << 6, CODA9_REG_JPEG_BBC_INT_ADDR);
516 coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
517 coda_write(dev, 0, CODA9_REG_JPEG_BBC_COMMAND);
518 do {
519 ret = coda_read(dev, CODA9_REG_JPEG_BBC_BUSY);
520 } while (ret == 1);
521
522 bbc_cur_pos++;
523 coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
524 coda_write(dev, bbc_base_addr + (bbc_cur_pos << 8),
525 CODA9_REG_JPEG_BBC_EXT_ADDR);
526 coda_write(dev, (bbc_cur_pos & 1) << 6, CODA9_REG_JPEG_BBC_INT_ADDR);
527 coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
528 coda_write(dev, 0, CODA9_REG_JPEG_BBC_COMMAND);
529 do {
530 ret = coda_read(dev, CODA9_REG_JPEG_BBC_BUSY);
531 } while (ret == 1);
532
533 bbc_cur_pos++;
534 coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
535 coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
536
537 coda_write(dev, 0, CODA9_REG_JPEG_GBU_TT_CNT);
538 coda_write(dev, word_ptr, CODA9_REG_JPEG_GBU_WD_PTR);
539 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
540 coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
541 if (page_ptr & 1) {
542 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBIR);
543 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBHR);
544 } else {
545 coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
546 coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
547 }
548 coda_write(dev, 4, CODA9_REG_JPEG_GBU_CTRL);
549 coda_write(dev, bit_ptr, CODA9_REG_JPEG_GBU_FF_RPTR);
550 coda_write(dev, 3, CODA9_REG_JPEG_GBU_CTRL);
551}
552
96f6f62c
PZ
553static const int bus_req_num[] = {
554 [CODA9_JPEG_FORMAT_420] = 2,
555 [CODA9_JPEG_FORMAT_422] = 3,
556 [CODA9_JPEG_FORMAT_224] = 3,
557 [CODA9_JPEG_FORMAT_444] = 4,
558 [CODA9_JPEG_FORMAT_400] = 4,
559};
560
561#define MCU_INFO(mcu_block_num, comp_num, comp0_info, comp1_info, comp2_info) \
562 (((mcu_block_num) << CODA9_JPEG_MCU_BLOCK_NUM_OFFSET) | \
563 ((comp_num) << CODA9_JPEG_COMP_NUM_OFFSET) | \
564 ((comp0_info) << CODA9_JPEG_COMP0_INFO_OFFSET) | \
565 ((comp1_info) << CODA9_JPEG_COMP1_INFO_OFFSET) | \
566 ((comp2_info) << CODA9_JPEG_COMP2_INFO_OFFSET))
567
568static const u32 mcu_info[] = {
569 [CODA9_JPEG_FORMAT_420] = MCU_INFO(6, 3, 10, 5, 5),
570 [CODA9_JPEG_FORMAT_422] = MCU_INFO(4, 3, 9, 5, 5),
571 [CODA9_JPEG_FORMAT_224] = MCU_INFO(4, 3, 6, 5, 5),
572 [CODA9_JPEG_FORMAT_444] = MCU_INFO(3, 3, 5, 5, 5),
573 [CODA9_JPEG_FORMAT_400] = MCU_INFO(1, 1, 5, 0, 0),
574};
575
576/*
577 * Convert Huffman table specifcations to tables of codes and code lengths.
578 * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
579 *
580 * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
581 */
582static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num,
583 int *ehufsi, int *ehufco)
584{
585 int i, j, k, lastk, si, code, maxsymbol;
586 const u8 *bits, *huffval;
587 struct {
588 int size[256];
589 int code[256];
590 } *huff;
591 static const unsigned char *huff_tabs[4] = {
592 luma_dc, luma_ac, chroma_dc, chroma_ac,
593 };
594 int ret = -EINVAL;
595
596 huff = kzalloc(sizeof(*huff), GFP_KERNEL);
597 if (!huff)
598 return -ENOMEM;
599
600 bits = huff_tabs[tab_num];
601 huffval = huff_tabs[tab_num] + 16;
602
603 maxsymbol = tab_num & 1 ? 256 : 16;
604
605 /* Figure C.1 - Generation of table of Huffman code sizes */
606 k = 0;
607 for (i = 1; i <= 16; i++) {
608 j = bits[i - 1];
609 if (k + j > maxsymbol)
610 goto out;
611 while (j--)
612 huff->size[k++] = i;
613 }
614 lastk = k;
615
616 /* Figure C.2 - Generation of table of Huffman codes */
617 k = 0;
618 code = 0;
619 si = huff->size[0];
620 while (k < lastk) {
621 while (huff->size[k] == si) {
622 huff->code[k++] = code;
623 code++;
624 }
625 if (code >= (1 << si))
626 goto out;
627 code <<= 1;
628 si++;
629 }
630
631 /* Figure C.3 - Ordering procedure for encoding procedure code tables */
632 for (k = 0; k < lastk; k++) {
633 i = huffval[k];
634 if (i >= maxsymbol || ehufsi[i])
635 goto out;
636 ehufco[i] = huff->code[k];
637 ehufsi[i] = huff->size[k];
638 }
639
640 ret = 0;
641out:
642 kfree(huff);
643 return ret;
644}
645
646#define DC_TABLE_INDEX0 0
647#define AC_TABLE_INDEX0 1
648#define DC_TABLE_INDEX1 2
649#define AC_TABLE_INDEX1 3
650
12310819
PZ
651static u8 *coda9_jpeg_get_huff_bits(struct coda_ctx *ctx, int tab_num)
652{
653 struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab;
654
655 if (!huff_tab)
656 return NULL;
657
658 switch (tab_num) {
659 case DC_TABLE_INDEX0: return huff_tab->luma_dc;
660 case AC_TABLE_INDEX0: return huff_tab->luma_ac;
661 case DC_TABLE_INDEX1: return huff_tab->chroma_dc;
662 case AC_TABLE_INDEX1: return huff_tab->chroma_ac;
663 }
664
665 return NULL;
666}
667
668static int coda9_jpeg_gen_dec_huff_tab(struct coda_ctx *ctx, int tab_num)
669{
670 int ptr_cnt = 0, huff_code = 0, zero_flag = 0, data_flag = 0;
671 u8 *huff_bits;
672 s16 *huff_max;
673 s16 *huff_min;
674 s8 *huff_ptr;
675 int ofs;
676 int i;
677
678 huff_bits = coda9_jpeg_get_huff_bits(ctx, tab_num);
679 if (!huff_bits)
680 return -EINVAL;
681
682 /* DC/AC Luma, DC/AC Chroma -> DC Luma/Chroma, AC Luma/Chroma */
683 ofs = ((tab_num & 1) << 1) | ((tab_num >> 1) & 1);
684 ofs *= 16;
685
686 huff_ptr = ctx->params.jpeg_huff_tab->ptr + ofs;
687 huff_max = ctx->params.jpeg_huff_tab->max + ofs;
688 huff_min = ctx->params.jpeg_huff_tab->min + ofs;
689
690 for (i = 0; i < 16; i++) {
691 if (huff_bits[i]) {
692 huff_ptr[i] = ptr_cnt;
693 ptr_cnt += huff_bits[i];
694 huff_min[i] = huff_code;
695 huff_max[i] = huff_code + (huff_bits[i] - 1);
696 data_flag = 1;
697 zero_flag = 0;
698 } else {
699 huff_ptr[i] = -1;
700 huff_min[i] = -1;
701 huff_max[i] = -1;
702 zero_flag = 1;
703 }
704
705 if (data_flag == 1) {
706 if (zero_flag == 1)
707 huff_code <<= 1;
708 else
709 huff_code = (huff_max[i] + 1) << 1;
710 }
711 }
712
713 return 0;
714}
715
96f6f62c
PZ
716static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx)
717{
718 struct {
719 int size[4][256];
720 int code[4][256];
721 } *huff;
722 u32 *huff_data;
723 int i, j;
724 int ret;
725
726 huff = kzalloc(sizeof(*huff), GFP_KERNEL);
727 if (!huff)
728 return -ENOMEM;
729
730 /* Generate all four (luma/chroma DC/AC) code/size lookup tables */
731 for (i = 0; i < 4; i++) {
732 ret = coda9_jpeg_gen_enc_huff_tab(ctx, i, huff->size[i],
733 huff->code[i]);
734 if (ret)
735 goto out;
736 }
737
738 if (!ctx->params.jpeg_huff_data) {
739 ctx->params.jpeg_huff_data =
740 kzalloc(sizeof(u32) * CODA9_JPEG_ENC_HUFF_DATA_SIZE,
741 GFP_KERNEL);
742 if (!ctx->params.jpeg_huff_data) {
743 ret = -ENOMEM;
744 goto out;
745 }
746 }
747 huff_data = ctx->params.jpeg_huff_data;
748
749 for (j = 0; j < 4; j++) {
750 /* Store Huffman lookup tables in AC0, AC1, DC0, DC1 order */
751 int t = (j == 0) ? AC_TABLE_INDEX0 :
752 (j == 1) ? AC_TABLE_INDEX1 :
753 (j == 2) ? DC_TABLE_INDEX0 :
754 DC_TABLE_INDEX1;
755 /* DC tables only have 16 entries */
756 int len = (j < 2) ? 256 : 16;
757
758 for (i = 0; i < len; i++) {
759 if (huff->size[t][i] == 0 && huff->code[t][i] == 0)
760 *(huff_data++) = 0;
761 else
762 *(huff_data++) =
763 ((huff->size[t][i] - 1) << 16) |
764 huff->code[t][i];
765 }
766 }
767
768 ret = 0;
769out:
770 kfree(huff);
771 return ret;
772}
773
774static void coda9_jpeg_write_huff_tab(struct coda_ctx *ctx)
775{
776 struct coda_dev *dev = ctx->dev;
777 u32 *huff_data = ctx->params.jpeg_huff_data;
778 int i;
779
780 /* Write Huffman size/code lookup tables in AC0, AC1, DC0, DC1 order */
781 coda_write(dev, 0x3, CODA9_REG_JPEG_HUFF_CTRL);
782 for (i = 0; i < CODA9_JPEG_ENC_HUFF_DATA_SIZE; i++)
783 coda_write(dev, *(huff_data++), CODA9_REG_JPEG_HUFF_DATA);
784 coda_write(dev, 0x0, CODA9_REG_JPEG_HUFF_CTRL);
785}
786
787static inline void coda9_jpeg_write_qmat_quotients(struct coda_dev *dev,
788 u8 *qmat, int index)
789{
790 int i;
791
792 coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
793 for (i = 0; i < 64; i++)
794 coda_write(dev, 0x80000 / qmat[i], CODA9_REG_JPEG_QMAT_DATA);
795 coda_write(dev, index, CODA9_REG_JPEG_QMAT_CTRL);
796}
797
798static void coda9_jpeg_load_qmat_tab(struct coda_ctx *ctx)
799{
800 struct coda_dev *dev = ctx->dev;
801 u8 *luma_tab;
802 u8 *chroma_tab;
803
804 luma_tab = ctx->params.jpeg_qmat_tab[0];
805 if (!luma_tab)
806 luma_tab = luma_q;
807
808 chroma_tab = ctx->params.jpeg_qmat_tab[1];
809 if (!chroma_tab)
810 chroma_tab = chroma_q;
811
812 coda9_jpeg_write_qmat_quotients(dev, luma_tab, 0x00);
813 coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x40);
814 coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x80);
815}
816
817struct coda_jpeg_stream {
818 u8 *curr;
819 u8 *end;
820};
821
822static inline int coda_jpeg_put_byte(u8 byte, struct coda_jpeg_stream *stream)
823{
824 if (stream->curr >= stream->end)
825 return -EINVAL;
826
827 *stream->curr++ = byte;
828
829 return 0;
830}
831
832static inline int coda_jpeg_put_word(u16 word, struct coda_jpeg_stream *stream)
833{
834 if (stream->curr + sizeof(__be16) > stream->end)
835 return -EINVAL;
836
837 put_unaligned_be16(word, stream->curr);
838 stream->curr += sizeof(__be16);
839
840 return 0;
841}
842
843static int coda_jpeg_put_table(u16 marker, u8 index, const u8 *table,
844 size_t len, struct coda_jpeg_stream *stream)
845{
846 int i, ret;
847
848 ret = coda_jpeg_put_word(marker, stream);
849 if (ret < 0)
850 return ret;
851 ret = coda_jpeg_put_word(3 + len, stream);
852 if (ret < 0)
853 return ret;
854 ret = coda_jpeg_put_byte(index, stream);
855 for (i = 0; i < len && ret == 0; i++)
856 ret = coda_jpeg_put_byte(table[i], stream);
857
858 return ret;
859}
860
861static int coda_jpeg_define_quantization_table(struct coda_ctx *ctx, u8 index,
862 struct coda_jpeg_stream *stream)
863{
864 return coda_jpeg_put_table(DQT_MARKER, index,
865 ctx->params.jpeg_qmat_tab[index], 64,
866 stream);
867}
868
869static int coda_jpeg_define_huffman_table(u8 index, const u8 *table, size_t len,
870 struct coda_jpeg_stream *stream)
871{
872 return coda_jpeg_put_table(DHT_MARKER, index, table, len, stream);
873}
874
875static int coda9_jpeg_encode_header(struct coda_ctx *ctx, int len, u8 *buf)
876{
877 struct coda_jpeg_stream stream = { buf, buf + len };
878 struct coda_q_data *q_data_src;
879 int chroma_format, comp_num;
880 int i, ret, pad;
881
882 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
883 chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
884 if (chroma_format < 0)
885 return 0;
886
887 /* Start Of Image */
888 ret = coda_jpeg_put_word(SOI_MARKER, &stream);
889 if (ret < 0)
890 return ret;
891
892 /* Define Restart Interval */
893 if (ctx->params.jpeg_restart_interval) {
894 ret = coda_jpeg_put_word(DRI_MARKER, &stream);
895 if (ret < 0)
896 return ret;
897 ret = coda_jpeg_put_word(4, &stream);
898 if (ret < 0)
899 return ret;
900 ret = coda_jpeg_put_word(ctx->params.jpeg_restart_interval,
901 &stream);
902 if (ret < 0)
903 return ret;
904 }
905
906 /* Define Quantization Tables */
907 ret = coda_jpeg_define_quantization_table(ctx, 0x00, &stream);
908 if (ret < 0)
909 return ret;
910 if (chroma_format != CODA9_JPEG_FORMAT_400) {
911 ret = coda_jpeg_define_quantization_table(ctx, 0x01, &stream);
912 if (ret < 0)
913 return ret;
914 }
915
916 /* Define Huffman Tables */
917 ret = coda_jpeg_define_huffman_table(0x00, luma_dc, 16 + 12, &stream);
918 if (ret < 0)
919 return ret;
920 ret = coda_jpeg_define_huffman_table(0x10, luma_ac, 16 + 162, &stream);
921 if (ret < 0)
922 return ret;
923 if (chroma_format != CODA9_JPEG_FORMAT_400) {
924 ret = coda_jpeg_define_huffman_table(0x01, chroma_dc, 16 + 12,
925 &stream);
926 if (ret < 0)
927 return ret;
928 ret = coda_jpeg_define_huffman_table(0x11, chroma_ac, 16 + 162,
929 &stream);
930 if (ret < 0)
931 return ret;
932 }
933
934 /* Start Of Frame */
935 ret = coda_jpeg_put_word(SOF_MARKER, &stream);
936 if (ret < 0)
937 return ret;
938 comp_num = (chroma_format == CODA9_JPEG_FORMAT_400) ? 1 : 3;
939 ret = coda_jpeg_put_word(8 + comp_num * 3, &stream);
940 if (ret < 0)
941 return ret;
942 ret = coda_jpeg_put_byte(0x08, &stream);
943 if (ret < 0)
944 return ret;
945 ret = coda_jpeg_put_word(q_data_src->height, &stream);
946 if (ret < 0)
947 return ret;
948 ret = coda_jpeg_put_word(q_data_src->width, &stream);
949 if (ret < 0)
950 return ret;
951 ret = coda_jpeg_put_byte(comp_num, &stream);
952 if (ret < 0)
953 return ret;
954 for (i = 0; i < comp_num; i++) {
955 static unsigned char subsampling[5][3] = {
956 [CODA9_JPEG_FORMAT_420] = { 0x22, 0x11, 0x11 },
957 [CODA9_JPEG_FORMAT_422] = { 0x21, 0x11, 0x11 },
958 [CODA9_JPEG_FORMAT_224] = { 0x12, 0x11, 0x11 },
959 [CODA9_JPEG_FORMAT_444] = { 0x11, 0x11, 0x11 },
960 [CODA9_JPEG_FORMAT_400] = { 0x11 },
961 };
962
963 /* Component identifier, matches SOS */
964 ret = coda_jpeg_put_byte(i + 1, &stream);
965 if (ret < 0)
966 return ret;
967 ret = coda_jpeg_put_byte(subsampling[chroma_format][i],
968 &stream);
969 if (ret < 0)
970 return ret;
971 /* Chroma table index */
972 ret = coda_jpeg_put_byte((i == 0) ? 0 : 1, &stream);
973 if (ret < 0)
974 return ret;
975 }
976
977 /* Pad to multiple of 8 bytes */
978 pad = (stream.curr - buf) % 8;
979 if (pad) {
980 pad = 8 - pad;
981 while (pad--) {
982 ret = coda_jpeg_put_byte(0x00, &stream);
983 if (ret < 0)
984 return ret;
985 }
986 }
987
988 return stream.curr - buf;
989}
990
cb1d3a33
PZ
991/*
992 * Scale quantization table using nonlinear scaling factor
993 * u8 qtab[64], scale [50,190]
994 */
995static void coda_scale_quant_table(u8 *q_tab, int scale)
996{
997 unsigned int temp;
998 int i;
999
1000 for (i = 0; i < 64; i++) {
1001 temp = DIV_ROUND_CLOSEST((unsigned int)q_tab[i] * scale, 100);
1002 if (temp <= 0)
1003 temp = 1;
1004 if (temp > 255)
1005 temp = 255;
1006 q_tab[i] = (unsigned char)temp;
1007 }
1008}
1009
1010void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality)
1011{
1012 unsigned int scale;
1013
1014 ctx->params.jpeg_quality = quality;
1015
1016 /* Clip quality setting to [5,100] interval */
1017 if (quality > 100)
1018 quality = 100;
1019 if (quality < 5)
1020 quality = 5;
1021
1022 /*
1023 * Non-linear scaling factor:
1024 * [5,50] -> [1000..100], [51,100] -> [98..0]
1025 */
1026 if (quality < 50)
1027 scale = 5000 / quality;
1028 else
1029 scale = 200 - 2 * quality;
1030
1031 if (ctx->params.jpeg_qmat_tab[0]) {
1032 memcpy(ctx->params.jpeg_qmat_tab[0], luma_q, 64);
1033 coda_scale_quant_table(ctx->params.jpeg_qmat_tab[0], scale);
1034 }
1035 if (ctx->params.jpeg_qmat_tab[1]) {
1036 memcpy(ctx->params.jpeg_qmat_tab[1], chroma_q, 64);
1037 coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale);
1038 }
1039}
96f6f62c
PZ
1040
1041/*
1042 * Encoder context operations
1043 */
1044
1045static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
1046{
1047 struct coda_dev *dev = ctx->dev;
1048 int ret;
1049
1050 ret = coda9_jpeg_load_huff_tab(ctx);
1051 if (ret < 0) {
1052 v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
1053 return ret;
1054 }
1055 if (!ctx->params.jpeg_qmat_tab[0])
1056 ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
1057 if (!ctx->params.jpeg_qmat_tab[1])
1058 ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
1059 coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
1060
1061 return 0;
1062}
1063
1064static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
1065{
1066 struct coda_q_data *q_data_src;
1067 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1068 struct coda_dev *dev = ctx->dev;
1069 u32 start_addr, end_addr;
1070 u16 aligned_width, aligned_height;
1071 bool chroma_interleave;
1072 int chroma_format;
1073 int header_len;
1074 int ret;
1075 ktime_t timeout;
1076
1077 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1078 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1079 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1080
1081 if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
1082 vb2_set_plane_payload(&src_buf->vb2_buf, 0,
1083 vb2_plane_size(&src_buf->vb2_buf, 0));
1084
1085 src_buf->sequence = ctx->osequence;
1086 dst_buf->sequence = ctx->osequence;
1087 ctx->osequence++;
1088
1089 src_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1090 src_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
1091
1092 coda_set_gdi_regs(ctx);
1093
1094 start_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1095 end_addr = start_addr + vb2_plane_size(&dst_buf->vb2_buf, 0);
1096
1097 chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
1098 if (chroma_format < 0)
1099 return chroma_format;
1100
1101 /* Round image dimensions to multiple of MCU size */
1102 aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
1103 aligned_height = round_up(q_data_src->height,
1104 height_align[chroma_format]);
1105 if (aligned_width != q_data_src->bytesperline) {
1106 v4l2_err(&dev->v4l2_dev, "wrong stride: %d instead of %d\n",
1107 aligned_width, q_data_src->bytesperline);
1108 }
1109
1110 header_len =
1111 coda9_jpeg_encode_header(ctx,
1112 vb2_plane_size(&dst_buf->vb2_buf, 0),
1113 vb2_plane_vaddr(&dst_buf->vb2_buf, 0));
1114 if (header_len < 0)
1115 return header_len;
1116
1117 coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_BAS_ADDR);
1118 coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_END_ADDR);
1119 coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_WR_PTR);
1120 coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_RD_PTR);
1121 coda_write(dev, 0, CODA9_REG_JPEG_BBC_CUR_POS);
1122 /* 64 words per 256-byte page */
1123 coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
1124 coda_write(dev, start_addr, CODA9_REG_JPEG_BBC_EXT_ADDR);
1125 coda_write(dev, 0, CODA9_REG_JPEG_BBC_INT_ADDR);
1126
1127 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
1128 coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
1129 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
bb6bd058
PZ
1130 coda_write(dev, BIT(31) | ((end_addr - start_addr - header_len) / 256),
1131 CODA9_REG_JPEG_BBC_STRM_CTRL);
96f6f62c
PZ
1132 coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
1133 coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
1134 coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
1135 coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
1136 coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
1137
1138 chroma_interleave = (q_data_src->fourcc == V4L2_PIX_FMT_NV12);
1139 coda_write(dev, CODA9_JPEG_PIC_CTRL_TC_DIRECTION |
1140 CODA9_JPEG_PIC_CTRL_ENCODER_EN, CODA9_REG_JPEG_PIC_CTRL);
1141 coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
1142 coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
1143 coda_write(dev, ctx->params.jpeg_restart_interval,
1144 CODA9_REG_JPEG_RST_INTVAL);
1145 coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
1146
1147 coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
1148
1149 coda9_jpeg_write_huff_tab(ctx);
1150 coda9_jpeg_load_qmat_tab(ctx);
1151
1152 if (ctx->params.rot_mode & CODA_ROT_90) {
1153 aligned_width = aligned_height;
1154 aligned_height = q_data_src->bytesperline;
1155 if (chroma_format == CODA9_JPEG_FORMAT_422)
1156 chroma_format = CODA9_JPEG_FORMAT_224;
1157 else if (chroma_format == CODA9_JPEG_FORMAT_224)
1158 chroma_format = CODA9_JPEG_FORMAT_422;
1159 }
1160 /* These need to be multiples of MCU size */
1161 coda_write(dev, aligned_width << 16 | aligned_height,
1162 CODA9_REG_JPEG_PIC_SIZE);
1163 coda_write(dev, ctx->params.rot_mode ?
1164 (CODA_ROT_MIR_ENABLE | ctx->params.rot_mode) : 0,
1165 CODA9_REG_JPEG_ROT_INFO);
1166
1167 coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
1168
1169 coda_write(dev, 1, CODA9_GDI_CONTROL);
1170 timeout = ktime_add_us(ktime_get(), 100000);
1171 do {
1172 ret = coda_read(dev, CODA9_GDI_STATUS);
1173 if (ktime_compare(ktime_get(), timeout) > 0) {
1174 v4l2_err(&dev->v4l2_dev, "timeout waiting for GDI\n");
1175 return -ETIMEDOUT;
1176 }
1177 } while (!ret);
1178
1179 coda_write(dev, (chroma_format << 17) | (chroma_interleave << 16) |
1180 q_data_src->bytesperline, CODA9_GDI_INFO_CONTROL);
1181 /* The content of this register seems to be irrelevant: */
1182 coda_write(dev, aligned_width << 16 | aligned_height,
1183 CODA9_GDI_INFO_PIC_SIZE);
1184
1185 coda_write_base(ctx, q_data_src, src_buf, CODA9_GDI_INFO_BASE_Y);
1186
1187 coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
1188 coda_write(dev, 0, CODA9_GDI_CONTROL);
1189 coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
1190
1191 coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
1192 coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
1193
1194 trace_coda_jpeg_run(ctx, src_buf);
1195
1196 coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
1197
1198 return 0;
1199}
1200
1201static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
1202{
1203 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1204 struct coda_dev *dev = ctx->dev;
1205 u32 wr_ptr, start_ptr;
1206 u32 err_mb;
1207
1208 if (ctx->aborting) {
1209 coda_write(ctx->dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
1210 return;
1211 }
1212
1213 /*
1214 * Lock to make sure that an encoder stop command running in parallel
1215 * will either already have marked src_buf as last, or it will wake up
1216 * the capture queue after the buffers are returned.
1217 */
1218 mutex_lock(&ctx->wakeup_mutex);
1219 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1220 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1221
1222 trace_coda_jpeg_done(ctx, dst_buf);
1223
1224 /*
1225 * Set plane payload to the number of bytes written out
1226 * by the JPEG processing unit
1227 */
1228 start_ptr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1229 wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
1230 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr);
1231
1232 err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
1233 if (err_mb)
1234 coda_dbg(1, ctx, "ERRMB: 0x%x\n", err_mb);
1235
1236 coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
1237
1238 dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
1239 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1240 dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
1241
1242 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
1243
1244 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1245 coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
1246 VB2_BUF_STATE_DONE);
1247 mutex_unlock(&ctx->wakeup_mutex);
1248
1249 coda_dbg(1, ctx, "job finished: encoded frame (%u)%s\n",
1250 dst_buf->sequence,
1251 (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
12310819
PZ
1252
1253 /*
1254 * Reset JPEG processing unit after each encode run to work
1255 * around hangups when switching context between encoder and
1256 * decoder.
1257 */
1258 coda_hw_reset(ctx);
96f6f62c
PZ
1259}
1260
bb6bd058
PZ
1261static void coda9_jpeg_encode_timeout(struct coda_ctx *ctx)
1262{
1263 struct coda_dev *dev = ctx->dev;
1264 u32 end_addr, wr_ptr;
1265
1266 /* Handle missing BBC overflow interrupt via timeout */
1267 end_addr = coda_read(dev, CODA9_REG_JPEG_BBC_END_ADDR);
1268 wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
1269 if (wr_ptr >= end_addr - 256) {
1270 v4l2_err(&dev->v4l2_dev, "JPEG too large for capture buffer\n");
1271 coda9_jpeg_finish_encode(ctx);
1272 return;
1273 }
1274
1275 coda_hw_reset(ctx);
1276}
1277
96f6f62c
PZ
1278static void coda9_jpeg_release(struct coda_ctx *ctx)
1279{
1280 int i;
1281
1282 if (ctx->params.jpeg_qmat_tab[0] == luma_q)
1283 ctx->params.jpeg_qmat_tab[0] = NULL;
1284 if (ctx->params.jpeg_qmat_tab[1] == chroma_q)
1285 ctx->params.jpeg_qmat_tab[1] = NULL;
1286 for (i = 0; i < 3; i++)
1287 kfree(ctx->params.jpeg_qmat_tab[i]);
1288 kfree(ctx->params.jpeg_huff_data);
12310819 1289 kfree(ctx->params.jpeg_huff_tab);
96f6f62c
PZ
1290}
1291
1292const struct coda_context_ops coda9_jpeg_encode_ops = {
1293 .queue_init = coda_encoder_queue_init,
1294 .start_streaming = coda9_jpeg_start_encoding,
1295 .prepare_run = coda9_jpeg_prepare_encode,
1296 .finish_run = coda9_jpeg_finish_encode,
bb6bd058 1297 .run_timeout = coda9_jpeg_encode_timeout,
96f6f62c
PZ
1298 .release = coda9_jpeg_release,
1299};
1300
12310819
PZ
1301/*
1302 * Decoder context operations
1303 */
1304
1305static int coda9_jpeg_start_decoding(struct coda_ctx *ctx)
1306{
1307 ctx->params.jpeg_qmat_index[0] = 0;
1308 ctx->params.jpeg_qmat_index[1] = 1;
1309 ctx->params.jpeg_qmat_index[2] = 1;
1310 ctx->params.jpeg_qmat_tab[0] = luma_q;
1311 ctx->params.jpeg_qmat_tab[1] = chroma_q;
1312 /* nothing more to do here */
1313
1314 /* TODO: we could already scan the first header to get the chroma
1315 * format.
1316 */
1317
1318 return 0;
1319}
1320
1321static int coda9_jpeg_prepare_decode(struct coda_ctx *ctx)
1322{
1323 struct coda_dev *dev = ctx->dev;
1324 int aligned_width, aligned_height;
1325 int chroma_format;
1326 int ret;
1327 u32 val, dst_fourcc;
1328 struct coda_q_data *q_data_src, *q_data_dst;
1329 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1330 int chroma_interleave;
1331
1332 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1333 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1334 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1335 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1336 dst_fourcc = q_data_dst->fourcc;
1337
1338 if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
1339 vb2_set_plane_payload(&src_buf->vb2_buf, 0,
1340 vb2_plane_size(&src_buf->vb2_buf, 0));
1341
1342 chroma_format = coda9_jpeg_chroma_format(q_data_dst->fourcc);
1343 if (chroma_format < 0) {
1344 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
1345 return chroma_format;
1346 }
1347
1348 ret = coda_jpeg_decode_header(ctx, &src_buf->vb2_buf);
1349 if (ret < 0) {
1350 v4l2_err(&dev->v4l2_dev, "failed to decode JPEG header: %d\n",
1351 ret);
1352
1353 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1354 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1355 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1356 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1357
1358 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
1359 return ret;
1360 }
1361
1362 /* Round image dimensions to multiple of MCU size */
1363 aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
1364 aligned_height = round_up(q_data_src->height, height_align[chroma_format]);
1365 if (aligned_width != q_data_dst->bytesperline) {
1366 v4l2_err(&dev->v4l2_dev, "stride mismatch: %d != %d\n",
1367 aligned_width, q_data_dst->bytesperline);
1368 }
1369
1370 coda_set_gdi_regs(ctx);
1371
1372 val = ctx->params.jpeg_huff_ac_index[0] << 12 |
1373 ctx->params.jpeg_huff_ac_index[1] << 11 |
1374 ctx->params.jpeg_huff_ac_index[2] << 10 |
1375 ctx->params.jpeg_huff_dc_index[0] << 9 |
1376 ctx->params.jpeg_huff_dc_index[1] << 8 |
1377 ctx->params.jpeg_huff_dc_index[2] << 7;
1378 if (ctx->params.jpeg_huff_tab)
1379 val |= CODA9_JPEG_PIC_CTRL_USER_HUFFMAN_EN;
1380 coda_write(dev, val, CODA9_REG_JPEG_PIC_CTRL);
1381
1382 coda_write(dev, aligned_width << 16 | aligned_height,
1383 CODA9_REG_JPEG_PIC_SIZE);
1384
1385 chroma_interleave = (dst_fourcc == V4L2_PIX_FMT_NV12);
1386 coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO);
1387 coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
1388 coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
1389 coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
1390 coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
1391 coda_write(dev, ctx->params.jpeg_restart_interval,
1392 CODA9_REG_JPEG_RST_INTVAL);
1393
1394 if (ctx->params.jpeg_huff_tab) {
1395 ret = coda9_jpeg_dec_huff_setup(ctx);
1396 if (ret < 0) {
1397 v4l2_err(&dev->v4l2_dev,
1398 "failed to set up Huffman tables: %d\n", ret);
1399 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
1400 return ret;
1401 }
1402 }
1403
1404 coda9_jpeg_qmat_setup(ctx);
1405
1406 coda9_jpeg_dec_bbc_gbu_setup(ctx, &src_buf->vb2_buf,
1407 ctx->jpeg_ecs_offset);
1408
1409 coda_write(dev, 0, CODA9_REG_JPEG_RST_INDEX);
1410 coda_write(dev, 0, CODA9_REG_JPEG_RST_COUNT);
1411
1412 coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_Y);
1413 coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_CB);
1414 coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_CR);
1415
1416 coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO);
1417
1418 coda_write(dev, 1, CODA9_GDI_CONTROL);
1419 do {
1420 ret = coda_read(dev, CODA9_GDI_STATUS);
1421 } while (!ret);
1422
1423 val = (chroma_format << 17) | (chroma_interleave << 16) |
1424 q_data_dst->bytesperline;
1425 if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP)
1426 val |= 3 << 20;
1427 coda_write(dev, val, CODA9_GDI_INFO_CONTROL);
1428
1429 coda_write(dev, aligned_width << 16 | aligned_height,
1430 CODA9_GDI_INFO_PIC_SIZE);
1431
1432 coda_write_base(ctx, q_data_dst, dst_buf, CODA9_GDI_INFO_BASE_Y);
1433
1434 coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
1435 coda_write(dev, 0, CODA9_GDI_CONTROL);
1436 coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
1437
1438 trace_coda_jpeg_run(ctx, src_buf);
1439
1440 coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
1441
1442 return 0;
1443}
1444
1445static void coda9_jpeg_finish_decode(struct coda_ctx *ctx)
1446{
1447 struct coda_dev *dev = ctx->dev;
1448 struct vb2_v4l2_buffer *dst_buf, *src_buf;
1449 struct coda_q_data *q_data_dst;
1450 u32 err_mb;
1451
1452 err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
1453 if (err_mb)
1454 v4l2_err(&dev->v4l2_dev, "ERRMB: 0x%x\n", err_mb);
1455
1456 coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
1457
15c3d5aa
PZ
1458 /*
1459 * Lock to make sure that a decoder stop command running in parallel
1460 * will either already have marked src_buf as last, or it will wake up
1461 * the capture queue after the buffers are returned.
1462 */
1463 mutex_lock(&ctx->wakeup_mutex);
12310819
PZ
1464 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1465 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1466 dst_buf->sequence = ctx->osequence++;
1467
1468 trace_coda_jpeg_done(ctx, dst_buf);
1469
1470 dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
1471 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1472 dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
1473
1474 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
1475
1476 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1477 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, q_data_dst->sizeimage);
1478
1479 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1480 coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
1481 VB2_BUF_STATE_DONE);
1482
15c3d5aa
PZ
1483 mutex_unlock(&ctx->wakeup_mutex);
1484
12310819
PZ
1485 coda_dbg(1, ctx, "job finished: decoded frame (%u)%s\n",
1486 dst_buf->sequence,
1487 (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
1488
1489 /*
1490 * Reset JPEG processing unit after each decode run to work
1491 * around hangups when switching context between encoder and
1492 * decoder.
1493 */
1494 coda_hw_reset(ctx);
1495}
1496
1497const struct coda_context_ops coda9_jpeg_decode_ops = {
1498 .queue_init = coda_encoder_queue_init, /* non-bitstream operation */
1499 .start_streaming = coda9_jpeg_start_decoding,
1500 .prepare_run = coda9_jpeg_prepare_decode,
1501 .finish_run = coda9_jpeg_finish_decode,
1502 .release = coda9_jpeg_release,
1503};
1504
96f6f62c
PZ
1505irqreturn_t coda9_jpeg_irq_handler(int irq, void *data)
1506{
1507 struct coda_dev *dev = data;
1508 struct coda_ctx *ctx;
1509 int status;
1510 int err_mb;
1511
1512 status = coda_read(dev, CODA9_REG_JPEG_PIC_STATUS);
1513 if (status == 0)
1514 return IRQ_HANDLED;
1515 coda_write(dev, status, CODA9_REG_JPEG_PIC_STATUS);
1516
1517 if (status & CODA9_JPEG_STATUS_OVERFLOW)
1518 v4l2_err(&dev->v4l2_dev, "JPEG overflow\n");
1519
1520 if (status & CODA9_JPEG_STATUS_BBC_INT)
1521 v4l2_err(&dev->v4l2_dev, "JPEG BBC interrupt\n");
1522
1523 if (status & CODA9_JPEG_STATUS_ERROR) {
1524 v4l2_err(&dev->v4l2_dev, "JPEG error\n");
1525
1526 err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
1527 if (err_mb) {
1528 v4l2_err(&dev->v4l2_dev,
1529 "ERRMB: 0x%x: rst idx %d, mcu pos (%d,%d)\n",
1530 err_mb, err_mb >> 24, (err_mb >> 12) & 0xfff,
1531 err_mb & 0xfff);
1532 }
1533 }
1534
1535 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
1536 if (!ctx) {
1537 v4l2_err(&dev->v4l2_dev,
1538 "Instance released before the end of transaction\n");
1539 mutex_unlock(&dev->coda_mutex);
1540 return IRQ_HANDLED;
1541 }
1542
1543 complete(&ctx->completion);
1544
1545 return IRQ_HANDLED;
1546}