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