cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

coda-jpeg.c (44337B)


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