treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / media / platform / coda / coda-jpeg.c
blob92234fd1f4fddabb789f99b19860b5fa0e10e394
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Coda multi-standard codec IP - JPEG support functions
5 * Copyright (C) 2014 Philipp Zabel, Pengutronix
6 */
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>
16 #include <media/v4l2-common.h>
17 #include <media/v4l2-fh.h>
18 #include <media/v4l2-mem2mem.h>
19 #include <media/videobuf2-core.h>
20 #include <media/videobuf2-dma-contig.h>
22 #include "coda.h"
23 #include "trace.h"
25 #define SOI_MARKER 0xffd8
26 #define DRI_MARKER 0xffdd
27 #define DQT_MARKER 0xffdb
28 #define DHT_MARKER 0xffc4
29 #define SOF_MARKER 0xffc0
30 #define EOI_MARKER 0xffd9
32 enum {
33 CODA9_JPEG_FORMAT_420,
34 CODA9_JPEG_FORMAT_422,
35 CODA9_JPEG_FORMAT_224,
36 CODA9_JPEG_FORMAT_444,
37 CODA9_JPEG_FORMAT_400,
40 #define CODA9_JPEG_ENC_HUFF_DATA_SIZE (256 + 256 + 16 + 16)
43 * Typical Huffman tables for 8-bit precision luminance and
44 * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3
47 static const unsigned char luma_dc[16 + 12] = {
48 /* bits */
49 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
50 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 /* values */
52 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
53 0x08, 0x09, 0x0a, 0x0b,
56 static const unsigned char chroma_dc[16 + 12] = {
57 /* bits */
58 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
59 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
60 /* values */
61 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
62 0x08, 0x09, 0x0a, 0x0b,
65 static const unsigned char luma_ac[16 + 162 + 2] = {
66 /* bits */
67 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
68 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
69 /* values */
70 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
71 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
72 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
73 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
74 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
75 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
76 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
77 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
78 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
79 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
80 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
81 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
82 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
83 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
84 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
85 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
86 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
87 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
88 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
89 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
90 0xf9, 0xfa, /* padded to 32-bit */
93 static const unsigned char chroma_ac[16 + 162 + 2] = {
94 /* bits */
95 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
96 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
97 /* values */
98 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
99 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
100 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
101 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
102 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
103 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
104 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
105 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
106 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
107 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
108 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
109 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
110 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
111 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
112 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
113 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
114 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
115 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
116 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
117 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
118 0xf9, 0xfa, /* padded to 32-bit */
122 * Quantization tables for luminance and chrominance components in
123 * zig-zag scan order from the Freescale i.MX VPU libraries
126 static unsigned char luma_q[64] = {
127 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05,
128 0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b,
129 0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a, 0x0a,
130 0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c,
131 0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c,
132 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
133 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
134 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
137 static unsigned char chroma_q[64] = {
138 0x07, 0x07, 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10,
139 0x10, 0x18, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14,
140 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c,
141 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c,
142 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c,
143 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
144 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
145 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
148 static const unsigned char width_align[] = {
149 [CODA9_JPEG_FORMAT_420] = 16,
150 [CODA9_JPEG_FORMAT_422] = 16,
151 [CODA9_JPEG_FORMAT_224] = 8,
152 [CODA9_JPEG_FORMAT_444] = 8,
153 [CODA9_JPEG_FORMAT_400] = 8,
156 static const unsigned char height_align[] = {
157 [CODA9_JPEG_FORMAT_420] = 16,
158 [CODA9_JPEG_FORMAT_422] = 8,
159 [CODA9_JPEG_FORMAT_224] = 16,
160 [CODA9_JPEG_FORMAT_444] = 8,
161 [CODA9_JPEG_FORMAT_400] = 8,
164 static int coda9_jpeg_chroma_format(u32 pixfmt)
166 switch (pixfmt) {
167 case V4L2_PIX_FMT_YUV420:
168 case V4L2_PIX_FMT_NV12:
169 return CODA9_JPEG_FORMAT_420;
170 case V4L2_PIX_FMT_YUV422P:
171 return CODA9_JPEG_FORMAT_422;
172 case V4L2_PIX_FMT_YUV444:
173 return CODA9_JPEG_FORMAT_444;
174 case V4L2_PIX_FMT_GREY:
175 return CODA9_JPEG_FORMAT_400;
177 return -EINVAL;
180 struct coda_memcpy_desc {
181 int offset;
182 const void *src;
183 size_t len;
186 static void coda_memcpy_parabuf(void *parabuf,
187 const struct coda_memcpy_desc *desc)
189 u32 *dst = parabuf + desc->offset;
190 const u32 *src = desc->src;
191 int len = desc->len / 4;
192 int i;
194 for (i = 0; i < len; i += 2) {
195 dst[i + 1] = swab32(src[i]);
196 dst[i] = swab32(src[i + 1]);
200 int coda_jpeg_write_tables(struct coda_ctx *ctx)
202 int i;
203 static const struct coda_memcpy_desc huff[8] = {
204 { 0, luma_dc, sizeof(luma_dc) },
205 { 32, luma_ac, sizeof(luma_ac) },
206 { 216, chroma_dc, sizeof(chroma_dc) },
207 { 248, chroma_ac, sizeof(chroma_ac) },
209 struct coda_memcpy_desc qmat[3] = {
210 { 512, ctx->params.jpeg_qmat_tab[0], 64 },
211 { 576, ctx->params.jpeg_qmat_tab[1], 64 },
212 { 640, ctx->params.jpeg_qmat_tab[1], 64 },
215 /* Write huffman tables to parameter memory */
216 for (i = 0; i < ARRAY_SIZE(huff); i++)
217 coda_memcpy_parabuf(ctx->parabuf.vaddr, huff + i);
219 /* Write Q-matrix to parameter memory */
220 for (i = 0; i < ARRAY_SIZE(qmat); i++)
221 coda_memcpy_parabuf(ctx->parabuf.vaddr, qmat + i);
223 return 0;
226 bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
228 void *vaddr = vb2_plane_vaddr(vb, 0);
229 u16 soi, eoi;
230 int len, i;
232 soi = be16_to_cpup((__be16 *)vaddr);
233 if (soi != SOI_MARKER)
234 return false;
236 len = vb2_get_plane_payload(vb, 0);
237 vaddr += len - 2;
238 for (i = 0; i < 32; i++) {
239 eoi = be16_to_cpup((__be16 *)(vaddr - i));
240 if (eoi == EOI_MARKER) {
241 if (i > 0)
242 vb2_set_plane_payload(vb, 0, len - i);
243 return true;
247 return false;
250 static const int bus_req_num[] = {
251 [CODA9_JPEG_FORMAT_420] = 2,
252 [CODA9_JPEG_FORMAT_422] = 3,
253 [CODA9_JPEG_FORMAT_224] = 3,
254 [CODA9_JPEG_FORMAT_444] = 4,
255 [CODA9_JPEG_FORMAT_400] = 4,
258 #define MCU_INFO(mcu_block_num, comp_num, comp0_info, comp1_info, comp2_info) \
259 (((mcu_block_num) << CODA9_JPEG_MCU_BLOCK_NUM_OFFSET) | \
260 ((comp_num) << CODA9_JPEG_COMP_NUM_OFFSET) | \
261 ((comp0_info) << CODA9_JPEG_COMP0_INFO_OFFSET) | \
262 ((comp1_info) << CODA9_JPEG_COMP1_INFO_OFFSET) | \
263 ((comp2_info) << CODA9_JPEG_COMP2_INFO_OFFSET))
265 static const u32 mcu_info[] = {
266 [CODA9_JPEG_FORMAT_420] = MCU_INFO(6, 3, 10, 5, 5),
267 [CODA9_JPEG_FORMAT_422] = MCU_INFO(4, 3, 9, 5, 5),
268 [CODA9_JPEG_FORMAT_224] = MCU_INFO(4, 3, 6, 5, 5),
269 [CODA9_JPEG_FORMAT_444] = MCU_INFO(3, 3, 5, 5, 5),
270 [CODA9_JPEG_FORMAT_400] = MCU_INFO(1, 1, 5, 0, 0),
274 * Convert Huffman table specifcations to tables of codes and code lengths.
275 * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
277 * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
279 static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num,
280 int *ehufsi, int *ehufco)
282 int i, j, k, lastk, si, code, maxsymbol;
283 const u8 *bits, *huffval;
284 struct {
285 int size[256];
286 int code[256];
287 } *huff;
288 static const unsigned char *huff_tabs[4] = {
289 luma_dc, luma_ac, chroma_dc, chroma_ac,
291 int ret = -EINVAL;
293 huff = kzalloc(sizeof(*huff), GFP_KERNEL);
294 if (!huff)
295 return -ENOMEM;
297 bits = huff_tabs[tab_num];
298 huffval = huff_tabs[tab_num] + 16;
300 maxsymbol = tab_num & 1 ? 256 : 16;
302 /* Figure C.1 - Generation of table of Huffman code sizes */
303 k = 0;
304 for (i = 1; i <= 16; i++) {
305 j = bits[i - 1];
306 if (k + j > maxsymbol)
307 goto out;
308 while (j--)
309 huff->size[k++] = i;
311 lastk = k;
313 /* Figure C.2 - Generation of table of Huffman codes */
314 k = 0;
315 code = 0;
316 si = huff->size[0];
317 while (k < lastk) {
318 while (huff->size[k] == si) {
319 huff->code[k++] = code;
320 code++;
322 if (code >= (1 << si))
323 goto out;
324 code <<= 1;
325 si++;
328 /* Figure C.3 - Ordering procedure for encoding procedure code tables */
329 for (k = 0; k < lastk; k++) {
330 i = huffval[k];
331 if (i >= maxsymbol || ehufsi[i])
332 goto out;
333 ehufco[i] = huff->code[k];
334 ehufsi[i] = huff->size[k];
337 ret = 0;
338 out:
339 kfree(huff);
340 return ret;
343 #define DC_TABLE_INDEX0 0
344 #define AC_TABLE_INDEX0 1
345 #define DC_TABLE_INDEX1 2
346 #define AC_TABLE_INDEX1 3
348 static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx)
350 struct {
351 int size[4][256];
352 int code[4][256];
353 } *huff;
354 u32 *huff_data;
355 int i, j;
356 int ret;
358 huff = kzalloc(sizeof(*huff), GFP_KERNEL);
359 if (!huff)
360 return -ENOMEM;
362 /* Generate all four (luma/chroma DC/AC) code/size lookup tables */
363 for (i = 0; i < 4; i++) {
364 ret = coda9_jpeg_gen_enc_huff_tab(ctx, i, huff->size[i],
365 huff->code[i]);
366 if (ret)
367 goto out;
370 if (!ctx->params.jpeg_huff_data) {
371 ctx->params.jpeg_huff_data =
372 kzalloc(sizeof(u32) * CODA9_JPEG_ENC_HUFF_DATA_SIZE,
373 GFP_KERNEL);
374 if (!ctx->params.jpeg_huff_data) {
375 ret = -ENOMEM;
376 goto out;
379 huff_data = ctx->params.jpeg_huff_data;
381 for (j = 0; j < 4; j++) {
382 /* Store Huffman lookup tables in AC0, AC1, DC0, DC1 order */
383 int t = (j == 0) ? AC_TABLE_INDEX0 :
384 (j == 1) ? AC_TABLE_INDEX1 :
385 (j == 2) ? DC_TABLE_INDEX0 :
386 DC_TABLE_INDEX1;
387 /* DC tables only have 16 entries */
388 int len = (j < 2) ? 256 : 16;
390 for (i = 0; i < len; i++) {
391 if (huff->size[t][i] == 0 && huff->code[t][i] == 0)
392 *(huff_data++) = 0;
393 else
394 *(huff_data++) =
395 ((huff->size[t][i] - 1) << 16) |
396 huff->code[t][i];
400 ret = 0;
401 out:
402 kfree(huff);
403 return ret;
406 static void coda9_jpeg_write_huff_tab(struct coda_ctx *ctx)
408 struct coda_dev *dev = ctx->dev;
409 u32 *huff_data = ctx->params.jpeg_huff_data;
410 int i;
412 /* Write Huffman size/code lookup tables in AC0, AC1, DC0, DC1 order */
413 coda_write(dev, 0x3, CODA9_REG_JPEG_HUFF_CTRL);
414 for (i = 0; i < CODA9_JPEG_ENC_HUFF_DATA_SIZE; i++)
415 coda_write(dev, *(huff_data++), CODA9_REG_JPEG_HUFF_DATA);
416 coda_write(dev, 0x0, CODA9_REG_JPEG_HUFF_CTRL);
419 static inline void coda9_jpeg_write_qmat_quotients(struct coda_dev *dev,
420 u8 *qmat, int index)
422 int i;
424 coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
425 for (i = 0; i < 64; i++)
426 coda_write(dev, 0x80000 / qmat[i], CODA9_REG_JPEG_QMAT_DATA);
427 coda_write(dev, index, CODA9_REG_JPEG_QMAT_CTRL);
430 static void coda9_jpeg_load_qmat_tab(struct coda_ctx *ctx)
432 struct coda_dev *dev = ctx->dev;
433 u8 *luma_tab;
434 u8 *chroma_tab;
436 luma_tab = ctx->params.jpeg_qmat_tab[0];
437 if (!luma_tab)
438 luma_tab = luma_q;
440 chroma_tab = ctx->params.jpeg_qmat_tab[1];
441 if (!chroma_tab)
442 chroma_tab = chroma_q;
444 coda9_jpeg_write_qmat_quotients(dev, luma_tab, 0x00);
445 coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x40);
446 coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x80);
449 struct coda_jpeg_stream {
450 u8 *curr;
451 u8 *end;
454 static inline int coda_jpeg_put_byte(u8 byte, struct coda_jpeg_stream *stream)
456 if (stream->curr >= stream->end)
457 return -EINVAL;
459 *stream->curr++ = byte;
461 return 0;
464 static inline int coda_jpeg_put_word(u16 word, struct coda_jpeg_stream *stream)
466 if (stream->curr + sizeof(__be16) > stream->end)
467 return -EINVAL;
469 put_unaligned_be16(word, stream->curr);
470 stream->curr += sizeof(__be16);
472 return 0;
475 static int coda_jpeg_put_table(u16 marker, u8 index, const u8 *table,
476 size_t len, struct coda_jpeg_stream *stream)
478 int i, ret;
480 ret = coda_jpeg_put_word(marker, stream);
481 if (ret < 0)
482 return ret;
483 ret = coda_jpeg_put_word(3 + len, stream);
484 if (ret < 0)
485 return ret;
486 ret = coda_jpeg_put_byte(index, stream);
487 for (i = 0; i < len && ret == 0; i++)
488 ret = coda_jpeg_put_byte(table[i], stream);
490 return ret;
493 static int coda_jpeg_define_quantization_table(struct coda_ctx *ctx, u8 index,
494 struct coda_jpeg_stream *stream)
496 return coda_jpeg_put_table(DQT_MARKER, index,
497 ctx->params.jpeg_qmat_tab[index], 64,
498 stream);
501 static int coda_jpeg_define_huffman_table(u8 index, const u8 *table, size_t len,
502 struct coda_jpeg_stream *stream)
504 return coda_jpeg_put_table(DHT_MARKER, index, table, len, stream);
507 static int coda9_jpeg_encode_header(struct coda_ctx *ctx, int len, u8 *buf)
509 struct coda_jpeg_stream stream = { buf, buf + len };
510 struct coda_q_data *q_data_src;
511 int chroma_format, comp_num;
512 int i, ret, pad;
514 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
515 chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
516 if (chroma_format < 0)
517 return 0;
519 /* Start Of Image */
520 ret = coda_jpeg_put_word(SOI_MARKER, &stream);
521 if (ret < 0)
522 return ret;
524 /* Define Restart Interval */
525 if (ctx->params.jpeg_restart_interval) {
526 ret = coda_jpeg_put_word(DRI_MARKER, &stream);
527 if (ret < 0)
528 return ret;
529 ret = coda_jpeg_put_word(4, &stream);
530 if (ret < 0)
531 return ret;
532 ret = coda_jpeg_put_word(ctx->params.jpeg_restart_interval,
533 &stream);
534 if (ret < 0)
535 return ret;
538 /* Define Quantization Tables */
539 ret = coda_jpeg_define_quantization_table(ctx, 0x00, &stream);
540 if (ret < 0)
541 return ret;
542 if (chroma_format != CODA9_JPEG_FORMAT_400) {
543 ret = coda_jpeg_define_quantization_table(ctx, 0x01, &stream);
544 if (ret < 0)
545 return ret;
548 /* Define Huffman Tables */
549 ret = coda_jpeg_define_huffman_table(0x00, luma_dc, 16 + 12, &stream);
550 if (ret < 0)
551 return ret;
552 ret = coda_jpeg_define_huffman_table(0x10, luma_ac, 16 + 162, &stream);
553 if (ret < 0)
554 return ret;
555 if (chroma_format != CODA9_JPEG_FORMAT_400) {
556 ret = coda_jpeg_define_huffman_table(0x01, chroma_dc, 16 + 12,
557 &stream);
558 if (ret < 0)
559 return ret;
560 ret = coda_jpeg_define_huffman_table(0x11, chroma_ac, 16 + 162,
561 &stream);
562 if (ret < 0)
563 return ret;
566 /* Start Of Frame */
567 ret = coda_jpeg_put_word(SOF_MARKER, &stream);
568 if (ret < 0)
569 return ret;
570 comp_num = (chroma_format == CODA9_JPEG_FORMAT_400) ? 1 : 3;
571 ret = coda_jpeg_put_word(8 + comp_num * 3, &stream);
572 if (ret < 0)
573 return ret;
574 ret = coda_jpeg_put_byte(0x08, &stream);
575 if (ret < 0)
576 return ret;
577 ret = coda_jpeg_put_word(q_data_src->height, &stream);
578 if (ret < 0)
579 return ret;
580 ret = coda_jpeg_put_word(q_data_src->width, &stream);
581 if (ret < 0)
582 return ret;
583 ret = coda_jpeg_put_byte(comp_num, &stream);
584 if (ret < 0)
585 return ret;
586 for (i = 0; i < comp_num; i++) {
587 static unsigned char subsampling[5][3] = {
588 [CODA9_JPEG_FORMAT_420] = { 0x22, 0x11, 0x11 },
589 [CODA9_JPEG_FORMAT_422] = { 0x21, 0x11, 0x11 },
590 [CODA9_JPEG_FORMAT_224] = { 0x12, 0x11, 0x11 },
591 [CODA9_JPEG_FORMAT_444] = { 0x11, 0x11, 0x11 },
592 [CODA9_JPEG_FORMAT_400] = { 0x11 },
595 /* Component identifier, matches SOS */
596 ret = coda_jpeg_put_byte(i + 1, &stream);
597 if (ret < 0)
598 return ret;
599 ret = coda_jpeg_put_byte(subsampling[chroma_format][i],
600 &stream);
601 if (ret < 0)
602 return ret;
603 /* Chroma table index */
604 ret = coda_jpeg_put_byte((i == 0) ? 0 : 1, &stream);
605 if (ret < 0)
606 return ret;
609 /* Pad to multiple of 8 bytes */
610 pad = (stream.curr - buf) % 8;
611 if (pad) {
612 pad = 8 - pad;
613 while (pad--) {
614 ret = coda_jpeg_put_byte(0x00, &stream);
615 if (ret < 0)
616 return ret;
620 return stream.curr - buf;
624 * Scale quantization table using nonlinear scaling factor
625 * u8 qtab[64], scale [50,190]
627 static void coda_scale_quant_table(u8 *q_tab, int scale)
629 unsigned int temp;
630 int i;
632 for (i = 0; i < 64; i++) {
633 temp = DIV_ROUND_CLOSEST((unsigned int)q_tab[i] * scale, 100);
634 if (temp <= 0)
635 temp = 1;
636 if (temp > 255)
637 temp = 255;
638 q_tab[i] = (unsigned char)temp;
642 void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality)
644 unsigned int scale;
646 ctx->params.jpeg_quality = quality;
648 /* Clip quality setting to [5,100] interval */
649 if (quality > 100)
650 quality = 100;
651 if (quality < 5)
652 quality = 5;
655 * Non-linear scaling factor:
656 * [5,50] -> [1000..100], [51,100] -> [98..0]
658 if (quality < 50)
659 scale = 5000 / quality;
660 else
661 scale = 200 - 2 * quality;
663 if (ctx->params.jpeg_qmat_tab[0]) {
664 memcpy(ctx->params.jpeg_qmat_tab[0], luma_q, 64);
665 coda_scale_quant_table(ctx->params.jpeg_qmat_tab[0], scale);
667 if (ctx->params.jpeg_qmat_tab[1]) {
668 memcpy(ctx->params.jpeg_qmat_tab[1], chroma_q, 64);
669 coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale);
674 * Encoder context operations
677 static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
679 struct coda_dev *dev = ctx->dev;
680 int ret;
682 ret = coda9_jpeg_load_huff_tab(ctx);
683 if (ret < 0) {
684 v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
685 return ret;
687 if (!ctx->params.jpeg_qmat_tab[0])
688 ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
689 if (!ctx->params.jpeg_qmat_tab[1])
690 ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
691 coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
693 return 0;
696 static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
698 struct coda_q_data *q_data_src;
699 struct vb2_v4l2_buffer *src_buf, *dst_buf;
700 struct coda_dev *dev = ctx->dev;
701 u32 start_addr, end_addr;
702 u16 aligned_width, aligned_height;
703 bool chroma_interleave;
704 int chroma_format;
705 int header_len;
706 int ret;
707 ktime_t timeout;
709 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
710 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
711 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
713 if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
714 vb2_set_plane_payload(&src_buf->vb2_buf, 0,
715 vb2_plane_size(&src_buf->vb2_buf, 0));
717 src_buf->sequence = ctx->osequence;
718 dst_buf->sequence = ctx->osequence;
719 ctx->osequence++;
721 src_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
722 src_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
724 coda_set_gdi_regs(ctx);
726 start_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
727 end_addr = start_addr + vb2_plane_size(&dst_buf->vb2_buf, 0);
729 chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
730 if (chroma_format < 0)
731 return chroma_format;
733 /* Round image dimensions to multiple of MCU size */
734 aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
735 aligned_height = round_up(q_data_src->height,
736 height_align[chroma_format]);
737 if (aligned_width != q_data_src->bytesperline) {
738 v4l2_err(&dev->v4l2_dev, "wrong stride: %d instead of %d\n",
739 aligned_width, q_data_src->bytesperline);
742 header_len =
743 coda9_jpeg_encode_header(ctx,
744 vb2_plane_size(&dst_buf->vb2_buf, 0),
745 vb2_plane_vaddr(&dst_buf->vb2_buf, 0));
746 if (header_len < 0)
747 return header_len;
749 coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_BAS_ADDR);
750 coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_END_ADDR);
751 coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_WR_PTR);
752 coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_RD_PTR);
753 coda_write(dev, 0, CODA9_REG_JPEG_BBC_CUR_POS);
754 /* 64 words per 256-byte page */
755 coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
756 coda_write(dev, start_addr, CODA9_REG_JPEG_BBC_EXT_ADDR);
757 coda_write(dev, 0, CODA9_REG_JPEG_BBC_INT_ADDR);
759 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
760 coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
761 coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
762 coda_write(dev, 0, CODA9_REG_JPEG_BBC_STRM_CTRL);
763 coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
764 coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
765 coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
766 coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
767 coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
769 chroma_interleave = (q_data_src->fourcc == V4L2_PIX_FMT_NV12);
770 coda_write(dev, CODA9_JPEG_PIC_CTRL_TC_DIRECTION |
771 CODA9_JPEG_PIC_CTRL_ENCODER_EN, CODA9_REG_JPEG_PIC_CTRL);
772 coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
773 coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
774 coda_write(dev, ctx->params.jpeg_restart_interval,
775 CODA9_REG_JPEG_RST_INTVAL);
776 coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
778 coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
780 coda9_jpeg_write_huff_tab(ctx);
781 coda9_jpeg_load_qmat_tab(ctx);
783 if (ctx->params.rot_mode & CODA_ROT_90) {
784 aligned_width = aligned_height;
785 aligned_height = q_data_src->bytesperline;
786 if (chroma_format == CODA9_JPEG_FORMAT_422)
787 chroma_format = CODA9_JPEG_FORMAT_224;
788 else if (chroma_format == CODA9_JPEG_FORMAT_224)
789 chroma_format = CODA9_JPEG_FORMAT_422;
791 /* These need to be multiples of MCU size */
792 coda_write(dev, aligned_width << 16 | aligned_height,
793 CODA9_REG_JPEG_PIC_SIZE);
794 coda_write(dev, ctx->params.rot_mode ?
795 (CODA_ROT_MIR_ENABLE | ctx->params.rot_mode) : 0,
796 CODA9_REG_JPEG_ROT_INFO);
798 coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
800 coda_write(dev, 1, CODA9_GDI_CONTROL);
801 timeout = ktime_add_us(ktime_get(), 100000);
802 do {
803 ret = coda_read(dev, CODA9_GDI_STATUS);
804 if (ktime_compare(ktime_get(), timeout) > 0) {
805 v4l2_err(&dev->v4l2_dev, "timeout waiting for GDI\n");
806 return -ETIMEDOUT;
808 } while (!ret);
810 coda_write(dev, (chroma_format << 17) | (chroma_interleave << 16) |
811 q_data_src->bytesperline, CODA9_GDI_INFO_CONTROL);
812 /* The content of this register seems to be irrelevant: */
813 coda_write(dev, aligned_width << 16 | aligned_height,
814 CODA9_GDI_INFO_PIC_SIZE);
816 coda_write_base(ctx, q_data_src, src_buf, CODA9_GDI_INFO_BASE_Y);
818 coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
819 coda_write(dev, 0, CODA9_GDI_CONTROL);
820 coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
822 coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
823 coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
825 trace_coda_jpeg_run(ctx, src_buf);
827 coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
829 return 0;
832 static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
834 struct vb2_v4l2_buffer *src_buf, *dst_buf;
835 struct coda_dev *dev = ctx->dev;
836 u32 wr_ptr, start_ptr;
837 u32 err_mb;
839 if (ctx->aborting) {
840 coda_write(ctx->dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
841 return;
845 * Lock to make sure that an encoder stop command running in parallel
846 * will either already have marked src_buf as last, or it will wake up
847 * the capture queue after the buffers are returned.
849 mutex_lock(&ctx->wakeup_mutex);
850 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
851 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
853 trace_coda_jpeg_done(ctx, dst_buf);
856 * Set plane payload to the number of bytes written out
857 * by the JPEG processing unit
859 start_ptr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
860 wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
861 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr);
863 err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
864 if (err_mb)
865 coda_dbg(1, ctx, "ERRMB: 0x%x\n", err_mb);
867 coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
869 dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
870 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
871 dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
873 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
875 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
876 coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
877 VB2_BUF_STATE_DONE);
878 mutex_unlock(&ctx->wakeup_mutex);
880 coda_dbg(1, ctx, "job finished: encoded frame (%u)%s\n",
881 dst_buf->sequence,
882 (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
885 static void coda9_jpeg_release(struct coda_ctx *ctx)
887 int i;
889 if (ctx->params.jpeg_qmat_tab[0] == luma_q)
890 ctx->params.jpeg_qmat_tab[0] = NULL;
891 if (ctx->params.jpeg_qmat_tab[1] == chroma_q)
892 ctx->params.jpeg_qmat_tab[1] = NULL;
893 for (i = 0; i < 3; i++)
894 kfree(ctx->params.jpeg_qmat_tab[i]);
895 kfree(ctx->params.jpeg_huff_data);
898 const struct coda_context_ops coda9_jpeg_encode_ops = {
899 .queue_init = coda_encoder_queue_init,
900 .start_streaming = coda9_jpeg_start_encoding,
901 .prepare_run = coda9_jpeg_prepare_encode,
902 .finish_run = coda9_jpeg_finish_encode,
903 .release = coda9_jpeg_release,
906 irqreturn_t coda9_jpeg_irq_handler(int irq, void *data)
908 struct coda_dev *dev = data;
909 struct coda_ctx *ctx;
910 int status;
911 int err_mb;
913 status = coda_read(dev, CODA9_REG_JPEG_PIC_STATUS);
914 if (status == 0)
915 return IRQ_HANDLED;
916 coda_write(dev, status, CODA9_REG_JPEG_PIC_STATUS);
918 if (status & CODA9_JPEG_STATUS_OVERFLOW)
919 v4l2_err(&dev->v4l2_dev, "JPEG overflow\n");
921 if (status & CODA9_JPEG_STATUS_BBC_INT)
922 v4l2_err(&dev->v4l2_dev, "JPEG BBC interrupt\n");
924 if (status & CODA9_JPEG_STATUS_ERROR) {
925 v4l2_err(&dev->v4l2_dev, "JPEG error\n");
927 err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
928 if (err_mb) {
929 v4l2_err(&dev->v4l2_dev,
930 "ERRMB: 0x%x: rst idx %d, mcu pos (%d,%d)\n",
931 err_mb, err_mb >> 24, (err_mb >> 12) & 0xfff,
932 err_mb & 0xfff);
936 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
937 if (!ctx) {
938 v4l2_err(&dev->v4l2_dev,
939 "Instance released before the end of transaction\n");
940 mutex_unlock(&dev->coda_mutex);
941 return IRQ_HANDLED;
944 complete(&ctx->completion);
946 return IRQ_HANDLED;