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