Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Coda multi-standard codec IP - JPEG support functions
0004  *
0005  * Copyright (C) 2014 Philipp Zabel, Pengutronix
0006  */
0007 
0008 #include <asm/unaligned.h>
0009 #include <linux/irqreturn.h>
0010 #include <linux/kernel.h>
0011 #include <linux/ktime.h>
0012 #include <linux/slab.h>
0013 #include <linux/swab.h>
0014 #include <linux/videodev2.h>
0015 
0016 #include <media/v4l2-common.h>
0017 #include <media/v4l2-fh.h>
0018 #include <media/v4l2-jpeg.h>
0019 #include <media/v4l2-mem2mem.h>
0020 #include <media/videobuf2-core.h>
0021 #include <media/videobuf2-dma-contig.h>
0022 
0023 #include "coda.h"
0024 #include "trace.h"
0025 
0026 #define SOI_MARKER  0xffd8
0027 #define APP9_MARKER 0xffe9
0028 #define DRI_MARKER  0xffdd
0029 #define DQT_MARKER  0xffdb
0030 #define DHT_MARKER  0xffc4
0031 #define SOF_MARKER  0xffc0
0032 #define SOS_MARKER  0xffda
0033 #define EOI_MARKER  0xffd9
0034 
0035 enum {
0036     CODA9_JPEG_FORMAT_420,
0037     CODA9_JPEG_FORMAT_422,
0038     CODA9_JPEG_FORMAT_224,
0039     CODA9_JPEG_FORMAT_444,
0040     CODA9_JPEG_FORMAT_400,
0041 };
0042 
0043 struct coda_huff_tab {
0044     u8 luma_dc[16 + 12];
0045     u8 chroma_dc[16 + 12];
0046     u8 luma_ac[16 + 162];
0047     u8 chroma_ac[16 + 162];
0048 
0049     /* DC Luma, DC Chroma, AC Luma, AC Chroma */
0050     s16 min[4 * 16];
0051     s16 max[4 * 16];
0052     s8  ptr[4 * 16];
0053 };
0054 
0055 #define CODA9_JPEG_ENC_HUFF_DATA_SIZE   (256 + 256 + 16 + 16)
0056 
0057 /*
0058  * Typical Huffman tables for 8-bit precision luminance and
0059  * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3
0060  */
0061 
0062 static const unsigned char luma_dc[16 + 12] = {
0063     /* bits */
0064     0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
0065     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0066     /* values */
0067     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0068     0x08, 0x09, 0x0a, 0x0b,
0069 };
0070 
0071 static const unsigned char chroma_dc[16 + 12] = {
0072     /* bits */
0073     0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0074     0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0075     /* values */
0076     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0077     0x08, 0x09, 0x0a, 0x0b,
0078 };
0079 
0080 static const unsigned char luma_ac[16 + 162 + 2] = {
0081     /* bits */
0082     0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
0083     0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
0084     /* values */
0085     0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0086     0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0087     0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0088     0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0089     0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0090     0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0091     0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0092     0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0093     0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0094     0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0095     0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0096     0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0097     0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0098     0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0099     0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0100     0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0101     0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0102     0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0103     0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0104     0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0105     0xf9, 0xfa, /* padded to 32-bit */
0106 };
0107 
0108 static const unsigned char chroma_ac[16 + 162 + 2] = {
0109     /* bits */
0110     0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
0111     0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
0112     /* values */
0113     0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0114     0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0115     0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0116     0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0117     0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0118     0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0119     0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0120     0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0121     0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0122     0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0123     0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0124     0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0125     0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0126     0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0127     0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0128     0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0129     0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0130     0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0131     0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0132     0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0133     0xf9, 0xfa, /* padded to 32-bit */
0134 };
0135 
0136 /*
0137  * Quantization tables for luminance and chrominance components in
0138  * zig-zag scan order from the Freescale i.MX VPU libraries
0139  */
0140 
0141 static unsigned char luma_q[64] = {
0142     0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05,
0143     0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b,
0144     0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a, 0x0a,
0145     0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c,
0146     0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c,
0147     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0148     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0149     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0150 };
0151 
0152 static unsigned char chroma_q[64] = {
0153     0x07, 0x07, 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10,
0154     0x10, 0x18, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14,
0155     0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c,
0156     0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c,
0157     0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c,
0158     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0159     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0160     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0161 };
0162 
0163 static const unsigned char width_align[] = {
0164     [CODA9_JPEG_FORMAT_420] = 16,
0165     [CODA9_JPEG_FORMAT_422] = 16,
0166     [CODA9_JPEG_FORMAT_224] = 8,
0167     [CODA9_JPEG_FORMAT_444] = 8,
0168     [CODA9_JPEG_FORMAT_400] = 8,
0169 };
0170 
0171 static const unsigned char height_align[] = {
0172     [CODA9_JPEG_FORMAT_420] = 16,
0173     [CODA9_JPEG_FORMAT_422] = 8,
0174     [CODA9_JPEG_FORMAT_224] = 16,
0175     [CODA9_JPEG_FORMAT_444] = 8,
0176     [CODA9_JPEG_FORMAT_400] = 8,
0177 };
0178 
0179 static int coda9_jpeg_chroma_format(u32 pixfmt)
0180 {
0181     switch (pixfmt) {
0182     case V4L2_PIX_FMT_YUV420:
0183     case V4L2_PIX_FMT_NV12:
0184         return CODA9_JPEG_FORMAT_420;
0185     case V4L2_PIX_FMT_YUV422P:
0186         return CODA9_JPEG_FORMAT_422;
0187     case V4L2_PIX_FMT_YUV444:
0188         return CODA9_JPEG_FORMAT_444;
0189     case V4L2_PIX_FMT_GREY:
0190         return CODA9_JPEG_FORMAT_400;
0191     }
0192     return -EINVAL;
0193 }
0194 
0195 struct coda_memcpy_desc {
0196     int offset;
0197     const void *src;
0198     size_t len;
0199 };
0200 
0201 static void coda_memcpy_parabuf(void *parabuf,
0202                 const struct coda_memcpy_desc *desc)
0203 {
0204     u32 *dst = parabuf + desc->offset;
0205     const u32 *src = desc->src;
0206     int len = desc->len / 4;
0207     int i;
0208 
0209     for (i = 0; i < len; i += 2) {
0210         dst[i + 1] = swab32(src[i]);
0211         dst[i] = swab32(src[i + 1]);
0212     }
0213 }
0214 
0215 int coda_jpeg_write_tables(struct coda_ctx *ctx)
0216 {
0217     int i;
0218     static const struct coda_memcpy_desc huff[8] = {
0219         { 0,   luma_dc,    sizeof(luma_dc)    },
0220         { 32,  luma_ac,    sizeof(luma_ac)    },
0221         { 216, chroma_dc,  sizeof(chroma_dc)  },
0222         { 248, chroma_ac,  sizeof(chroma_ac)  },
0223     };
0224     struct coda_memcpy_desc qmat[3] = {
0225         { 512, ctx->params.jpeg_qmat_tab[0], 64 },
0226         { 576, ctx->params.jpeg_qmat_tab[1], 64 },
0227         { 640, ctx->params.jpeg_qmat_tab[1], 64 },
0228     };
0229 
0230     /* Write huffman tables to parameter memory */
0231     for (i = 0; i < ARRAY_SIZE(huff); i++)
0232         coda_memcpy_parabuf(ctx->parabuf.vaddr, huff + i);
0233 
0234     /* Write Q-matrix to parameter memory */
0235     for (i = 0; i < ARRAY_SIZE(qmat); i++)
0236         coda_memcpy_parabuf(ctx->parabuf.vaddr, qmat + i);
0237 
0238     return 0;
0239 }
0240 
0241 bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
0242 {
0243     void *vaddr = vb2_plane_vaddr(vb, 0);
0244     u16 soi, eoi;
0245     int len, i;
0246 
0247     soi = be16_to_cpup((__be16 *)vaddr);
0248     if (soi != SOI_MARKER)
0249         return false;
0250 
0251     len = vb2_get_plane_payload(vb, 0);
0252     vaddr += len - 2;
0253     for (i = 0; i < 32; i++) {
0254         eoi = be16_to_cpup((__be16 *)(vaddr - i));
0255         if (eoi == EOI_MARKER) {
0256             if (i > 0)
0257                 vb2_set_plane_payload(vb, 0, len - i);
0258             return true;
0259         }
0260     }
0261 
0262     return false;
0263 }
0264 
0265 static int coda9_jpeg_gen_dec_huff_tab(struct coda_ctx *ctx, int tab_num);
0266 
0267 int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb)
0268 {
0269     struct coda_dev *dev = ctx->dev;
0270     u8 *buf = vb2_plane_vaddr(vb, 0);
0271     size_t len = vb2_get_plane_payload(vb, 0);
0272     struct v4l2_jpeg_scan_header scan_header;
0273     struct v4l2_jpeg_reference quantization_tables[4] = { };
0274     struct v4l2_jpeg_reference huffman_tables[4] = { };
0275     struct v4l2_jpeg_header header = {
0276         .scan = &scan_header,
0277         .quantization_tables = quantization_tables,
0278         .huffman_tables = huffman_tables,
0279     };
0280     struct coda_q_data *q_data_src;
0281     struct coda_huff_tab *huff_tab;
0282     int i, j, ret;
0283 
0284     ret = v4l2_jpeg_parse_header(buf, len, &header);
0285     if (ret < 0) {
0286         v4l2_err(&dev->v4l2_dev, "failed to parse JPEG header: %pe\n",
0287              ERR_PTR(ret));
0288         return ret;
0289     }
0290 
0291     ctx->params.jpeg_restart_interval = header.restart_interval;
0292 
0293     /* check frame header */
0294     if (header.frame.height > ctx->codec->max_h ||
0295         header.frame.width > ctx->codec->max_w) {
0296         v4l2_err(&dev->v4l2_dev, "invalid dimensions: %dx%d\n",
0297              header.frame.width, header.frame.height);
0298         return -EINVAL;
0299     }
0300 
0301     q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
0302     if (header.frame.height != q_data_src->height ||
0303         header.frame.width != q_data_src->width) {
0304         v4l2_err(&dev->v4l2_dev,
0305              "dimensions don't match format: %dx%d\n",
0306              header.frame.width, header.frame.height);
0307         return -EINVAL;
0308     }
0309 
0310     if (header.frame.num_components != 3) {
0311         v4l2_err(&dev->v4l2_dev,
0312              "unsupported number of components: %d\n",
0313              header.frame.num_components);
0314         return -EINVAL;
0315     }
0316 
0317     /* install quantization tables */
0318     if (quantization_tables[3].start) {
0319         v4l2_err(&dev->v4l2_dev,
0320              "only 3 quantization tables supported\n");
0321         return -EINVAL;
0322     }
0323     for (i = 0; i < 3; i++) {
0324         if (!quantization_tables[i].start)
0325             continue;
0326         if (quantization_tables[i].length != 64) {
0327             v4l2_err(&dev->v4l2_dev,
0328                  "only 8-bit quantization tables supported\n");
0329             continue;
0330         }
0331         if (!ctx->params.jpeg_qmat_tab[i]) {
0332             ctx->params.jpeg_qmat_tab[i] = kmalloc(64, GFP_KERNEL);
0333             if (!ctx->params.jpeg_qmat_tab[i])
0334                 return -ENOMEM;
0335         }
0336         memcpy(ctx->params.jpeg_qmat_tab[i],
0337                quantization_tables[i].start, 64);
0338     }
0339 
0340     /* install Huffman tables */
0341     for (i = 0; i < 4; i++) {
0342         if (!huffman_tables[i].start) {
0343             v4l2_err(&dev->v4l2_dev, "missing Huffman table\n");
0344             return -EINVAL;
0345         }
0346         /* AC tables should be between 17 -> 178, DC between 17 -> 28 */
0347         if (huffman_tables[i].length < 17 ||
0348             huffman_tables[i].length > 178 ||
0349             ((i & 2) == 0 && huffman_tables[i].length > 28)) {
0350             v4l2_err(&dev->v4l2_dev,
0351                  "invalid Huffman table %d length: %zu\n",
0352                  i, huffman_tables[i].length);
0353             return -EINVAL;
0354         }
0355     }
0356     huff_tab = ctx->params.jpeg_huff_tab;
0357     if (!huff_tab) {
0358         huff_tab = kzalloc(sizeof(struct coda_huff_tab), GFP_KERNEL);
0359         if (!huff_tab)
0360             return -ENOMEM;
0361         ctx->params.jpeg_huff_tab = huff_tab;
0362     }
0363 
0364     memset(huff_tab, 0, sizeof(*huff_tab));
0365     memcpy(huff_tab->luma_dc, huffman_tables[0].start, huffman_tables[0].length);
0366     memcpy(huff_tab->chroma_dc, huffman_tables[1].start, huffman_tables[1].length);
0367     memcpy(huff_tab->luma_ac, huffman_tables[2].start, huffman_tables[2].length);
0368     memcpy(huff_tab->chroma_ac, huffman_tables[3].start, huffman_tables[3].length);
0369 
0370     /* check scan header */
0371     for (i = 0; i < scan_header.num_components; i++) {
0372         struct v4l2_jpeg_scan_component_spec *scan_component;
0373 
0374         scan_component = &scan_header.component[i];
0375         for (j = 0; j < header.frame.num_components; j++) {
0376             if (header.frame.component[j].component_identifier ==
0377                 scan_component->component_selector)
0378                 break;
0379         }
0380         if (j == header.frame.num_components)
0381             continue;
0382 
0383         ctx->params.jpeg_huff_dc_index[j] =
0384             scan_component->dc_entropy_coding_table_selector;
0385         ctx->params.jpeg_huff_ac_index[j] =
0386             scan_component->ac_entropy_coding_table_selector;
0387     }
0388 
0389     /* Generate Huffman table information */
0390     for (i = 0; i < 4; i++)
0391         coda9_jpeg_gen_dec_huff_tab(ctx, i);
0392 
0393     /* start of entropy coded segment */
0394     ctx->jpeg_ecs_offset = header.ecs_offset;
0395 
0396     switch (header.frame.subsampling) {
0397     case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
0398     case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
0399         ctx->params.jpeg_chroma_subsampling = header.frame.subsampling;
0400         break;
0401     default:
0402         v4l2_err(&dev->v4l2_dev, "chroma subsampling not supported: %d",
0403              header.frame.subsampling);
0404         return -EINVAL;
0405     }
0406 
0407     return 0;
0408 }
0409 
0410 static inline void coda9_jpeg_write_huff_values(struct coda_dev *dev, u8 *bits,
0411                         int num_values)
0412 {
0413     s8 *values = (s8 *)(bits + 16);
0414     int huff_length, i;
0415 
0416     for (huff_length = 0, i = 0; i < 16; i++)
0417         huff_length += bits[i];
0418     for (i = huff_length; i < num_values; i++)
0419         values[i] = -1;
0420     for (i = 0; i < num_values; i++)
0421         coda_write(dev, (s32)values[i], CODA9_REG_JPEG_HUFF_DATA);
0422 }
0423 
0424 static int coda9_jpeg_dec_huff_setup(struct coda_ctx *ctx)
0425 {
0426     struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab;
0427     struct coda_dev *dev = ctx->dev;
0428     s16 *huff_min = huff_tab->min;
0429     s16 *huff_max = huff_tab->max;
0430     s8 *huff_ptr = huff_tab->ptr;
0431     int i;
0432 
0433     /* MIN Tables */
0434     coda_write(dev, 0x003, CODA9_REG_JPEG_HUFF_CTRL);
0435     coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_ADDR);
0436     for (i = 0; i < 4 * 16; i++)
0437         coda_write(dev, (s32)huff_min[i], CODA9_REG_JPEG_HUFF_DATA);
0438 
0439     /* MAX Tables */
0440     coda_write(dev, 0x403, CODA9_REG_JPEG_HUFF_CTRL);
0441     coda_write(dev, 0x440, CODA9_REG_JPEG_HUFF_ADDR);
0442     for (i = 0; i < 4 * 16; i++)
0443         coda_write(dev, (s32)huff_max[i], CODA9_REG_JPEG_HUFF_DATA);
0444 
0445     /* PTR Tables */
0446     coda_write(dev, 0x803, CODA9_REG_JPEG_HUFF_CTRL);
0447     coda_write(dev, 0x880, CODA9_REG_JPEG_HUFF_ADDR);
0448     for (i = 0; i < 4 * 16; i++)
0449         coda_write(dev, (s32)huff_ptr[i], CODA9_REG_JPEG_HUFF_DATA);
0450 
0451     /* VAL Tables: DC Luma, DC Chroma, AC Luma, AC Chroma */
0452     coda_write(dev, 0xc03, CODA9_REG_JPEG_HUFF_CTRL);
0453     coda9_jpeg_write_huff_values(dev, huff_tab->luma_dc, 12);
0454     coda9_jpeg_write_huff_values(dev, huff_tab->chroma_dc, 12);
0455     coda9_jpeg_write_huff_values(dev, huff_tab->luma_ac, 162);
0456     coda9_jpeg_write_huff_values(dev, huff_tab->chroma_ac, 162);
0457     coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_CTRL);
0458     return 0;
0459 }
0460 
0461 static inline void coda9_jpeg_write_qmat_tab(struct coda_dev *dev,
0462                          u8 *qmat, int index)
0463 {
0464     int i;
0465 
0466     coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
0467     for (i = 0; i < 64; i++)
0468         coda_write(dev, qmat[i], CODA9_REG_JPEG_QMAT_DATA);
0469     coda_write(dev, 0, CODA9_REG_JPEG_QMAT_CTRL);
0470 }
0471 
0472 static void coda9_jpeg_qmat_setup(struct coda_ctx *ctx)
0473 {
0474     struct coda_dev *dev = ctx->dev;
0475     int *qmat_index = ctx->params.jpeg_qmat_index;
0476     u8 **qmat_tab = ctx->params.jpeg_qmat_tab;
0477 
0478     coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[0]], 0x00);
0479     coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[1]], 0x40);
0480     coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[2]], 0x80);
0481 }
0482 
0483 static void coda9_jpeg_dec_bbc_gbu_setup(struct coda_ctx *ctx,
0484                      struct vb2_buffer *buf, u32 ecs_offset)
0485 {
0486     struct coda_dev *dev = ctx->dev;
0487     int page_ptr, word_ptr, bit_ptr;
0488     u32 bbc_base_addr, end_addr;
0489     int bbc_cur_pos;
0490     int ret, val;
0491 
0492     bbc_base_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
0493     end_addr = bbc_base_addr + vb2_get_plane_payload(buf, 0);
0494 
0495     page_ptr = ecs_offset / 256;
0496     word_ptr = (ecs_offset % 256) / 4;
0497     if (page_ptr & 1)
0498         word_ptr += 64;
0499     bit_ptr = (ecs_offset % 4) * 8;
0500     if (word_ptr & 1)
0501         bit_ptr += 32;
0502     word_ptr &= ~0x1;
0503 
0504     coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_WR_PTR);
0505     coda_write(dev, bbc_base_addr, CODA9_REG_JPEG_BBC_BAS_ADDR);
0506 
0507     /* Leave 3 256-byte page margin to avoid a BBC interrupt */
0508     coda_write(dev, end_addr + 256 * 3 + 256, CODA9_REG_JPEG_BBC_END_ADDR);
0509     val = DIV_ROUND_UP(vb2_plane_size(buf, 0), 256) + 3;
0510     coda_write(dev, BIT(31) | val, CODA9_REG_JPEG_BBC_STRM_CTRL);
0511 
0512     bbc_cur_pos = page_ptr;
0513     coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
0514     coda_write(dev, bbc_base_addr + (bbc_cur_pos << 8),
0515             CODA9_REG_JPEG_BBC_EXT_ADDR);
0516     coda_write(dev, (bbc_cur_pos & 1) << 6, CODA9_REG_JPEG_BBC_INT_ADDR);
0517     coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
0518     coda_write(dev, 0, CODA9_REG_JPEG_BBC_COMMAND);
0519     do {
0520         ret = coda_read(dev, CODA9_REG_JPEG_BBC_BUSY);
0521     } while (ret == 1);
0522 
0523     bbc_cur_pos++;
0524     coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
0525     coda_write(dev, bbc_base_addr + (bbc_cur_pos << 8),
0526             CODA9_REG_JPEG_BBC_EXT_ADDR);
0527     coda_write(dev, (bbc_cur_pos & 1) << 6, CODA9_REG_JPEG_BBC_INT_ADDR);
0528     coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
0529     coda_write(dev, 0, CODA9_REG_JPEG_BBC_COMMAND);
0530     do {
0531         ret = coda_read(dev, CODA9_REG_JPEG_BBC_BUSY);
0532     } while (ret == 1);
0533 
0534     bbc_cur_pos++;
0535     coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
0536     coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
0537 
0538     coda_write(dev, 0, CODA9_REG_JPEG_GBU_TT_CNT);
0539     coda_write(dev, word_ptr, CODA9_REG_JPEG_GBU_WD_PTR);
0540     coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
0541     coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
0542     if (page_ptr & 1) {
0543         coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBIR);
0544         coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBHR);
0545     } else {
0546         coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
0547         coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
0548     }
0549     coda_write(dev, 4, CODA9_REG_JPEG_GBU_CTRL);
0550     coda_write(dev, bit_ptr, CODA9_REG_JPEG_GBU_FF_RPTR);
0551     coda_write(dev, 3, CODA9_REG_JPEG_GBU_CTRL);
0552 }
0553 
0554 static const int bus_req_num[] = {
0555     [CODA9_JPEG_FORMAT_420] = 2,
0556     [CODA9_JPEG_FORMAT_422] = 3,
0557     [CODA9_JPEG_FORMAT_224] = 3,
0558     [CODA9_JPEG_FORMAT_444] = 4,
0559     [CODA9_JPEG_FORMAT_400] = 4,
0560 };
0561 
0562 #define MCU_INFO(mcu_block_num, comp_num, comp0_info, comp1_info, comp2_info) \
0563     (((mcu_block_num) << CODA9_JPEG_MCU_BLOCK_NUM_OFFSET) | \
0564      ((comp_num) << CODA9_JPEG_COMP_NUM_OFFSET) | \
0565      ((comp0_info) << CODA9_JPEG_COMP0_INFO_OFFSET) | \
0566      ((comp1_info) << CODA9_JPEG_COMP1_INFO_OFFSET) | \
0567      ((comp2_info) << CODA9_JPEG_COMP2_INFO_OFFSET))
0568 
0569 static const u32 mcu_info[] = {
0570     [CODA9_JPEG_FORMAT_420] = MCU_INFO(6, 3, 10, 5, 5),
0571     [CODA9_JPEG_FORMAT_422] = MCU_INFO(4, 3, 9, 5, 5),
0572     [CODA9_JPEG_FORMAT_224] = MCU_INFO(4, 3, 6, 5, 5),
0573     [CODA9_JPEG_FORMAT_444] = MCU_INFO(3, 3, 5, 5, 5),
0574     [CODA9_JPEG_FORMAT_400] = MCU_INFO(1, 1, 5, 0, 0),
0575 };
0576 
0577 /*
0578  * Convert Huffman table specifcations to tables of codes and code lengths.
0579  * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
0580  *
0581  * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
0582  */
0583 static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num,
0584                        int *ehufsi, int *ehufco)
0585 {
0586     int i, j, k, lastk, si, code, maxsymbol;
0587     const u8 *bits, *huffval;
0588     struct {
0589         int size[256];
0590         int code[256];
0591     } *huff;
0592     static const unsigned char *huff_tabs[4] = {
0593         luma_dc, luma_ac, chroma_dc, chroma_ac,
0594     };
0595     int ret = -EINVAL;
0596 
0597     huff = kzalloc(sizeof(*huff), GFP_KERNEL);
0598     if (!huff)
0599         return -ENOMEM;
0600 
0601     bits = huff_tabs[tab_num];
0602     huffval = huff_tabs[tab_num] + 16;
0603 
0604     maxsymbol = tab_num & 1 ? 256 : 16;
0605 
0606     /* Figure C.1 - Generation of table of Huffman code sizes */
0607     k = 0;
0608     for (i = 1; i <= 16; i++) {
0609         j = bits[i - 1];
0610         if (k + j > maxsymbol)
0611             goto out;
0612         while (j--)
0613             huff->size[k++] = i;
0614     }
0615     lastk = k;
0616 
0617     /* Figure C.2 - Generation of table of Huffman codes */
0618     k = 0;
0619     code = 0;
0620     si = huff->size[0];
0621     while (k < lastk) {
0622         while (huff->size[k] == si) {
0623             huff->code[k++] = code;
0624             code++;
0625         }
0626         if (code >= (1 << si))
0627             goto out;
0628         code <<= 1;
0629         si++;
0630     }
0631 
0632     /* Figure C.3 - Ordering procedure for encoding procedure code tables */
0633     for (k = 0; k < lastk; k++) {
0634         i = huffval[k];
0635         if (i >= maxsymbol || ehufsi[i])
0636             goto out;
0637         ehufco[i] = huff->code[k];
0638         ehufsi[i] = huff->size[k];
0639     }
0640 
0641     ret = 0;
0642 out:
0643     kfree(huff);
0644     return ret;
0645 }
0646 
0647 #define DC_TABLE_INDEX0         0
0648 #define AC_TABLE_INDEX0         1
0649 #define DC_TABLE_INDEX1         2
0650 #define AC_TABLE_INDEX1         3
0651 
0652 static u8 *coda9_jpeg_get_huff_bits(struct coda_ctx *ctx, int tab_num)
0653 {
0654     struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab;
0655 
0656     if (!huff_tab)
0657         return NULL;
0658 
0659     switch (tab_num) {
0660     case DC_TABLE_INDEX0: return huff_tab->luma_dc;
0661     case AC_TABLE_INDEX0: return huff_tab->luma_ac;
0662     case DC_TABLE_INDEX1: return huff_tab->chroma_dc;
0663     case AC_TABLE_INDEX1: return huff_tab->chroma_ac;
0664     }
0665 
0666     return NULL;
0667 }
0668 
0669 static int coda9_jpeg_gen_dec_huff_tab(struct coda_ctx *ctx, int tab_num)
0670 {
0671     int ptr_cnt = 0, huff_code = 0, zero_flag = 0, data_flag = 0;
0672     u8 *huff_bits;
0673     s16 *huff_max;
0674     s16 *huff_min;
0675     s8 *huff_ptr;
0676     int ofs;
0677     int i;
0678 
0679     huff_bits = coda9_jpeg_get_huff_bits(ctx, tab_num);
0680     if (!huff_bits)
0681         return -EINVAL;
0682 
0683     /* DC/AC Luma, DC/AC Chroma -> DC Luma/Chroma, AC Luma/Chroma */
0684     ofs = ((tab_num & 1) << 1) | ((tab_num >> 1) & 1);
0685     ofs *= 16;
0686 
0687     huff_ptr = ctx->params.jpeg_huff_tab->ptr + ofs;
0688     huff_max = ctx->params.jpeg_huff_tab->max + ofs;
0689     huff_min = ctx->params.jpeg_huff_tab->min + ofs;
0690 
0691     for (i = 0; i < 16; i++) {
0692         if (huff_bits[i]) {
0693             huff_ptr[i] = ptr_cnt;
0694             ptr_cnt += huff_bits[i];
0695             huff_min[i] = huff_code;
0696             huff_max[i] = huff_code + (huff_bits[i] - 1);
0697             data_flag = 1;
0698             zero_flag = 0;
0699         } else {
0700             huff_ptr[i] = -1;
0701             huff_min[i] = -1;
0702             huff_max[i] = -1;
0703             zero_flag = 1;
0704         }
0705 
0706         if (data_flag == 1) {
0707             if (zero_flag == 1)
0708                 huff_code <<= 1;
0709             else
0710                 huff_code = (huff_max[i] + 1) << 1;
0711         }
0712     }
0713 
0714     return 0;
0715 }
0716 
0717 static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx)
0718 {
0719     struct {
0720         int size[4][256];
0721         int code[4][256];
0722     } *huff;
0723     u32 *huff_data;
0724     int i, j;
0725     int ret;
0726 
0727     huff = kzalloc(sizeof(*huff), GFP_KERNEL);
0728     if (!huff)
0729         return -ENOMEM;
0730 
0731     /* Generate all four (luma/chroma DC/AC) code/size lookup tables */
0732     for (i = 0; i < 4; i++) {
0733         ret = coda9_jpeg_gen_enc_huff_tab(ctx, i, huff->size[i],
0734                           huff->code[i]);
0735         if (ret)
0736             goto out;
0737     }
0738 
0739     if (!ctx->params.jpeg_huff_data) {
0740         ctx->params.jpeg_huff_data =
0741             kzalloc(sizeof(u32) * CODA9_JPEG_ENC_HUFF_DATA_SIZE,
0742                 GFP_KERNEL);
0743         if (!ctx->params.jpeg_huff_data) {
0744             ret = -ENOMEM;
0745             goto out;
0746         }
0747     }
0748     huff_data = ctx->params.jpeg_huff_data;
0749 
0750     for (j = 0; j < 4; j++) {
0751         /* Store Huffman lookup tables in AC0, AC1, DC0, DC1 order */
0752         int t = (j == 0) ? AC_TABLE_INDEX0 :
0753             (j == 1) ? AC_TABLE_INDEX1 :
0754             (j == 2) ? DC_TABLE_INDEX0 :
0755                    DC_TABLE_INDEX1;
0756         /* DC tables only have 16 entries */
0757         int len = (j < 2) ? 256 : 16;
0758 
0759         for (i = 0; i < len; i++) {
0760             if (huff->size[t][i] == 0 && huff->code[t][i] == 0)
0761                 *(huff_data++) = 0;
0762             else
0763                 *(huff_data++) =
0764                     ((huff->size[t][i] - 1) << 16) |
0765                     huff->code[t][i];
0766         }
0767     }
0768 
0769     ret = 0;
0770 out:
0771     kfree(huff);
0772     return ret;
0773 }
0774 
0775 static void coda9_jpeg_write_huff_tab(struct coda_ctx *ctx)
0776 {
0777     struct coda_dev *dev = ctx->dev;
0778     u32 *huff_data = ctx->params.jpeg_huff_data;
0779     int i;
0780 
0781     /* Write Huffman size/code lookup tables in AC0, AC1, DC0, DC1 order */
0782     coda_write(dev, 0x3, CODA9_REG_JPEG_HUFF_CTRL);
0783     for (i = 0; i < CODA9_JPEG_ENC_HUFF_DATA_SIZE; i++)
0784         coda_write(dev, *(huff_data++), CODA9_REG_JPEG_HUFF_DATA);
0785     coda_write(dev, 0x0, CODA9_REG_JPEG_HUFF_CTRL);
0786 }
0787 
0788 static inline void coda9_jpeg_write_qmat_quotients(struct coda_dev *dev,
0789                            u8 *qmat, int index)
0790 {
0791     int i;
0792 
0793     coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
0794     for (i = 0; i < 64; i++)
0795         coda_write(dev, 0x80000 / qmat[i], CODA9_REG_JPEG_QMAT_DATA);
0796     coda_write(dev, index, CODA9_REG_JPEG_QMAT_CTRL);
0797 }
0798 
0799 static void coda9_jpeg_load_qmat_tab(struct coda_ctx *ctx)
0800 {
0801     struct coda_dev *dev = ctx->dev;
0802     u8 *luma_tab;
0803     u8 *chroma_tab;
0804 
0805     luma_tab = ctx->params.jpeg_qmat_tab[0];
0806     if (!luma_tab)
0807         luma_tab = luma_q;
0808 
0809     chroma_tab = ctx->params.jpeg_qmat_tab[1];
0810     if (!chroma_tab)
0811         chroma_tab = chroma_q;
0812 
0813     coda9_jpeg_write_qmat_quotients(dev, luma_tab, 0x00);
0814     coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x40);
0815     coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x80);
0816 }
0817 
0818 struct coda_jpeg_stream {
0819     u8 *curr;
0820     u8 *end;
0821 };
0822 
0823 static inline int coda_jpeg_put_byte(u8 byte, struct coda_jpeg_stream *stream)
0824 {
0825     if (stream->curr >= stream->end)
0826         return -EINVAL;
0827 
0828     *stream->curr++ = byte;
0829 
0830     return 0;
0831 }
0832 
0833 static inline int coda_jpeg_put_word(u16 word, struct coda_jpeg_stream *stream)
0834 {
0835     if (stream->curr + sizeof(__be16) > stream->end)
0836         return -EINVAL;
0837 
0838     put_unaligned_be16(word, stream->curr);
0839     stream->curr += sizeof(__be16);
0840 
0841     return 0;
0842 }
0843 
0844 static int coda_jpeg_put_table(u16 marker, u8 index, const u8 *table,
0845                    size_t len, struct coda_jpeg_stream *stream)
0846 {
0847     int i, ret;
0848 
0849     ret = coda_jpeg_put_word(marker, stream);
0850     if (ret < 0)
0851         return ret;
0852     ret = coda_jpeg_put_word(3 + len, stream);
0853     if (ret < 0)
0854         return ret;
0855     ret = coda_jpeg_put_byte(index, stream);
0856     for (i = 0; i < len && ret == 0; i++)
0857         ret = coda_jpeg_put_byte(table[i], stream);
0858 
0859     return ret;
0860 }
0861 
0862 static int coda_jpeg_define_quantization_table(struct coda_ctx *ctx, u8 index,
0863                            struct coda_jpeg_stream *stream)
0864 {
0865     return coda_jpeg_put_table(DQT_MARKER, index,
0866                    ctx->params.jpeg_qmat_tab[index], 64,
0867                    stream);
0868 }
0869 
0870 static int coda_jpeg_define_huffman_table(u8 index, const u8 *table, size_t len,
0871                       struct coda_jpeg_stream *stream)
0872 {
0873     return coda_jpeg_put_table(DHT_MARKER, index, table, len, stream);
0874 }
0875 
0876 static int coda9_jpeg_encode_header(struct coda_ctx *ctx, int len, u8 *buf)
0877 {
0878     struct coda_jpeg_stream stream = { buf, buf + len };
0879     struct coda_q_data *q_data_src;
0880     int chroma_format, comp_num;
0881     int i, ret, pad;
0882 
0883     q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
0884     chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
0885     if (chroma_format < 0)
0886         return 0;
0887 
0888     /* Start Of Image */
0889     ret = coda_jpeg_put_word(SOI_MARKER, &stream);
0890     if (ret < 0)
0891         return ret;
0892 
0893     /* Define Restart Interval */
0894     if (ctx->params.jpeg_restart_interval) {
0895         ret = coda_jpeg_put_word(DRI_MARKER, &stream);
0896         if (ret < 0)
0897             return ret;
0898         ret = coda_jpeg_put_word(4, &stream);
0899         if (ret < 0)
0900             return ret;
0901         ret = coda_jpeg_put_word(ctx->params.jpeg_restart_interval,
0902                      &stream);
0903         if (ret < 0)
0904             return ret;
0905     }
0906 
0907     /* Define Quantization Tables */
0908     ret = coda_jpeg_define_quantization_table(ctx, 0x00, &stream);
0909     if (ret < 0)
0910         return ret;
0911     if (chroma_format != CODA9_JPEG_FORMAT_400) {
0912         ret = coda_jpeg_define_quantization_table(ctx, 0x01, &stream);
0913         if (ret < 0)
0914             return ret;
0915     }
0916 
0917     /* Define Huffman Tables */
0918     ret = coda_jpeg_define_huffman_table(0x00, luma_dc, 16 + 12, &stream);
0919     if (ret < 0)
0920         return ret;
0921     ret = coda_jpeg_define_huffman_table(0x10, luma_ac, 16 + 162, &stream);
0922     if (ret < 0)
0923         return ret;
0924     if (chroma_format != CODA9_JPEG_FORMAT_400) {
0925         ret = coda_jpeg_define_huffman_table(0x01, chroma_dc, 16 + 12,
0926                              &stream);
0927         if (ret < 0)
0928             return ret;
0929         ret = coda_jpeg_define_huffman_table(0x11, chroma_ac, 16 + 162,
0930                              &stream);
0931         if (ret < 0)
0932             return ret;
0933     }
0934 
0935     /* Start Of Frame */
0936     ret = coda_jpeg_put_word(SOF_MARKER, &stream);
0937     if (ret < 0)
0938         return ret;
0939     comp_num = (chroma_format == CODA9_JPEG_FORMAT_400) ? 1 : 3;
0940     ret = coda_jpeg_put_word(8 + comp_num * 3, &stream);
0941     if (ret < 0)
0942         return ret;
0943     ret = coda_jpeg_put_byte(0x08, &stream);
0944     if (ret < 0)
0945         return ret;
0946     ret = coda_jpeg_put_word(q_data_src->height, &stream);
0947     if (ret < 0)
0948         return ret;
0949     ret = coda_jpeg_put_word(q_data_src->width, &stream);
0950     if (ret < 0)
0951         return ret;
0952     ret = coda_jpeg_put_byte(comp_num, &stream);
0953     if (ret < 0)
0954         return ret;
0955     for (i = 0; i < comp_num; i++) {
0956         static unsigned char subsampling[5][3] = {
0957             [CODA9_JPEG_FORMAT_420] = { 0x22, 0x11, 0x11 },
0958             [CODA9_JPEG_FORMAT_422] = { 0x21, 0x11, 0x11 },
0959             [CODA9_JPEG_FORMAT_224] = { 0x12, 0x11, 0x11 },
0960             [CODA9_JPEG_FORMAT_444] = { 0x11, 0x11, 0x11 },
0961             [CODA9_JPEG_FORMAT_400] = { 0x11 },
0962         };
0963 
0964         /* Component identifier, matches SOS */
0965         ret = coda_jpeg_put_byte(i + 1, &stream);
0966         if (ret < 0)
0967             return ret;
0968         ret = coda_jpeg_put_byte(subsampling[chroma_format][i],
0969                      &stream);
0970         if (ret < 0)
0971             return ret;
0972         /* Chroma table index */
0973         ret = coda_jpeg_put_byte((i == 0) ? 0 : 1, &stream);
0974         if (ret < 0)
0975             return ret;
0976     }
0977 
0978     /* Pad to multiple of 8 bytes */
0979     pad = (stream.curr - buf) % 8;
0980     if (pad) {
0981         pad = 8 - pad;
0982         while (pad--) {
0983             ret = coda_jpeg_put_byte(0x00, &stream);
0984             if (ret < 0)
0985                 return ret;
0986         }
0987     }
0988 
0989     return stream.curr - buf;
0990 }
0991 
0992 /*
0993  * Scale quantization table using nonlinear scaling factor
0994  * u8 qtab[64], scale [50,190]
0995  */
0996 static void coda_scale_quant_table(u8 *q_tab, int scale)
0997 {
0998     unsigned int temp;
0999     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 
1011 void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality)
1012 {
1013     unsigned int scale;
1014 
1015     ctx->params.jpeg_quality = quality;
1016 
1017     /* Clip quality setting to [5,100] interval */
1018     if (quality > 100)
1019         quality = 100;
1020     if (quality < 5)
1021         quality = 5;
1022 
1023     /*
1024      * Non-linear scaling factor:
1025      * [5,50] -> [1000..100], [51,100] -> [98..0]
1026      */
1027     if (quality < 50)
1028         scale = 5000 / quality;
1029     else
1030         scale = 200 - 2 * quality;
1031 
1032     if (ctx->params.jpeg_qmat_tab[0]) {
1033         memcpy(ctx->params.jpeg_qmat_tab[0], luma_q, 64);
1034         coda_scale_quant_table(ctx->params.jpeg_qmat_tab[0], scale);
1035     }
1036     if (ctx->params.jpeg_qmat_tab[1]) {
1037         memcpy(ctx->params.jpeg_qmat_tab[1], chroma_q, 64);
1038         coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale);
1039     }
1040 }
1041 
1042 /*
1043  * Encoder context operations
1044  */
1045 
1046 static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
1047 {
1048     struct coda_dev *dev = ctx->dev;
1049     int ret;
1050 
1051     ret = coda9_jpeg_load_huff_tab(ctx);
1052     if (ret < 0) {
1053         v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
1054         return ret;
1055     }
1056     if (!ctx->params.jpeg_qmat_tab[0])
1057         ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
1058     if (!ctx->params.jpeg_qmat_tab[1])
1059         ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
1060     coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
1061 
1062     return 0;
1063 }
1064 
1065 static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
1066 {
1067     struct coda_q_data *q_data_src;
1068     struct vb2_v4l2_buffer *src_buf, *dst_buf;
1069     struct coda_dev *dev = ctx->dev;
1070     u32 start_addr, end_addr;
1071     u16 aligned_width, aligned_height;
1072     bool chroma_interleave;
1073     int chroma_format;
1074     int header_len;
1075     int ret;
1076     ktime_t timeout;
1077 
1078     src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1079     dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1080     q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1081 
1082     if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
1083         vb2_set_plane_payload(&src_buf->vb2_buf, 0,
1084                       vb2_plane_size(&src_buf->vb2_buf, 0));
1085 
1086     src_buf->sequence = ctx->osequence;
1087     dst_buf->sequence = ctx->osequence;
1088     ctx->osequence++;
1089 
1090     src_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1091     src_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
1092 
1093     coda_set_gdi_regs(ctx);
1094 
1095     start_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1096     end_addr = start_addr + vb2_plane_size(&dst_buf->vb2_buf, 0);
1097 
1098     chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
1099     if (chroma_format < 0)
1100         return chroma_format;
1101 
1102     /* Round image dimensions to multiple of MCU size */
1103     aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
1104     aligned_height = round_up(q_data_src->height,
1105                   height_align[chroma_format]);
1106     if (aligned_width != q_data_src->bytesperline) {
1107         v4l2_err(&dev->v4l2_dev, "wrong stride: %d instead of %d\n",
1108              aligned_width, q_data_src->bytesperline);
1109     }
1110 
1111     header_len =
1112         coda9_jpeg_encode_header(ctx,
1113                      vb2_plane_size(&dst_buf->vb2_buf, 0),
1114                      vb2_plane_vaddr(&dst_buf->vb2_buf, 0));
1115     if (header_len < 0)
1116         return header_len;
1117 
1118     coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_BAS_ADDR);
1119     coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_END_ADDR);
1120     coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_WR_PTR);
1121     coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_RD_PTR);
1122     coda_write(dev, 0, CODA9_REG_JPEG_BBC_CUR_POS);
1123     /* 64 words per 256-byte page */
1124     coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
1125     coda_write(dev, start_addr, CODA9_REG_JPEG_BBC_EXT_ADDR);
1126     coda_write(dev, 0, CODA9_REG_JPEG_BBC_INT_ADDR);
1127 
1128     coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
1129     coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
1130     coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
1131     coda_write(dev, BIT(31) | ((end_addr - start_addr - header_len) / 256),
1132            CODA9_REG_JPEG_BBC_STRM_CTRL);
1133     coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
1134     coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
1135     coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
1136     coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
1137     coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
1138 
1139     chroma_interleave = (q_data_src->fourcc == V4L2_PIX_FMT_NV12);
1140     coda_write(dev, CODA9_JPEG_PIC_CTRL_TC_DIRECTION |
1141            CODA9_JPEG_PIC_CTRL_ENCODER_EN, CODA9_REG_JPEG_PIC_CTRL);
1142     coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
1143     coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
1144     coda_write(dev, ctx->params.jpeg_restart_interval,
1145            CODA9_REG_JPEG_RST_INTVAL);
1146     coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
1147 
1148     coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
1149 
1150     coda9_jpeg_write_huff_tab(ctx);
1151     coda9_jpeg_load_qmat_tab(ctx);
1152 
1153     if (ctx->params.rot_mode & CODA_ROT_90) {
1154         aligned_width = aligned_height;
1155         aligned_height = q_data_src->bytesperline;
1156         if (chroma_format == CODA9_JPEG_FORMAT_422)
1157             chroma_format = CODA9_JPEG_FORMAT_224;
1158         else if (chroma_format == CODA9_JPEG_FORMAT_224)
1159             chroma_format = CODA9_JPEG_FORMAT_422;
1160     }
1161     /* These need to be multiples of MCU size */
1162     coda_write(dev, aligned_width << 16 | aligned_height,
1163            CODA9_REG_JPEG_PIC_SIZE);
1164     coda_write(dev, ctx->params.rot_mode ?
1165            (CODA_ROT_MIR_ENABLE | ctx->params.rot_mode) : 0,
1166            CODA9_REG_JPEG_ROT_INFO);
1167 
1168     coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
1169 
1170     coda_write(dev, 1, CODA9_GDI_CONTROL);
1171     timeout = ktime_add_us(ktime_get(), 100000);
1172     do {
1173         ret = coda_read(dev, CODA9_GDI_STATUS);
1174         if (ktime_compare(ktime_get(), timeout) > 0) {
1175             v4l2_err(&dev->v4l2_dev, "timeout waiting for GDI\n");
1176             return -ETIMEDOUT;
1177         }
1178     } while (!ret);
1179 
1180     coda_write(dev, (chroma_format << 17) | (chroma_interleave << 16) |
1181            q_data_src->bytesperline, CODA9_GDI_INFO_CONTROL);
1182     /* The content of this register seems to be irrelevant: */
1183     coda_write(dev, aligned_width << 16 | aligned_height,
1184            CODA9_GDI_INFO_PIC_SIZE);
1185 
1186     coda_write_base(ctx, q_data_src, src_buf, CODA9_GDI_INFO_BASE_Y);
1187 
1188     coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
1189     coda_write(dev, 0, CODA9_GDI_CONTROL);
1190     coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
1191 
1192     coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
1193     coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
1194 
1195     trace_coda_jpeg_run(ctx, src_buf);
1196 
1197     coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
1198 
1199     return 0;
1200 }
1201 
1202 static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
1203 {
1204     struct vb2_v4l2_buffer *src_buf, *dst_buf;
1205     struct coda_dev *dev = ctx->dev;
1206     u32 wr_ptr, start_ptr;
1207     u32 err_mb;
1208 
1209     if (ctx->aborting) {
1210         coda_write(ctx->dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
1211         return;
1212     }
1213 
1214     /*
1215      * Lock to make sure that an encoder stop command running in parallel
1216      * will either already have marked src_buf as last, or it will wake up
1217      * the capture queue after the buffers are returned.
1218      */
1219     mutex_lock(&ctx->wakeup_mutex);
1220     src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1221     dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1222 
1223     trace_coda_jpeg_done(ctx, dst_buf);
1224 
1225     /*
1226      * Set plane payload to the number of bytes written out
1227      * by the JPEG processing unit
1228      */
1229     start_ptr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1230     wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
1231     vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr);
1232 
1233     err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
1234     if (err_mb)
1235         coda_dbg(1, ctx, "ERRMB: 0x%x\n", err_mb);
1236 
1237     coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
1238 
1239     dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
1240     dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1241     dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
1242 
1243     v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
1244 
1245     v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1246     coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
1247                          VB2_BUF_STATE_DONE);
1248     mutex_unlock(&ctx->wakeup_mutex);
1249 
1250     coda_dbg(1, ctx, "job finished: encoded frame (%u)%s\n",
1251          dst_buf->sequence,
1252          (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
1253 
1254     /*
1255      * Reset JPEG processing unit after each encode run to work
1256      * around hangups when switching context between encoder and
1257      * decoder.
1258      */
1259     coda_hw_reset(ctx);
1260 }
1261 
1262 static void coda9_jpeg_encode_timeout(struct coda_ctx *ctx)
1263 {
1264     struct coda_dev *dev = ctx->dev;
1265     u32 end_addr, wr_ptr;
1266 
1267     /* Handle missing BBC overflow interrupt via timeout */
1268     end_addr = coda_read(dev, CODA9_REG_JPEG_BBC_END_ADDR);
1269     wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
1270     if (wr_ptr >= end_addr - 256) {
1271         v4l2_err(&dev->v4l2_dev, "JPEG too large for capture buffer\n");
1272         coda9_jpeg_finish_encode(ctx);
1273         return;
1274     }
1275 
1276     coda_hw_reset(ctx);
1277 }
1278 
1279 static void coda9_jpeg_release(struct coda_ctx *ctx)
1280 {
1281     int i;
1282 
1283     if (ctx->params.jpeg_qmat_tab[0] == luma_q)
1284         ctx->params.jpeg_qmat_tab[0] = NULL;
1285     if (ctx->params.jpeg_qmat_tab[1] == chroma_q)
1286         ctx->params.jpeg_qmat_tab[1] = NULL;
1287     for (i = 0; i < 3; i++)
1288         kfree(ctx->params.jpeg_qmat_tab[i]);
1289     kfree(ctx->params.jpeg_huff_data);
1290     kfree(ctx->params.jpeg_huff_tab);
1291 }
1292 
1293 const struct coda_context_ops coda9_jpeg_encode_ops = {
1294     .queue_init = coda_encoder_queue_init,
1295     .start_streaming = coda9_jpeg_start_encoding,
1296     .prepare_run = coda9_jpeg_prepare_encode,
1297     .finish_run = coda9_jpeg_finish_encode,
1298     .run_timeout = coda9_jpeg_encode_timeout,
1299     .release = coda9_jpeg_release,
1300 };
1301 
1302 /*
1303  * Decoder context operations
1304  */
1305 
1306 static int coda9_jpeg_start_decoding(struct coda_ctx *ctx)
1307 {
1308     ctx->params.jpeg_qmat_index[0] = 0;
1309     ctx->params.jpeg_qmat_index[1] = 1;
1310     ctx->params.jpeg_qmat_index[2] = 1;
1311     ctx->params.jpeg_qmat_tab[0] = luma_q;
1312     ctx->params.jpeg_qmat_tab[1] = chroma_q;
1313     /* nothing more to do here */
1314 
1315     /* TODO: we could already scan the first header to get the chroma
1316      * format.
1317      */
1318 
1319     return 0;
1320 }
1321 
1322 static int coda9_jpeg_prepare_decode(struct coda_ctx *ctx)
1323 {
1324     struct coda_dev *dev = ctx->dev;
1325     int aligned_width, aligned_height;
1326     int chroma_format;
1327     int ret;
1328     u32 val, dst_fourcc;
1329     struct coda_q_data *q_data_src, *q_data_dst;
1330     struct vb2_v4l2_buffer *src_buf, *dst_buf;
1331     int chroma_interleave;
1332     int scl_hor_mode, scl_ver_mode;
1333 
1334     src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1335     dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1336     q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1337     q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1338     dst_fourcc = q_data_dst->fourcc;
1339 
1340     scl_hor_mode = coda_jpeg_scale(q_data_src->width, q_data_dst->width);
1341     scl_ver_mode = coda_jpeg_scale(q_data_src->height, q_data_dst->height);
1342 
1343     if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
1344         vb2_set_plane_payload(&src_buf->vb2_buf, 0,
1345                       vb2_plane_size(&src_buf->vb2_buf, 0));
1346 
1347     chroma_format = coda9_jpeg_chroma_format(q_data_dst->fourcc);
1348     if (chroma_format < 0)
1349         return chroma_format;
1350 
1351     ret = coda_jpeg_decode_header(ctx, &src_buf->vb2_buf);
1352     if (ret < 0) {
1353         src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1354         dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1355         v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1356         v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1357 
1358         return ret;
1359     }
1360 
1361     /* Round image dimensions to multiple of MCU size */
1362     aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
1363     aligned_height = round_up(q_data_src->height, height_align[chroma_format]);
1364     if (aligned_width != q_data_dst->bytesperline) {
1365         v4l2_err(&dev->v4l2_dev, "stride mismatch: %d != %d\n",
1366              aligned_width, q_data_dst->bytesperline);
1367     }
1368 
1369     coda_set_gdi_regs(ctx);
1370 
1371     val = ctx->params.jpeg_huff_ac_index[0] << 12 |
1372           ctx->params.jpeg_huff_ac_index[1] << 11 |
1373           ctx->params.jpeg_huff_ac_index[2] << 10 |
1374           ctx->params.jpeg_huff_dc_index[0] << 9 |
1375           ctx->params.jpeg_huff_dc_index[1] << 8 |
1376           ctx->params.jpeg_huff_dc_index[2] << 7;
1377     if (ctx->params.jpeg_huff_tab)
1378         val |= CODA9_JPEG_PIC_CTRL_USER_HUFFMAN_EN;
1379     coda_write(dev, val, CODA9_REG_JPEG_PIC_CTRL);
1380 
1381     coda_write(dev, aligned_width << 16 | aligned_height,
1382             CODA9_REG_JPEG_PIC_SIZE);
1383 
1384     chroma_interleave = (dst_fourcc == V4L2_PIX_FMT_NV12);
1385     coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO);
1386     coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
1387     coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
1388     if (scl_hor_mode || scl_ver_mode)
1389         val = CODA9_JPEG_SCL_ENABLE | (scl_hor_mode << 2) | scl_ver_mode;
1390     else
1391         val = 0;
1392     coda_write(dev, val, CODA9_REG_JPEG_SCL_INFO);
1393     coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
1394     coda_write(dev, ctx->params.jpeg_restart_interval,
1395             CODA9_REG_JPEG_RST_INTVAL);
1396 
1397     if (ctx->params.jpeg_huff_tab) {
1398         ret = coda9_jpeg_dec_huff_setup(ctx);
1399         if (ret < 0) {
1400             v4l2_err(&dev->v4l2_dev,
1401                  "failed to set up Huffman tables: %d\n", ret);
1402             return ret;
1403         }
1404     }
1405 
1406     coda9_jpeg_qmat_setup(ctx);
1407 
1408     coda9_jpeg_dec_bbc_gbu_setup(ctx, &src_buf->vb2_buf,
1409                      ctx->jpeg_ecs_offset);
1410 
1411     coda_write(dev, 0, CODA9_REG_JPEG_RST_INDEX);
1412     coda_write(dev, 0, CODA9_REG_JPEG_RST_COUNT);
1413 
1414     coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_Y);
1415     coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_CB);
1416     coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_CR);
1417 
1418     coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO);
1419 
1420     coda_write(dev, 1, CODA9_GDI_CONTROL);
1421     do {
1422         ret = coda_read(dev, CODA9_GDI_STATUS);
1423     } while (!ret);
1424 
1425     val = (chroma_format << 17) | (chroma_interleave << 16) |
1426           q_data_dst->bytesperline;
1427     if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP)
1428         val |= 3 << 20;
1429     coda_write(dev, val, CODA9_GDI_INFO_CONTROL);
1430 
1431     coda_write(dev, aligned_width << 16 | aligned_height,
1432             CODA9_GDI_INFO_PIC_SIZE);
1433 
1434     coda_write_base(ctx, q_data_dst, dst_buf, CODA9_GDI_INFO_BASE_Y);
1435 
1436     coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
1437     coda_write(dev, 0, CODA9_GDI_CONTROL);
1438     coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
1439 
1440     trace_coda_jpeg_run(ctx, src_buf);
1441 
1442     coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
1443 
1444     return 0;
1445 }
1446 
1447 static void coda9_jpeg_finish_decode(struct coda_ctx *ctx)
1448 {
1449     struct coda_dev *dev = ctx->dev;
1450     struct vb2_v4l2_buffer *dst_buf, *src_buf;
1451     struct coda_q_data *q_data_dst;
1452     u32 err_mb;
1453 
1454     err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
1455     if (err_mb)
1456         v4l2_err(&dev->v4l2_dev, "ERRMB: 0x%x\n", err_mb);
1457 
1458     coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
1459 
1460     /*
1461      * Lock to make sure that a decoder stop command running in parallel
1462      * will either already have marked src_buf as last, or it will wake up
1463      * the capture queue after the buffers are returned.
1464      */
1465     mutex_lock(&ctx->wakeup_mutex);
1466     src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1467     dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1468     dst_buf->sequence = ctx->osequence++;
1469 
1470     trace_coda_jpeg_done(ctx, dst_buf);
1471 
1472     dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
1473     dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1474     dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
1475 
1476     v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
1477 
1478     q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1479     vb2_set_plane_payload(&dst_buf->vb2_buf, 0, q_data_dst->sizeimage);
1480 
1481     v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1482     coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
1483                          VB2_BUF_STATE_DONE);
1484 
1485     mutex_unlock(&ctx->wakeup_mutex);
1486 
1487     coda_dbg(1, ctx, "job finished: decoded frame (%u)%s\n",
1488          dst_buf->sequence,
1489          (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
1490 
1491     /*
1492      * Reset JPEG processing unit after each decode run to work
1493      * around hangups when switching context between encoder and
1494      * decoder.
1495      */
1496     coda_hw_reset(ctx);
1497 }
1498 
1499 const struct coda_context_ops coda9_jpeg_decode_ops = {
1500     .queue_init = coda_encoder_queue_init, /* non-bitstream operation */
1501     .start_streaming = coda9_jpeg_start_decoding,
1502     .prepare_run = coda9_jpeg_prepare_decode,
1503     .finish_run = coda9_jpeg_finish_decode,
1504     .release = coda9_jpeg_release,
1505 };
1506 
1507 irqreturn_t coda9_jpeg_irq_handler(int irq, void *data)
1508 {
1509     struct coda_dev *dev = data;
1510     struct coda_ctx *ctx;
1511     int status;
1512     int err_mb;
1513 
1514     status = coda_read(dev, CODA9_REG_JPEG_PIC_STATUS);
1515     if (status == 0)
1516         return IRQ_HANDLED;
1517     coda_write(dev, status, CODA9_REG_JPEG_PIC_STATUS);
1518 
1519     if (status & CODA9_JPEG_STATUS_OVERFLOW)
1520         v4l2_err(&dev->v4l2_dev, "JPEG overflow\n");
1521 
1522     if (status & CODA9_JPEG_STATUS_BBC_INT)
1523         v4l2_err(&dev->v4l2_dev, "JPEG BBC interrupt\n");
1524 
1525     if (status & CODA9_JPEG_STATUS_ERROR) {
1526         v4l2_err(&dev->v4l2_dev, "JPEG error\n");
1527 
1528         err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
1529         if (err_mb) {
1530             v4l2_err(&dev->v4l2_dev,
1531                  "ERRMB: 0x%x: rst idx %d, mcu pos (%d,%d)\n",
1532                  err_mb, err_mb >> 24, (err_mb >> 12) & 0xfff,
1533                  err_mb & 0xfff);
1534         }
1535     }
1536 
1537     ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
1538     if (!ctx) {
1539         v4l2_err(&dev->v4l2_dev,
1540              "Instance released before the end of transaction\n");
1541         mutex_unlock(&dev->coda_mutex);
1542         return IRQ_HANDLED;
1543     }
1544 
1545     complete(&ctx->completion);
1546 
1547     return IRQ_HANDLED;
1548 }