1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Coda multi-standard codec IP - JPEG support functions
5 * Copyright (C) 2014 Philipp Zabel, Pengutronix
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>
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
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] = {
49 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
50 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
53 0x08, 0x09, 0x0a, 0x0b,
56 static const unsigned char chroma_dc
[16 + 12] = {
58 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
59 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
62 0x08, 0x09, 0x0a, 0x0b,
65 static const unsigned char luma_ac
[16 + 162 + 2] = {
67 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
68 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
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] = {
95 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
96 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
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
)
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
;
180 struct coda_memcpy_desc
{
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;
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
)
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
);
226 bool coda_jpeg_check_buffer(struct coda_ctx
*ctx
, struct vb2_buffer
*vb
)
228 void *vaddr
= vb2_plane_vaddr(vb
, 0);
232 soi
= be16_to_cpup((__be16
*)vaddr
);
233 if (soi
!= SOI_MARKER
)
236 len
= vb2_get_plane_payload(vb
, 0);
238 for (i
= 0; i
< 32; i
++) {
239 eoi
= be16_to_cpup((__be16
*)(vaddr
- i
));
240 if (eoi
== EOI_MARKER
) {
242 vb2_set_plane_payload(vb
, 0, len
- i
);
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
;
288 static const unsigned char *huff_tabs
[4] = {
289 luma_dc
, luma_ac
, chroma_dc
, chroma_ac
,
293 huff
= kzalloc(sizeof(*huff
), GFP_KERNEL
);
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 */
304 for (i
= 1; i
<= 16; i
++) {
306 if (k
+ j
> maxsymbol
)
313 /* Figure C.2 - Generation of table of Huffman codes */
318 while (huff
->size
[k
] == si
) {
319 huff
->code
[k
++] = code
;
322 if (code
>= (1 << si
))
328 /* Figure C.3 - Ordering procedure for encoding procedure code tables */
329 for (k
= 0; k
< lastk
; k
++) {
331 if (i
>= maxsymbol
|| ehufsi
[i
])
333 ehufco
[i
] = huff
->code
[k
];
334 ehufsi
[i
] = huff
->size
[k
];
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
)
358 huff
= kzalloc(sizeof(*huff
), GFP_KERNEL
);
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
],
370 if (!ctx
->params
.jpeg_huff_data
) {
371 ctx
->params
.jpeg_huff_data
=
372 kzalloc(sizeof(u32
) * CODA9_JPEG_ENC_HUFF_DATA_SIZE
,
374 if (!ctx
->params
.jpeg_huff_data
) {
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
:
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)
395 ((huff
->size
[t
][i
] - 1) << 16) |
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
;
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
,
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
;
436 luma_tab
= ctx
->params
.jpeg_qmat_tab
[0];
440 chroma_tab
= ctx
->params
.jpeg_qmat_tab
[1];
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
{
454 static inline int coda_jpeg_put_byte(u8 byte
, struct coda_jpeg_stream
*stream
)
456 if (stream
->curr
>= stream
->end
)
459 *stream
->curr
++ = byte
;
464 static inline int coda_jpeg_put_word(u16 word
, struct coda_jpeg_stream
*stream
)
466 if (stream
->curr
+ sizeof(__be16
) > stream
->end
)
469 put_unaligned_be16(word
, stream
->curr
);
470 stream
->curr
+= sizeof(__be16
);
475 static int coda_jpeg_put_table(u16 marker
, u8 index
, const u8
*table
,
476 size_t len
, struct coda_jpeg_stream
*stream
)
480 ret
= coda_jpeg_put_word(marker
, stream
);
483 ret
= coda_jpeg_put_word(3 + len
, stream
);
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
);
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,
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
;
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)
520 ret
= coda_jpeg_put_word(SOI_MARKER
, &stream
);
524 /* Define Restart Interval */
525 if (ctx
->params
.jpeg_restart_interval
) {
526 ret
= coda_jpeg_put_word(DRI_MARKER
, &stream
);
529 ret
= coda_jpeg_put_word(4, &stream
);
532 ret
= coda_jpeg_put_word(ctx
->params
.jpeg_restart_interval
,
538 /* Define Quantization Tables */
539 ret
= coda_jpeg_define_quantization_table(ctx
, 0x00, &stream
);
542 if (chroma_format
!= CODA9_JPEG_FORMAT_400
) {
543 ret
= coda_jpeg_define_quantization_table(ctx
, 0x01, &stream
);
548 /* Define Huffman Tables */
549 ret
= coda_jpeg_define_huffman_table(0x00, luma_dc
, 16 + 12, &stream
);
552 ret
= coda_jpeg_define_huffman_table(0x10, luma_ac
, 16 + 162, &stream
);
555 if (chroma_format
!= CODA9_JPEG_FORMAT_400
) {
556 ret
= coda_jpeg_define_huffman_table(0x01, chroma_dc
, 16 + 12,
560 ret
= coda_jpeg_define_huffman_table(0x11, chroma_ac
, 16 + 162,
567 ret
= coda_jpeg_put_word(SOF_MARKER
, &stream
);
570 comp_num
= (chroma_format
== CODA9_JPEG_FORMAT_400
) ? 1 : 3;
571 ret
= coda_jpeg_put_word(8 + comp_num
* 3, &stream
);
574 ret
= coda_jpeg_put_byte(0x08, &stream
);
577 ret
= coda_jpeg_put_word(q_data_src
->height
, &stream
);
580 ret
= coda_jpeg_put_word(q_data_src
->width
, &stream
);
583 ret
= coda_jpeg_put_byte(comp_num
, &stream
);
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
);
599 ret
= coda_jpeg_put_byte(subsampling
[chroma_format
][i
],
603 /* Chroma table index */
604 ret
= coda_jpeg_put_byte((i
== 0) ? 0 : 1, &stream
);
609 /* Pad to multiple of 8 bytes */
610 pad
= (stream
.curr
- buf
) % 8;
614 ret
= coda_jpeg_put_byte(0x00, &stream
);
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
)
632 for (i
= 0; i
< 64; i
++) {
633 temp
= DIV_ROUND_CLOSEST((unsigned int)q_tab
[i
] * scale
, 100);
638 q_tab
[i
] = (unsigned char)temp
;
642 void coda_set_jpeg_compression_quality(struct coda_ctx
*ctx
, int quality
)
646 ctx
->params
.jpeg_quality
= quality
;
648 /* Clip quality setting to [5,100] interval */
655 * Non-linear scaling factor:
656 * [5,50] -> [1000..100], [51,100] -> [98..0]
659 scale
= 5000 / quality
;
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
;
682 ret
= coda9_jpeg_load_huff_tab(ctx
);
684 v4l2_err(&dev
->v4l2_dev
, "error loading Huffman tables\n");
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
);
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
;
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
;
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
);
743 coda9_jpeg_encode_header(ctx
,
744 vb2_plane_size(&dst_buf
->vb2_buf
, 0),
745 vb2_plane_vaddr(&dst_buf
->vb2_buf
, 0));
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);
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");
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
);
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
;
840 coda_write(ctx
->dev
, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD
);
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
);
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
:
878 mutex_unlock(&ctx
->wakeup_mutex
);
880 coda_dbg(1, ctx
, "job finished: encoded frame (%u)%s\n",
882 (dst_buf
->flags
& V4L2_BUF_FLAG_LAST
) ? " (last)" : "");
885 static void coda9_jpeg_release(struct coda_ctx
*ctx
)
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
;
913 status
= coda_read(dev
, CODA9_REG_JPEG_PIC_STATUS
);
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
);
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,
936 ctx
= v4l2_m2m_get_curr_priv(dev
->m2m_dev
);
938 v4l2_err(&dev
->v4l2_dev
,
939 "Instance released before the end of transaction\n");
940 mutex_unlock(&dev
->coda_mutex
);
944 complete(&ctx
->completion
);