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

jpeg-core.c (85532B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* linux/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
      3 *
      4 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
      5 *		http://www.samsung.com
      6 *
      7 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
      8 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
      9 */
     10
     11#include <linux/clk.h>
     12#include <linux/err.h>
     13#include <linux/gfp.h>
     14#include <linux/interrupt.h>
     15#include <linux/io.h>
     16#include <linux/kernel.h>
     17#include <linux/module.h>
     18#include <linux/of.h>
     19#include <linux/platform_device.h>
     20#include <linux/pm_runtime.h>
     21#include <linux/slab.h>
     22#include <linux/spinlock.h>
     23#include <linux/string.h>
     24#include <media/v4l2-event.h>
     25#include <media/v4l2-mem2mem.h>
     26#include <media/v4l2-ioctl.h>
     27#include <media/v4l2-rect.h>
     28#include <media/videobuf2-v4l2.h>
     29#include <media/videobuf2-dma-contig.h>
     30
     31#include "jpeg-core.h"
     32#include "jpeg-hw-s5p.h"
     33#include "jpeg-hw-exynos4.h"
     34#include "jpeg-hw-exynos3250.h"
     35#include "jpeg-regs.h"
     36
     37static struct s5p_jpeg_fmt sjpeg_formats[] = {
     38	{
     39		.fourcc		= V4L2_PIX_FMT_JPEG,
     40		.flags		= SJPEG_FMT_FLAG_ENC_CAPTURE |
     41				  SJPEG_FMT_FLAG_DEC_OUTPUT |
     42				  SJPEG_FMT_FLAG_S5P |
     43				  SJPEG_FMT_FLAG_EXYNOS3250 |
     44				  SJPEG_FMT_FLAG_EXYNOS4,
     45	},
     46	{
     47		.fourcc		= V4L2_PIX_FMT_YUYV,
     48		.depth		= 16,
     49		.colplanes	= 1,
     50		.h_align	= 4,
     51		.v_align	= 3,
     52		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
     53				  SJPEG_FMT_FLAG_DEC_CAPTURE |
     54				  SJPEG_FMT_FLAG_S5P |
     55				  SJPEG_FMT_NON_RGB,
     56		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
     57	},
     58	{
     59		.fourcc		= V4L2_PIX_FMT_YUYV,
     60		.depth		= 16,
     61		.colplanes	= 1,
     62		.h_align	= 1,
     63		.v_align	= 0,
     64		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
     65				  SJPEG_FMT_FLAG_DEC_CAPTURE |
     66				  SJPEG_FMT_FLAG_EXYNOS4 |
     67				  SJPEG_FMT_NON_RGB,
     68		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
     69	},
     70	{
     71		.fourcc		= V4L2_PIX_FMT_YUYV,
     72		.depth		= 16,
     73		.colplanes	= 1,
     74		.h_align	= 2,
     75		.v_align	= 0,
     76		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
     77				  SJPEG_FMT_FLAG_DEC_CAPTURE |
     78				  SJPEG_FMT_FLAG_EXYNOS3250 |
     79				  SJPEG_FMT_NON_RGB,
     80		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
     81	},
     82	{
     83		.fourcc		= V4L2_PIX_FMT_YVYU,
     84		.depth		= 16,
     85		.colplanes	= 1,
     86		.h_align	= 1,
     87		.v_align	= 0,
     88		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
     89				  SJPEG_FMT_FLAG_DEC_CAPTURE |
     90				  SJPEG_FMT_FLAG_EXYNOS4 |
     91				  SJPEG_FMT_NON_RGB,
     92		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
     93	},
     94	{
     95		.fourcc		= V4L2_PIX_FMT_YVYU,
     96		.depth		= 16,
     97		.colplanes	= 1,
     98		.h_align	= 2,
     99		.v_align	= 0,
    100		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    101				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    102				  SJPEG_FMT_FLAG_EXYNOS3250 |
    103				  SJPEG_FMT_NON_RGB,
    104		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    105	},
    106	{
    107		.fourcc		= V4L2_PIX_FMT_UYVY,
    108		.depth		= 16,
    109		.colplanes	= 1,
    110		.h_align	= 2,
    111		.v_align	= 0,
    112		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    113				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    114				  SJPEG_FMT_FLAG_EXYNOS3250 |
    115				  SJPEG_FMT_NON_RGB,
    116		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    117	},
    118	{
    119		.fourcc		= V4L2_PIX_FMT_VYUY,
    120		.depth		= 16,
    121		.colplanes	= 1,
    122		.h_align	= 2,
    123		.v_align	= 0,
    124		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    125				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    126				  SJPEG_FMT_FLAG_EXYNOS3250 |
    127				  SJPEG_FMT_NON_RGB,
    128		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    129	},
    130	{
    131		.fourcc		= V4L2_PIX_FMT_RGB565,
    132		.depth		= 16,
    133		.colplanes	= 1,
    134		.h_align	= 0,
    135		.v_align	= 0,
    136		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    137				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    138				  SJPEG_FMT_FLAG_EXYNOS4 |
    139				  SJPEG_FMT_RGB,
    140		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    141	},
    142	{
    143		.fourcc		= V4L2_PIX_FMT_RGB565,
    144		.depth		= 16,
    145		.colplanes	= 1,
    146		.h_align	= 2,
    147		.v_align	= 0,
    148		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    149				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    150				  SJPEG_FMT_FLAG_EXYNOS3250 |
    151				  SJPEG_FMT_RGB,
    152		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    153	},
    154	{
    155		.fourcc		= V4L2_PIX_FMT_RGB565X,
    156		.depth		= 16,
    157		.colplanes	= 1,
    158		.h_align	= 2,
    159		.v_align	= 0,
    160		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    161				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    162				  SJPEG_FMT_FLAG_EXYNOS3250 |
    163				  SJPEG_FMT_RGB,
    164		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    165	},
    166	{
    167		.fourcc		= V4L2_PIX_FMT_RGB565,
    168		.depth		= 16,
    169		.colplanes	= 1,
    170		.h_align	= 0,
    171		.v_align	= 0,
    172		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    173				  SJPEG_FMT_FLAG_S5P |
    174				  SJPEG_FMT_RGB,
    175		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    176	},
    177	{
    178		.fourcc		= V4L2_PIX_FMT_RGB32,
    179		.depth		= 32,
    180		.colplanes	= 1,
    181		.h_align	= 0,
    182		.v_align	= 0,
    183		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    184				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    185				  SJPEG_FMT_FLAG_EXYNOS4 |
    186				  SJPEG_FMT_RGB,
    187		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    188	},
    189	{
    190		.fourcc		= V4L2_PIX_FMT_RGB32,
    191		.depth		= 32,
    192		.colplanes	= 1,
    193		.h_align	= 2,
    194		.v_align	= 0,
    195		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    196				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    197				  SJPEG_FMT_FLAG_EXYNOS3250 |
    198				  SJPEG_FMT_RGB,
    199		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    200	},
    201	{
    202		.fourcc		= V4L2_PIX_FMT_NV24,
    203		.depth		= 24,
    204		.colplanes	= 2,
    205		.h_align	= 0,
    206		.v_align	= 0,
    207		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    208				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    209				  SJPEG_FMT_FLAG_EXYNOS4 |
    210				  SJPEG_FMT_NON_RGB,
    211		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    212	},
    213	{
    214		.fourcc		= V4L2_PIX_FMT_NV42,
    215		.depth		= 24,
    216		.colplanes	= 2,
    217		.h_align	= 0,
    218		.v_align	= 0,
    219		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    220				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    221				  SJPEG_FMT_FLAG_EXYNOS4 |
    222				  SJPEG_FMT_NON_RGB,
    223		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    224	},
    225	{
    226		.fourcc		= V4L2_PIX_FMT_NV61,
    227		.depth		= 16,
    228		.colplanes	= 2,
    229		.h_align	= 1,
    230		.v_align	= 0,
    231		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    232				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    233				  SJPEG_FMT_FLAG_EXYNOS4 |
    234				  SJPEG_FMT_NON_RGB,
    235		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    236	},
    237	{
    238		.fourcc		= V4L2_PIX_FMT_NV16,
    239		.depth		= 16,
    240		.colplanes	= 2,
    241		.h_align	= 1,
    242		.v_align	= 0,
    243		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    244				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    245				  SJPEG_FMT_FLAG_EXYNOS4 |
    246				  SJPEG_FMT_NON_RGB,
    247		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    248	},
    249	{
    250		.fourcc		= V4L2_PIX_FMT_NV12,
    251		.depth		= 12,
    252		.colplanes	= 2,
    253		.h_align	= 1,
    254		.v_align	= 1,
    255		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    256				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    257				  SJPEG_FMT_FLAG_EXYNOS4 |
    258				  SJPEG_FMT_NON_RGB,
    259		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    260	},
    261	{
    262		.fourcc		= V4L2_PIX_FMT_NV12,
    263		.depth		= 12,
    264		.colplanes	= 2,
    265		.h_align	= 3,
    266		.v_align	= 3,
    267		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    268				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    269				  SJPEG_FMT_FLAG_EXYNOS3250 |
    270				  SJPEG_FMT_NON_RGB,
    271		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    272	},
    273	{
    274		.fourcc		= V4L2_PIX_FMT_NV12,
    275		.depth		= 12,
    276		.colplanes	= 2,
    277		.h_align	= 4,
    278		.v_align	= 4,
    279		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    280				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    281				  SJPEG_FMT_FLAG_S5P |
    282				  SJPEG_FMT_NON_RGB,
    283		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    284	},
    285	{
    286		.fourcc		= V4L2_PIX_FMT_NV21,
    287		.depth		= 12,
    288		.colplanes	= 2,
    289		.h_align	= 3,
    290		.v_align	= 3,
    291		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    292				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    293				  SJPEG_FMT_FLAG_EXYNOS3250 |
    294				  SJPEG_FMT_NON_RGB,
    295		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    296	},
    297	{
    298		.fourcc		= V4L2_PIX_FMT_NV21,
    299		.depth		= 12,
    300		.colplanes	= 2,
    301		.h_align	= 1,
    302		.v_align	= 1,
    303		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    304				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    305				  SJPEG_FMT_FLAG_EXYNOS3250 |
    306				  SJPEG_FMT_FLAG_EXYNOS4 |
    307				  SJPEG_FMT_NON_RGB,
    308		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    309	},
    310	{
    311		.fourcc		= V4L2_PIX_FMT_YUV420,
    312		.depth		= 12,
    313		.colplanes	= 3,
    314		.h_align	= 1,
    315		.v_align	= 1,
    316		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    317				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    318				  SJPEG_FMT_FLAG_EXYNOS4 |
    319				  SJPEG_FMT_NON_RGB,
    320		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    321	},
    322	{
    323		.fourcc		= V4L2_PIX_FMT_YUV420,
    324		.depth		= 12,
    325		.colplanes	= 3,
    326		.h_align	= 4,
    327		.v_align	= 4,
    328		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    329				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    330				  SJPEG_FMT_FLAG_EXYNOS3250 |
    331				  SJPEG_FMT_NON_RGB,
    332		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    333	},
    334	{
    335		.fourcc		= V4L2_PIX_FMT_GREY,
    336		.depth		= 8,
    337		.colplanes	= 1,
    338		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
    339				  SJPEG_FMT_FLAG_DEC_CAPTURE |
    340				  SJPEG_FMT_FLAG_EXYNOS4 |
    341				  SJPEG_FMT_NON_RGB,
    342		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
    343	},
    344};
    345#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
    346
    347static const unsigned char qtbl_luminance[4][64] = {
    348	{/*level 0 - high compression quality */
    349		20, 16, 25, 39, 50, 46, 62, 68,
    350		16, 18, 23, 38, 38, 53, 65, 68,
    351		25, 23, 31, 38, 53, 65, 68, 68,
    352		39, 38, 38, 53, 65, 68, 68, 68,
    353		50, 38, 53, 65, 68, 68, 68, 68,
    354		46, 53, 65, 68, 68, 68, 68, 68,
    355		62, 65, 68, 68, 68, 68, 68, 68,
    356		68, 68, 68, 68, 68, 68, 68, 68
    357	},
    358	{/* level 1 */
    359		16, 11, 11, 16, 23, 27, 31, 30,
    360		11, 12, 12, 15, 20, 23, 23, 30,
    361		11, 12, 13, 16, 23, 26, 35, 47,
    362		16, 15, 16, 23, 26, 37, 47, 64,
    363		23, 20, 23, 26, 39, 51, 64, 64,
    364		27, 23, 26, 37, 51, 64, 64, 64,
    365		31, 23, 35, 47, 64, 64, 64, 64,
    366		30, 30, 47, 64, 64, 64, 64, 64
    367	},
    368	{/* level 2 */
    369		12,  8,  8, 12, 17, 21, 24, 23,
    370		 8,  9,  9, 11, 15, 19, 18, 23,
    371		 8,  9, 10, 12, 19, 20, 27, 36,
    372		12, 11, 12, 21, 20, 28, 36, 53,
    373		17, 15, 19, 20, 30, 39, 51, 59,
    374		21, 19, 20, 28, 39, 51, 59, 59,
    375		24, 18, 27, 36, 51, 59, 59, 59,
    376		23, 23, 36, 53, 59, 59, 59, 59
    377	},
    378	{/* level 3 - low compression quality */
    379		 8,  6,  6,  8, 12, 14, 16, 17,
    380		 6,  6,  6,  8, 10, 13, 12, 15,
    381		 6,  6,  7,  8, 13, 14, 18, 24,
    382		 8,  8,  8, 14, 13, 19, 24, 35,
    383		12, 10, 13, 13, 20, 26, 34, 39,
    384		14, 13, 14, 19, 26, 34, 39, 39,
    385		16, 12, 18, 24, 34, 39, 39, 39,
    386		17, 15, 24, 35, 39, 39, 39, 39
    387	}
    388};
    389
    390static const unsigned char qtbl_chrominance[4][64] = {
    391	{/*level 0 - high compression quality */
    392		21, 25, 32, 38, 54, 68, 68, 68,
    393		25, 28, 24, 38, 54, 68, 68, 68,
    394		32, 24, 32, 43, 66, 68, 68, 68,
    395		38, 38, 43, 53, 68, 68, 68, 68,
    396		54, 54, 66, 68, 68, 68, 68, 68,
    397		68, 68, 68, 68, 68, 68, 68, 68,
    398		68, 68, 68, 68, 68, 68, 68, 68,
    399		68, 68, 68, 68, 68, 68, 68, 68
    400	},
    401	{/* level 1 */
    402		17, 15, 17, 21, 20, 26, 38, 48,
    403		15, 19, 18, 17, 20, 26, 35, 43,
    404		17, 18, 20, 22, 26, 30, 46, 53,
    405		21, 17, 22, 28, 30, 39, 53, 64,
    406		20, 20, 26, 30, 39, 48, 64, 64,
    407		26, 26, 30, 39, 48, 63, 64, 64,
    408		38, 35, 46, 53, 64, 64, 64, 64,
    409		48, 43, 53, 64, 64, 64, 64, 64
    410	},
    411	{/* level 2 */
    412		13, 11, 13, 16, 20, 20, 29, 37,
    413		11, 14, 14, 14, 16, 20, 26, 32,
    414		13, 14, 15, 17, 20, 23, 35, 40,
    415		16, 14, 17, 21, 23, 30, 40, 50,
    416		20, 16, 20, 23, 30, 37, 50, 59,
    417		20, 20, 23, 30, 37, 48, 59, 59,
    418		29, 26, 35, 40, 50, 59, 59, 59,
    419		37, 32, 40, 50, 59, 59, 59, 59
    420	},
    421	{/* level 3 - low compression quality */
    422		 9,  8,  9, 11, 14, 17, 19, 24,
    423		 8, 10,  9, 11, 14, 13, 17, 22,
    424		 9,  9, 13, 14, 13, 15, 23, 26,
    425		11, 11, 14, 14, 15, 20, 26, 33,
    426		14, 14, 13, 15, 20, 24, 33, 39,
    427		17, 13, 15, 20, 24, 32, 39, 39,
    428		19, 17, 23, 26, 33, 39, 39, 39,
    429		24, 22, 26, 33, 39, 39, 39, 39
    430	}
    431};
    432
    433static const unsigned char hdctbl0[16] = {
    434	0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
    435};
    436
    437static const unsigned char hdctblg0[12] = {
    438	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
    439};
    440static const unsigned char hactbl0[16] = {
    441	0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
    442};
    443static const unsigned char hactblg0[162] = {
    444	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
    445	0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
    446	0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
    447	0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
    448	0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
    449	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
    450	0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
    451	0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
    452	0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
    453	0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
    454	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
    455	0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
    456	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
    457	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    458	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
    459	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
    460	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
    461	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
    462	0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
    463	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
    464	0xf9, 0xfa
    465};
    466
    467/*
    468 * Fourcc downgrade schema lookup tables for 422 and 420
    469 * chroma subsampling - fourcc on each position maps on the
    470 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
    471 * to get the most suitable fourcc counterpart for the given
    472 * downgraded subsampling property.
    473 */
    474static const u32 subs422_fourcc_dwngrd_schema[] = {
    475	V4L2_PIX_FMT_NV16,
    476	V4L2_PIX_FMT_NV61,
    477};
    478
    479static const u32 subs420_fourcc_dwngrd_schema[] = {
    480	V4L2_PIX_FMT_NV12,
    481	V4L2_PIX_FMT_NV21,
    482	V4L2_PIX_FMT_NV12,
    483	V4L2_PIX_FMT_NV21,
    484	V4L2_PIX_FMT_NV12,
    485	V4L2_PIX_FMT_NV21,
    486	V4L2_PIX_FMT_GREY,
    487	V4L2_PIX_FMT_GREY,
    488	V4L2_PIX_FMT_GREY,
    489	V4L2_PIX_FMT_GREY,
    490};
    491
    492/*
    493 * Lookup table for translation of a fourcc to the position
    494 * of its downgraded counterpart in the *fourcc_dwngrd_schema
    495 * tables.
    496 */
    497static const u32 fourcc_to_dwngrd_schema_id[] = {
    498	V4L2_PIX_FMT_NV24,
    499	V4L2_PIX_FMT_NV42,
    500	V4L2_PIX_FMT_NV16,
    501	V4L2_PIX_FMT_NV61,
    502	V4L2_PIX_FMT_YUYV,
    503	V4L2_PIX_FMT_YVYU,
    504	V4L2_PIX_FMT_NV12,
    505	V4L2_PIX_FMT_NV21,
    506	V4L2_PIX_FMT_YUV420,
    507	V4L2_PIX_FMT_GREY,
    508};
    509
    510static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
    511{
    512	int i;
    513
    514	for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
    515		if (fourcc_to_dwngrd_schema_id[i] == fourcc)
    516			return i;
    517	}
    518
    519	return -EINVAL;
    520}
    521
    522static int s5p_jpeg_adjust_fourcc_to_subsampling(
    523					enum v4l2_jpeg_chroma_subsampling subs,
    524					u32 in_fourcc,
    525					u32 *out_fourcc,
    526					struct s5p_jpeg_ctx *ctx)
    527{
    528	int dwngrd_sch_id;
    529
    530	if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
    531		dwngrd_sch_id =
    532			s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
    533		if (dwngrd_sch_id < 0)
    534			return -EINVAL;
    535	}
    536
    537	switch (ctx->subsampling) {
    538	case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
    539		*out_fourcc = V4L2_PIX_FMT_GREY;
    540		break;
    541	case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
    542		if (dwngrd_sch_id >
    543				ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
    544			return -EINVAL;
    545		*out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
    546		break;
    547	case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
    548		if (dwngrd_sch_id >
    549				ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
    550			return -EINVAL;
    551		*out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
    552		break;
    553	default:
    554		*out_fourcc = V4L2_PIX_FMT_GREY;
    555		break;
    556	}
    557
    558	return 0;
    559}
    560
    561static int exynos4x12_decoded_subsampling[] = {
    562	V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
    563	V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    564	V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    565	V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    566};
    567
    568static int exynos3250_decoded_subsampling[] = {
    569	V4L2_JPEG_CHROMA_SUBSAMPLING_444,
    570	V4L2_JPEG_CHROMA_SUBSAMPLING_422,
    571	V4L2_JPEG_CHROMA_SUBSAMPLING_420,
    572	V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
    573	-1,
    574	-1,
    575	V4L2_JPEG_CHROMA_SUBSAMPLING_411,
    576};
    577
    578static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
    579{
    580	return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
    581}
    582
    583static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
    584{
    585	return container_of(fh, struct s5p_jpeg_ctx, fh);
    586}
    587
    588static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
    589{
    590	switch (ctx->jpeg->variant->version) {
    591	case SJPEG_S5P:
    592		WARN_ON(ctx->subsampling > 3);
    593		if (ctx->subsampling > 2)
    594			return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
    595		return ctx->subsampling;
    596	case SJPEG_EXYNOS3250:
    597	case SJPEG_EXYNOS5420:
    598		WARN_ON(ctx->subsampling > 6);
    599		if (ctx->subsampling > 3)
    600			return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
    601		return exynos3250_decoded_subsampling[ctx->subsampling];
    602	case SJPEG_EXYNOS4:
    603		WARN_ON(ctx->subsampling > 3);
    604		if (ctx->subsampling > 2)
    605			return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
    606		return exynos4x12_decoded_subsampling[ctx->subsampling];
    607	case SJPEG_EXYNOS5433:
    608		return ctx->subsampling; /* parsed from header */
    609	default:
    610		WARN_ON(ctx->subsampling > 3);
    611		return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
    612	}
    613}
    614
    615static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
    616				     const unsigned char *qtbl,
    617				     unsigned long tab, int len)
    618{
    619	int i;
    620
    621	for (i = 0; i < len; i++)
    622		writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
    623}
    624
    625static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
    626{
    627	/* this driver fills quantisation table 0 with data for luma */
    628	s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
    629			  S5P_JPG_QTBL_CONTENT(0),
    630			  ARRAY_SIZE(qtbl_luminance[quality]));
    631}
    632
    633static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
    634{
    635	/* this driver fills quantisation table 1 with data for chroma */
    636	s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
    637			  S5P_JPG_QTBL_CONTENT(1),
    638			  ARRAY_SIZE(qtbl_chrominance[quality]));
    639}
    640
    641static inline void s5p_jpeg_set_htbl(void __iomem *regs,
    642				     const unsigned char *htbl,
    643				     unsigned long tab, int len)
    644{
    645	int i;
    646
    647	for (i = 0; i < len; i++)
    648		writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
    649}
    650
    651static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
    652{
    653	/* this driver fills table 0 for this component */
    654	s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
    655						ARRAY_SIZE(hdctbl0));
    656}
    657
    658static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
    659{
    660	/* this driver fills table 0 for this component */
    661	s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
    662						ARRAY_SIZE(hdctblg0));
    663}
    664
    665static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
    666{
    667	/* this driver fills table 0 for this component */
    668	s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
    669						ARRAY_SIZE(hactbl0));
    670}
    671
    672static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
    673{
    674	/* this driver fills table 0 for this component */
    675	s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
    676						ARRAY_SIZE(hactblg0));
    677}
    678
    679static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
    680					const unsigned char *tbl,
    681					unsigned long tab, int len)
    682{
    683	int i;
    684	unsigned int dword;
    685
    686	for (i = 0; i < len; i += 4) {
    687		dword = tbl[i] |
    688			(tbl[i + 1] << 8) |
    689			(tbl[i + 2] << 16) |
    690			(tbl[i + 3] << 24);
    691		writel(dword, regs + tab + i);
    692	}
    693}
    694
    695static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
    696{
    697	/* this driver fills quantisation table 0 with data for luma */
    698	exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
    699			     EXYNOS4_QTBL_CONTENT(0),
    700			     ARRAY_SIZE(qtbl_luminance[quality]));
    701}
    702
    703static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
    704{
    705	/* this driver fills quantisation table 1 with data for chroma */
    706	exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
    707			     EXYNOS4_QTBL_CONTENT(1),
    708			     ARRAY_SIZE(qtbl_chrominance[quality]));
    709}
    710
    711static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
    712{
    713	exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
    714							ARRAY_SIZE(hdctbl0));
    715	exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
    716							ARRAY_SIZE(hdctbl0));
    717	exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
    718							ARRAY_SIZE(hdctblg0));
    719	exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
    720							ARRAY_SIZE(hdctblg0));
    721	exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
    722							ARRAY_SIZE(hactbl0));
    723	exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
    724							ARRAY_SIZE(hactbl0));
    725	exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
    726							ARRAY_SIZE(hactblg0));
    727	exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
    728							ARRAY_SIZE(hactblg0));
    729}
    730
    731static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
    732{
    733	/*
    734	 * class: 0 - DC, 1 - AC
    735	 * id: 0 - Y, 1 - Cb/Cr
    736	 */
    737	if (class) {
    738		if (id)
    739			return lenval ? EXYNOS4_HUFF_TBL_HACCL :
    740				EXYNOS4_HUFF_TBL_HACCV;
    741		return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
    742
    743	}
    744	/* class == 0 */
    745	if (id)
    746		return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
    747
    748	return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
    749}
    750
    751static inline int exynos4_huff_tbl_len(int class, int id)
    752{
    753	return __exynos4_huff_tbl(class, id, true);
    754}
    755
    756static inline int exynos4_huff_tbl_val(int class, int id)
    757{
    758	return __exynos4_huff_tbl(class, id, false);
    759}
    760
    761static int get_byte(struct s5p_jpeg_buffer *buf);
    762static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
    763static void skip(struct s5p_jpeg_buffer *buf, long len);
    764
    765static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
    766{
    767	struct s5p_jpeg *jpeg = ctx->jpeg;
    768	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
    769	struct s5p_jpeg_buffer jpeg_buffer;
    770	unsigned int word;
    771	int c, x, components;
    772
    773	jpeg_buffer.size = 2; /* Ls */
    774	jpeg_buffer.data =
    775		(unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2;
    776	jpeg_buffer.curr = 0;
    777
    778	word = 0;
    779
    780	if (get_word_be(&jpeg_buffer, &word))
    781		return;
    782	jpeg_buffer.size = (long)word - 2;
    783	jpeg_buffer.data += 2;
    784	jpeg_buffer.curr = 0;
    785
    786	components = get_byte(&jpeg_buffer);
    787	if (components == -1)
    788		return;
    789	while (components--) {
    790		c = get_byte(&jpeg_buffer);
    791		if (c == -1)
    792			return;
    793		x = get_byte(&jpeg_buffer);
    794		if (x == -1)
    795			return;
    796		exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
    797					(((x >> 4) & 0x1) << 1) | (x & 0x1));
    798	}
    799
    800}
    801
    802static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
    803{
    804	struct s5p_jpeg *jpeg = ctx->jpeg;
    805	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
    806	struct s5p_jpeg_buffer jpeg_buffer;
    807	unsigned int word;
    808	int c, i, n, j;
    809
    810	for (j = 0; j < ctx->out_q.dht.n; ++j) {
    811		jpeg_buffer.size = ctx->out_q.dht.len[j];
    812		jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) +
    813				   ctx->out_q.dht.marker[j];
    814		jpeg_buffer.curr = 0;
    815
    816		word = 0;
    817		while (jpeg_buffer.curr < jpeg_buffer.size) {
    818			char id, class;
    819
    820			c = get_byte(&jpeg_buffer);
    821			if (c == -1)
    822				return;
    823			id = c & 0xf;
    824			class = (c >> 4) & 0xf;
    825			n = 0;
    826			for (i = 0; i < 16; ++i) {
    827				c = get_byte(&jpeg_buffer);
    828				if (c == -1)
    829					return;
    830				word |= c << ((i % 4) * 8);
    831				if ((i + 1) % 4 == 0) {
    832					writel(word, jpeg->regs +
    833					exynos4_huff_tbl_len(class, id) +
    834					(i / 4) * 4);
    835					word = 0;
    836				}
    837				n += c;
    838			}
    839			word = 0;
    840			for (i = 0; i < n; ++i) {
    841				c = get_byte(&jpeg_buffer);
    842				if (c == -1)
    843					return;
    844				word |= c << ((i % 4) * 8);
    845				if ((i + 1) % 4 == 0) {
    846					writel(word, jpeg->regs +
    847					exynos4_huff_tbl_val(class, id) +
    848					(i / 4) * 4);
    849					word = 0;
    850				}
    851			}
    852			if (i % 4) {
    853				writel(word, jpeg->regs +
    854				exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
    855			}
    856			word = 0;
    857		}
    858	}
    859}
    860
    861static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
    862{
    863	struct s5p_jpeg *jpeg = ctx->jpeg;
    864	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
    865	struct s5p_jpeg_buffer jpeg_buffer;
    866	int c, x, components;
    867
    868	jpeg_buffer.size = ctx->out_q.sof_len;
    869	jpeg_buffer.data =
    870		(unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sof;
    871	jpeg_buffer.curr = 0;
    872
    873	skip(&jpeg_buffer, 5); /* P, Y, X */
    874	components = get_byte(&jpeg_buffer);
    875	if (components == -1)
    876		return;
    877
    878	exynos4_jpeg_set_dec_components(jpeg->regs, components);
    879
    880	while (components--) {
    881		c = get_byte(&jpeg_buffer);
    882		if (c == -1)
    883			return;
    884		skip(&jpeg_buffer, 1);
    885		x = get_byte(&jpeg_buffer);
    886		if (x == -1)
    887			return;
    888		exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
    889	}
    890}
    891
    892static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
    893{
    894	struct s5p_jpeg *jpeg = ctx->jpeg;
    895	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
    896	struct s5p_jpeg_buffer jpeg_buffer;
    897	unsigned int word;
    898	int c, i, j;
    899
    900	for (j = 0; j < ctx->out_q.dqt.n; ++j) {
    901		jpeg_buffer.size = ctx->out_q.dqt.len[j];
    902		jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) +
    903				   ctx->out_q.dqt.marker[j];
    904		jpeg_buffer.curr = 0;
    905
    906		word = 0;
    907		while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
    908			char id;
    909
    910			c = get_byte(&jpeg_buffer);
    911			if (c == -1)
    912				return;
    913			id = c & 0xf;
    914			/* nonzero means extended mode - not supported */
    915			if ((c >> 4) & 0xf)
    916				return;
    917			for (i = 0; i < 64; ++i) {
    918				c = get_byte(&jpeg_buffer);
    919				if (c == -1)
    920					return;
    921				word |= c << ((i % 4) * 8);
    922				if ((i + 1) % 4 == 0) {
    923					writel(word, jpeg->regs +
    924					EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4);
    925					word = 0;
    926				}
    927			}
    928			word = 0;
    929		}
    930	}
    931}
    932
    933/*
    934 * ============================================================================
    935 * Device file operations
    936 * ============================================================================
    937 */
    938
    939static int queue_init(void *priv, struct vb2_queue *src_vq,
    940		      struct vb2_queue *dst_vq);
    941static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
    942				__u32 pixelformat, unsigned int fmt_type);
    943static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
    944
    945static int s5p_jpeg_open(struct file *file)
    946{
    947	struct s5p_jpeg *jpeg = video_drvdata(file);
    948	struct video_device *vfd = video_devdata(file);
    949	struct s5p_jpeg_ctx *ctx;
    950	struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
    951	int ret = 0;
    952
    953	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    954	if (!ctx)
    955		return -ENOMEM;
    956
    957	if (mutex_lock_interruptible(&jpeg->lock)) {
    958		ret = -ERESTARTSYS;
    959		goto free;
    960	}
    961
    962	v4l2_fh_init(&ctx->fh, vfd);
    963	/* Use separate control handler per file handle */
    964	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
    965	file->private_data = &ctx->fh;
    966	v4l2_fh_add(&ctx->fh);
    967
    968	ctx->jpeg = jpeg;
    969	if (vfd == jpeg->vfd_encoder) {
    970		ctx->mode = S5P_JPEG_ENCODE;
    971		out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
    972							FMT_TYPE_OUTPUT);
    973		cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
    974							FMT_TYPE_CAPTURE);
    975	} else {
    976		ctx->mode = S5P_JPEG_DECODE;
    977		out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
    978							FMT_TYPE_OUTPUT);
    979		cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
    980							FMT_TYPE_CAPTURE);
    981		ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
    982	}
    983
    984	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
    985	if (IS_ERR(ctx->fh.m2m_ctx)) {
    986		ret = PTR_ERR(ctx->fh.m2m_ctx);
    987		goto error;
    988	}
    989
    990	ctx->out_q.fmt = out_fmt;
    991	ctx->cap_q.fmt = cap_fmt;
    992
    993	ret = s5p_jpeg_controls_create(ctx);
    994	if (ret < 0)
    995		goto error;
    996
    997	mutex_unlock(&jpeg->lock);
    998	return 0;
    999
   1000error:
   1001	v4l2_fh_del(&ctx->fh);
   1002	v4l2_fh_exit(&ctx->fh);
   1003	mutex_unlock(&jpeg->lock);
   1004free:
   1005	kfree(ctx);
   1006	return ret;
   1007}
   1008
   1009static int s5p_jpeg_release(struct file *file)
   1010{
   1011	struct s5p_jpeg *jpeg = video_drvdata(file);
   1012	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
   1013
   1014	mutex_lock(&jpeg->lock);
   1015	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
   1016	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
   1017	v4l2_fh_del(&ctx->fh);
   1018	v4l2_fh_exit(&ctx->fh);
   1019	kfree(ctx);
   1020	mutex_unlock(&jpeg->lock);
   1021
   1022	return 0;
   1023}
   1024
   1025static const struct v4l2_file_operations s5p_jpeg_fops = {
   1026	.owner		= THIS_MODULE,
   1027	.open		= s5p_jpeg_open,
   1028	.release	= s5p_jpeg_release,
   1029	.poll		= v4l2_m2m_fop_poll,
   1030	.unlocked_ioctl	= video_ioctl2,
   1031	.mmap		= v4l2_m2m_fop_mmap,
   1032};
   1033
   1034/*
   1035 * ============================================================================
   1036 * video ioctl operations
   1037 * ============================================================================
   1038 */
   1039
   1040static int get_byte(struct s5p_jpeg_buffer *buf)
   1041{
   1042	if (buf->curr >= buf->size)
   1043		return -1;
   1044
   1045	return ((unsigned char *)buf->data)[buf->curr++];
   1046}
   1047
   1048static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
   1049{
   1050	unsigned int temp;
   1051	int byte;
   1052
   1053	byte = get_byte(buf);
   1054	if (byte == -1)
   1055		return -1;
   1056	temp = byte << 8;
   1057	byte = get_byte(buf);
   1058	if (byte == -1)
   1059		return -1;
   1060	*word = (unsigned int)byte | temp;
   1061	return 0;
   1062}
   1063
   1064static void skip(struct s5p_jpeg_buffer *buf, long len)
   1065{
   1066	if (len <= 0)
   1067		return;
   1068
   1069	while (len--)
   1070		get_byte(buf);
   1071}
   1072
   1073static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
   1074					unsigned int subsampling)
   1075{
   1076	unsigned int version;
   1077
   1078	switch (subsampling) {
   1079	case 0x11:
   1080		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
   1081		break;
   1082	case 0x21:
   1083		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
   1084		break;
   1085	case 0x22:
   1086		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
   1087		break;
   1088	case 0x33:
   1089		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
   1090		break;
   1091	case 0x41:
   1092		/*
   1093		 * 4:1:1 subsampling only supported by 3250, 5420, and 5433
   1094		 * variants
   1095		 */
   1096		version = ctx->jpeg->variant->version;
   1097		if (version != SJPEG_EXYNOS3250 &&
   1098		    version != SJPEG_EXYNOS5420 &&
   1099		    version != SJPEG_EXYNOS5433)
   1100			return false;
   1101
   1102		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
   1103		break;
   1104	default:
   1105		return false;
   1106	}
   1107
   1108	return true;
   1109}
   1110
   1111static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
   1112			       unsigned long buffer, unsigned long size,
   1113			       struct s5p_jpeg_ctx *ctx)
   1114{
   1115	int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
   1116	unsigned int height = 0, width = 0, word, subsampling = 0;
   1117	unsigned int sos = 0, sof = 0, sof_len = 0;
   1118	unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER];
   1119	unsigned int dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
   1120	long length;
   1121	struct s5p_jpeg_buffer jpeg_buffer;
   1122
   1123	jpeg_buffer.size = size;
   1124	jpeg_buffer.data = buffer;
   1125	jpeg_buffer.curr = 0;
   1126
   1127	notfound = 1;
   1128	while (notfound || !sos) {
   1129		c = get_byte(&jpeg_buffer);
   1130		if (c == -1)
   1131			return false;
   1132		if (c != 0xff)
   1133			continue;
   1134		do
   1135			c = get_byte(&jpeg_buffer);
   1136		while (c == 0xff);
   1137		if (c == -1)
   1138			return false;
   1139		if (c == 0)
   1140			continue;
   1141		length = 0;
   1142		switch (c) {
   1143		/* JPEG_MARKER_SOF0: baseline JPEG */
   1144		case JPEG_MARKER_SOF0:
   1145			if (get_word_be(&jpeg_buffer, &word))
   1146				break;
   1147			length = (long)word - 2;
   1148			if (!length)
   1149				return false;
   1150			sof = jpeg_buffer.curr; /* after 0xffc0 */
   1151			sof_len = length;
   1152			if (get_byte(&jpeg_buffer) == -1)
   1153				break;
   1154			if (get_word_be(&jpeg_buffer, &height))
   1155				break;
   1156			if (get_word_be(&jpeg_buffer, &width))
   1157				break;
   1158			components = get_byte(&jpeg_buffer);
   1159			if (components == -1)
   1160				break;
   1161
   1162			if (components == 1) {
   1163				subsampling = 0x33;
   1164			} else {
   1165				skip(&jpeg_buffer, 1);
   1166				subsampling = get_byte(&jpeg_buffer);
   1167				skip(&jpeg_buffer, 1);
   1168			}
   1169			if (components > 3)
   1170				return false;
   1171			skip(&jpeg_buffer, components * 2);
   1172			notfound = 0;
   1173			break;
   1174
   1175		case JPEG_MARKER_DQT:
   1176			if (get_word_be(&jpeg_buffer, &word))
   1177				break;
   1178			length = (long)word - 2;
   1179			if (!length)
   1180				return false;
   1181			if (n_dqt >= S5P_JPEG_MAX_MARKER)
   1182				return false;
   1183			dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
   1184			dqt_len[n_dqt++] = length;
   1185			skip(&jpeg_buffer, length);
   1186			break;
   1187
   1188		case JPEG_MARKER_DHT:
   1189			if (get_word_be(&jpeg_buffer, &word))
   1190				break;
   1191			length = (long)word - 2;
   1192			if (!length)
   1193				return false;
   1194			if (n_dht >= S5P_JPEG_MAX_MARKER)
   1195				return false;
   1196			dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
   1197			dht_len[n_dht++] = length;
   1198			skip(&jpeg_buffer, length);
   1199			break;
   1200
   1201		case JPEG_MARKER_SOS:
   1202			sos = jpeg_buffer.curr - 2; /* 0xffda */
   1203			break;
   1204
   1205		/* skip payload-less markers */
   1206		case JPEG_MARKER_RST ... JPEG_MARKER_RST + 7:
   1207		case JPEG_MARKER_SOI:
   1208		case JPEG_MARKER_EOI:
   1209		case JPEG_MARKER_TEM:
   1210			break;
   1211
   1212		/* skip uninteresting payload markers */
   1213		default:
   1214			if (get_word_be(&jpeg_buffer, &word))
   1215				break;
   1216			length = (long)word - 2;
   1217			skip(&jpeg_buffer, length);
   1218			break;
   1219		}
   1220	}
   1221
   1222	if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling))
   1223		return false;
   1224
   1225	result->w = width;
   1226	result->h = height;
   1227	result->sos = sos;
   1228	result->dht.n = n_dht;
   1229	while (n_dht--) {
   1230		result->dht.marker[n_dht] = dht[n_dht];
   1231		result->dht.len[n_dht] = dht_len[n_dht];
   1232	}
   1233	result->dqt.n = n_dqt;
   1234	while (n_dqt--) {
   1235		result->dqt.marker[n_dqt] = dqt[n_dqt];
   1236		result->dqt.len[n_dqt] = dqt_len[n_dqt];
   1237	}
   1238	result->sof = sof;
   1239	result->sof_len = sof_len;
   1240
   1241	return true;
   1242}
   1243
   1244static int s5p_jpeg_querycap(struct file *file, void *priv,
   1245			   struct v4l2_capability *cap)
   1246{
   1247	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
   1248
   1249	if (ctx->mode == S5P_JPEG_ENCODE) {
   1250		strscpy(cap->driver, S5P_JPEG_M2M_NAME,
   1251			sizeof(cap->driver));
   1252		strscpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
   1253			sizeof(cap->card));
   1254	} else {
   1255		strscpy(cap->driver, S5P_JPEG_M2M_NAME,
   1256			sizeof(cap->driver));
   1257		strscpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
   1258			sizeof(cap->card));
   1259	}
   1260	return 0;
   1261}
   1262
   1263static int enum_fmt(struct s5p_jpeg_ctx *ctx,
   1264		    struct s5p_jpeg_fmt *sjpeg_formats, int n,
   1265		    struct v4l2_fmtdesc *f, u32 type)
   1266{
   1267	int i, num = 0;
   1268	unsigned int fmt_ver_flag = ctx->jpeg->variant->fmt_ver_flag;
   1269
   1270	for (i = 0; i < n; ++i) {
   1271		if (sjpeg_formats[i].flags & type &&
   1272		    sjpeg_formats[i].flags & fmt_ver_flag) {
   1273			/* index-th format of type type found ? */
   1274			if (num == f->index)
   1275				break;
   1276			/* Correct type but haven't reached our index yet,
   1277			 * just increment per-type index
   1278			 */
   1279			++num;
   1280		}
   1281	}
   1282
   1283	/* Format not found */
   1284	if (i >= n)
   1285		return -EINVAL;
   1286
   1287	f->pixelformat = sjpeg_formats[i].fourcc;
   1288
   1289	return 0;
   1290}
   1291
   1292static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
   1293				   struct v4l2_fmtdesc *f)
   1294{
   1295	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
   1296
   1297	if (ctx->mode == S5P_JPEG_ENCODE)
   1298		return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
   1299				SJPEG_FMT_FLAG_ENC_CAPTURE);
   1300
   1301	return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
   1302			SJPEG_FMT_FLAG_DEC_CAPTURE);
   1303}
   1304
   1305static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
   1306				   struct v4l2_fmtdesc *f)
   1307{
   1308	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
   1309
   1310	if (ctx->mode == S5P_JPEG_ENCODE)
   1311		return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
   1312				SJPEG_FMT_FLAG_ENC_OUTPUT);
   1313
   1314	return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
   1315			SJPEG_FMT_FLAG_DEC_OUTPUT);
   1316}
   1317
   1318static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
   1319					  enum v4l2_buf_type type)
   1320{
   1321	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
   1322		return &ctx->out_q;
   1323	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
   1324		return &ctx->cap_q;
   1325
   1326	return NULL;
   1327}
   1328
   1329static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
   1330{
   1331	struct vb2_queue *vq;
   1332	struct s5p_jpeg_q_data *q_data = NULL;
   1333	struct v4l2_pix_format *pix = &f->fmt.pix;
   1334	struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
   1335
   1336	vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
   1337	if (!vq)
   1338		return -EINVAL;
   1339
   1340	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
   1341	    ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
   1342		return -EINVAL;
   1343	q_data = get_q_data(ct, f->type);
   1344	BUG_ON(q_data == NULL);
   1345
   1346	pix->width = q_data->w;
   1347	pix->height = q_data->h;
   1348	pix->field = V4L2_FIELD_NONE;
   1349	pix->pixelformat = q_data->fmt->fourcc;
   1350	pix->bytesperline = 0;
   1351	if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
   1352		u32 bpl = q_data->w;
   1353
   1354		if (q_data->fmt->colplanes == 1)
   1355			bpl = (bpl * q_data->fmt->depth) >> 3;
   1356		pix->bytesperline = bpl;
   1357	}
   1358	pix->sizeimage = q_data->size;
   1359
   1360	return 0;
   1361}
   1362
   1363static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
   1364				u32 pixelformat, unsigned int fmt_type)
   1365{
   1366	unsigned int k, fmt_flag;
   1367
   1368	if (ctx->mode == S5P_JPEG_ENCODE)
   1369		fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
   1370				SJPEG_FMT_FLAG_ENC_OUTPUT :
   1371				SJPEG_FMT_FLAG_ENC_CAPTURE;
   1372	else
   1373		fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
   1374				SJPEG_FMT_FLAG_DEC_OUTPUT :
   1375				SJPEG_FMT_FLAG_DEC_CAPTURE;
   1376
   1377	for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
   1378		struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
   1379
   1380		if (fmt->fourcc == pixelformat &&
   1381		    fmt->flags & fmt_flag &&
   1382		    fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
   1383			return fmt;
   1384		}
   1385	}
   1386
   1387	return NULL;
   1388}
   1389
   1390static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
   1391				   u32 *w, unsigned int wmin, unsigned int wmax,
   1392				   unsigned int walign,
   1393				   u32 *h, unsigned int hmin, unsigned int hmax,
   1394				   unsigned int halign)
   1395{
   1396	int width, height, w_step, h_step;
   1397
   1398	width = *w;
   1399	height = *h;
   1400
   1401	w_step = 1 << walign;
   1402	h_step = 1 << halign;
   1403
   1404	if (ctx->jpeg->variant->hw3250_compat) {
   1405		/*
   1406		 * Rightmost and bottommost pixels are cropped by the
   1407		 * Exynos3250/compatible JPEG IP for RGB formats, for the
   1408		 * specific width and height values respectively. This
   1409		 * assignment will result in v4l_bound_align_image returning
   1410		 * dimensions reduced by 1 for the aforementioned cases.
   1411		 */
   1412		if (w_step == 4 && ((width & 3) == 1)) {
   1413			wmax = width;
   1414			hmax = height;
   1415		}
   1416	}
   1417
   1418	v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
   1419
   1420	if (*w < width && (*w + w_step) < wmax)
   1421		*w += w_step;
   1422	if (*h < height && (*h + h_step) < hmax)
   1423		*h += h_step;
   1424}
   1425
   1426static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
   1427			  struct s5p_jpeg_ctx *ctx, int q_type)
   1428{
   1429	struct v4l2_pix_format *pix = &f->fmt.pix;
   1430
   1431	if (pix->field == V4L2_FIELD_ANY)
   1432		pix->field = V4L2_FIELD_NONE;
   1433	else if (pix->field != V4L2_FIELD_NONE)
   1434		return -EINVAL;
   1435
   1436	/* V4L2 specification suggests the driver corrects the format struct
   1437	 * if any of the dimensions is unsupported
   1438	 */
   1439	if (q_type == FMT_TYPE_OUTPUT)
   1440		jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
   1441				       S5P_JPEG_MAX_WIDTH, 0,
   1442				       &pix->height, S5P_JPEG_MIN_HEIGHT,
   1443				       S5P_JPEG_MAX_HEIGHT, 0);
   1444	else
   1445		jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
   1446				       S5P_JPEG_MAX_WIDTH, fmt->h_align,
   1447				       &pix->height, S5P_JPEG_MIN_HEIGHT,
   1448				       S5P_JPEG_MAX_HEIGHT, fmt->v_align);
   1449
   1450	if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
   1451		if (pix->sizeimage <= 0)
   1452			pix->sizeimage = PAGE_SIZE;
   1453		pix->bytesperline = 0;
   1454	} else {
   1455		u32 bpl = pix->bytesperline;
   1456
   1457		if (fmt->colplanes > 1 && bpl < pix->width)
   1458			bpl = pix->width; /* planar */
   1459
   1460		if (fmt->colplanes == 1 && /* packed */
   1461		    (bpl << 3) / fmt->depth < pix->width)
   1462			bpl = (pix->width * fmt->depth) >> 3;
   1463
   1464		pix->bytesperline = bpl;
   1465		pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
   1466	}
   1467
   1468	return 0;
   1469}
   1470
   1471static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
   1472				  struct v4l2_format *f)
   1473{
   1474	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
   1475	struct v4l2_pix_format *pix = &f->fmt.pix;
   1476	struct s5p_jpeg_fmt *fmt;
   1477	int ret;
   1478
   1479	fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
   1480						FMT_TYPE_CAPTURE);
   1481	if (!fmt) {
   1482		v4l2_err(&ctx->jpeg->v4l2_dev,
   1483			 "Fourcc format (0x%08x) invalid.\n",
   1484			 f->fmt.pix.pixelformat);
   1485		return -EINVAL;
   1486	}
   1487
   1488	if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
   1489		goto exit;
   1490
   1491	/*
   1492	 * The exynos4x12 device requires resulting YUV image
   1493	 * subsampling not to be lower than the input jpeg subsampling.
   1494	 * If this requirement is not met then downgrade the requested
   1495	 * capture format to the one with subsampling equal to the input jpeg.
   1496	 */
   1497	if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
   1498	    (fmt->subsampling < ctx->subsampling)) {
   1499		ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
   1500							    fmt->fourcc,
   1501							    &pix->pixelformat,
   1502							    ctx);
   1503		if (ret < 0)
   1504			pix->pixelformat = V4L2_PIX_FMT_GREY;
   1505
   1506		fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
   1507							FMT_TYPE_CAPTURE);
   1508	}
   1509
   1510	/*
   1511	 * Decompression of a JPEG file with 4:2:0 subsampling and odd
   1512	 * width to the YUV 4:2:0 compliant formats produces a raw image
   1513	 * with broken luma component. Adjust capture format to RGB565
   1514	 * in such a case.
   1515	 */
   1516	if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
   1517	    (ctx->out_q.w & 1) &&
   1518	    (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
   1519	     pix->pixelformat == V4L2_PIX_FMT_NV21 ||
   1520	     pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
   1521		pix->pixelformat = V4L2_PIX_FMT_RGB565;
   1522		fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
   1523							FMT_TYPE_CAPTURE);
   1524	}
   1525
   1526exit:
   1527	return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
   1528}
   1529
   1530static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
   1531				  struct v4l2_format *f)
   1532{
   1533	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
   1534	struct s5p_jpeg_fmt *fmt;
   1535
   1536	fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
   1537						FMT_TYPE_OUTPUT);
   1538	if (!fmt) {
   1539		v4l2_err(&ctx->jpeg->v4l2_dev,
   1540			 "Fourcc format (0x%08x) invalid.\n",
   1541			 f->fmt.pix.pixelformat);
   1542		return -EINVAL;
   1543	}
   1544
   1545	return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
   1546}
   1547
   1548static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
   1549						struct v4l2_format *f,
   1550						int fmt_depth)
   1551{
   1552	struct v4l2_pix_format *pix = &f->fmt.pix;
   1553	u32 pix_fmt = f->fmt.pix.pixelformat;
   1554	int w = pix->width, h = pix->height, wh_align;
   1555	int padding = 0;
   1556
   1557	if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
   1558	    pix_fmt == V4L2_PIX_FMT_RGB565 ||
   1559	    pix_fmt == V4L2_PIX_FMT_NV24 ||
   1560	    pix_fmt == V4L2_PIX_FMT_NV42 ||
   1561	    pix_fmt == V4L2_PIX_FMT_NV12 ||
   1562	    pix_fmt == V4L2_PIX_FMT_NV21 ||
   1563	    pix_fmt == V4L2_PIX_FMT_YUV420)
   1564		wh_align = 4;
   1565	else
   1566		wh_align = 1;
   1567
   1568	jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
   1569			       S5P_JPEG_MAX_WIDTH, wh_align,
   1570			       &h, S5P_JPEG_MIN_HEIGHT,
   1571			       S5P_JPEG_MAX_HEIGHT, wh_align);
   1572
   1573	if (ctx->jpeg->variant->version == SJPEG_EXYNOS4)
   1574		padding = PAGE_SIZE;
   1575
   1576	return (w * h * fmt_depth >> 3) + padding;
   1577}
   1578
   1579static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
   1580				   struct v4l2_rect *r);
   1581
   1582static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
   1583{
   1584	struct vb2_queue *vq;
   1585	struct s5p_jpeg_q_data *q_data = NULL;
   1586	struct v4l2_pix_format *pix = &f->fmt.pix;
   1587	struct v4l2_ctrl *ctrl_subs;
   1588	struct v4l2_rect scale_rect;
   1589	unsigned int f_type;
   1590
   1591	vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
   1592	if (!vq)
   1593		return -EINVAL;
   1594
   1595	q_data = get_q_data(ct, f->type);
   1596	BUG_ON(q_data == NULL);
   1597
   1598	if (vb2_is_busy(vq)) {
   1599		v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
   1600		return -EBUSY;
   1601	}
   1602
   1603	f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
   1604			FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
   1605
   1606	q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
   1607	if (ct->mode == S5P_JPEG_ENCODE ||
   1608		(ct->mode == S5P_JPEG_DECODE &&
   1609		q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)) {
   1610		q_data->w = pix->width;
   1611		q_data->h = pix->height;
   1612	}
   1613	if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
   1614		/*
   1615		 * During encoding Exynos4x12 SoCs access wider memory area
   1616		 * than it results from Image_x and Image_y values written to
   1617		 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
   1618		 * page fault calculate proper buffer size in such a case.
   1619		 */
   1620		if (ct->jpeg->variant->hw_ex4_compat &&
   1621		    f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
   1622			q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
   1623							f,
   1624							q_data->fmt->depth);
   1625		else
   1626			q_data->size = q_data->w * q_data->h *
   1627						q_data->fmt->depth >> 3;
   1628	} else {
   1629		q_data->size = pix->sizeimage;
   1630	}
   1631
   1632	if (f_type == FMT_TYPE_OUTPUT) {
   1633		ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
   1634					V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
   1635		if (ctrl_subs)
   1636			v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
   1637		ct->crop_altered = false;
   1638	}
   1639
   1640	/*
   1641	 * For decoding init crop_rect with capture buffer dimmensions which
   1642	 * contain aligned dimensions of the input JPEG image and do it only
   1643	 * if crop rectangle hasn't been altered by the user space e.g. with
   1644	 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
   1645	 */
   1646	if (!ct->crop_altered &&
   1647	    ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
   1648	     (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
   1649		ct->crop_rect.width = pix->width;
   1650		ct->crop_rect.height = pix->height;
   1651	}
   1652
   1653	/*
   1654	 * Prevent downscaling to YUV420 format by more than 2
   1655	 * for Exynos3250/compatible SoC as it produces broken raw image
   1656	 * in such cases.
   1657	 */
   1658	if (ct->mode == S5P_JPEG_DECODE &&
   1659	    f_type == FMT_TYPE_CAPTURE &&
   1660	    ct->jpeg->variant->hw3250_compat &&
   1661	    pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
   1662	    ct->scale_factor > 2) {
   1663		scale_rect.width = ct->out_q.w / 2;
   1664		scale_rect.height = ct->out_q.h / 2;
   1665		exynos3250_jpeg_try_downscale(ct, &scale_rect);
   1666	}
   1667
   1668	return 0;
   1669}
   1670
   1671static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
   1672				struct v4l2_format *f)
   1673{
   1674	int ret;
   1675
   1676	ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
   1677	if (ret)
   1678		return ret;
   1679
   1680	return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
   1681}
   1682
   1683static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
   1684				struct v4l2_format *f)
   1685{
   1686	int ret;
   1687
   1688	ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
   1689	if (ret)
   1690		return ret;
   1691
   1692	return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
   1693}
   1694
   1695static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
   1696				    const struct v4l2_event_subscription *sub)
   1697{
   1698	if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
   1699		return v4l2_src_change_event_subscribe(fh, sub);
   1700
   1701	return -EINVAL;
   1702}
   1703
   1704static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
   1705				   struct v4l2_rect *r)
   1706{
   1707	int w_ratio, h_ratio, scale_factor, cur_ratio, i;
   1708
   1709	w_ratio = ctx->out_q.w / r->width;
   1710	h_ratio = ctx->out_q.h / r->height;
   1711
   1712	scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
   1713	scale_factor = clamp_val(scale_factor, 1, 8);
   1714
   1715	/* Align scale ratio to the nearest power of 2 */
   1716	for (i = 0; i <= 3; ++i) {
   1717		cur_ratio = 1 << i;
   1718		if (scale_factor <= cur_ratio) {
   1719			ctx->scale_factor = cur_ratio;
   1720			break;
   1721		}
   1722	}
   1723
   1724	r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
   1725	r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
   1726
   1727	ctx->crop_rect.width = r->width;
   1728	ctx->crop_rect.height = r->height;
   1729	ctx->crop_rect.left = 0;
   1730	ctx->crop_rect.top = 0;
   1731
   1732	ctx->crop_altered = true;
   1733
   1734	return 0;
   1735}
   1736
   1737static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
   1738				   struct v4l2_rect *r)
   1739{
   1740	struct v4l2_rect base_rect;
   1741	int w_step, h_step;
   1742
   1743	switch (ctx->cap_q.fmt->fourcc) {
   1744	case V4L2_PIX_FMT_NV12:
   1745	case V4L2_PIX_FMT_NV21:
   1746		w_step = 1;
   1747		h_step = 2;
   1748		break;
   1749	case V4L2_PIX_FMT_YUV420:
   1750		w_step = 2;
   1751		h_step = 2;
   1752		break;
   1753	default:
   1754		w_step = 1;
   1755		h_step = 1;
   1756		break;
   1757	}
   1758
   1759	base_rect.top = 0;
   1760	base_rect.left = 0;
   1761	base_rect.width = ctx->out_q.w;
   1762	base_rect.height = ctx->out_q.h;
   1763
   1764	r->width = round_down(r->width, w_step);
   1765	r->height = round_down(r->height, h_step);
   1766	r->left = round_down(r->left, 2);
   1767	r->top = round_down(r->top, 2);
   1768
   1769	if (!v4l2_rect_enclosed(r, &base_rect))
   1770		return -EINVAL;
   1771
   1772	ctx->crop_rect.left = r->left;
   1773	ctx->crop_rect.top = r->top;
   1774	ctx->crop_rect.width = r->width;
   1775	ctx->crop_rect.height = r->height;
   1776
   1777	ctx->crop_altered = true;
   1778
   1779	return 0;
   1780}
   1781
   1782/*
   1783 * V4L2 controls
   1784 */
   1785
   1786static int s5p_jpeg_g_selection(struct file *file, void *priv,
   1787			 struct v4l2_selection *s)
   1788{
   1789	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
   1790
   1791	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
   1792	    s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
   1793		return -EINVAL;
   1794
   1795	/* For JPEG blob active == default == bounds */
   1796	switch (s->target) {
   1797	case V4L2_SEL_TGT_CROP:
   1798	case V4L2_SEL_TGT_CROP_BOUNDS:
   1799	case V4L2_SEL_TGT_CROP_DEFAULT:
   1800	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
   1801		s->r.width = ctx->out_q.w;
   1802		s->r.height = ctx->out_q.h;
   1803		s->r.left = 0;
   1804		s->r.top = 0;
   1805		break;
   1806	case V4L2_SEL_TGT_COMPOSE:
   1807	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
   1808	case V4L2_SEL_TGT_COMPOSE_PADDED:
   1809		s->r.width = ctx->crop_rect.width;
   1810		s->r.height =  ctx->crop_rect.height;
   1811		s->r.left = ctx->crop_rect.left;
   1812		s->r.top = ctx->crop_rect.top;
   1813		break;
   1814	default:
   1815		return -EINVAL;
   1816	}
   1817	return 0;
   1818}
   1819
   1820/*
   1821 * V4L2 controls
   1822 */
   1823static int s5p_jpeg_s_selection(struct file *file, void *fh,
   1824				  struct v4l2_selection *s)
   1825{
   1826	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
   1827	struct v4l2_rect *rect = &s->r;
   1828	int ret = -EINVAL;
   1829
   1830	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
   1831		return -EINVAL;
   1832
   1833	if (s->target == V4L2_SEL_TGT_COMPOSE) {
   1834		if (ctx->mode != S5P_JPEG_DECODE)
   1835			return -EINVAL;
   1836		if (ctx->jpeg->variant->hw3250_compat)
   1837			ret = exynos3250_jpeg_try_downscale(ctx, rect);
   1838	} else if (s->target == V4L2_SEL_TGT_CROP) {
   1839		if (ctx->mode != S5P_JPEG_ENCODE)
   1840			return -EINVAL;
   1841		if (ctx->jpeg->variant->hw3250_compat)
   1842			ret = exynos3250_jpeg_try_crop(ctx, rect);
   1843	}
   1844
   1845	return ret;
   1846}
   1847
   1848static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
   1849{
   1850	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
   1851	struct s5p_jpeg *jpeg = ctx->jpeg;
   1852	unsigned long flags;
   1853
   1854	switch (ctrl->id) {
   1855	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
   1856		spin_lock_irqsave(&jpeg->slock, flags);
   1857		ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
   1858		spin_unlock_irqrestore(&jpeg->slock, flags);
   1859		break;
   1860	}
   1861
   1862	return 0;
   1863}
   1864
   1865static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
   1866{
   1867	switch (ctx->jpeg->variant->version) {
   1868	case SJPEG_S5P:
   1869		return 0;
   1870	case SJPEG_EXYNOS3250:
   1871	case SJPEG_EXYNOS5420:
   1872		/*
   1873		 * The exynos3250/compatible device can produce JPEG image only
   1874		 * of 4:4:4 subsampling when given RGB32 source image.
   1875		 */
   1876		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
   1877			*ctrl_val = 0;
   1878		break;
   1879	case SJPEG_EXYNOS4:
   1880		/*
   1881		 * The exynos4x12 device requires input raw image fourcc
   1882		 * to be V4L2_PIX_FMT_GREY if gray jpeg format
   1883		 * is to be set.
   1884		 */
   1885		if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
   1886		    *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
   1887			return -EINVAL;
   1888		break;
   1889	}
   1890
   1891	/*
   1892	 * The exynos4x12 and exynos3250/compatible devices require resulting
   1893	 * jpeg subsampling not to be lower than the input raw image
   1894	 * subsampling.
   1895	 */
   1896	if (ctx->out_q.fmt->subsampling > *ctrl_val)
   1897		*ctrl_val = ctx->out_q.fmt->subsampling;
   1898
   1899	return 0;
   1900}
   1901
   1902static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
   1903{
   1904	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
   1905	unsigned long flags;
   1906	int ret = 0;
   1907
   1908	spin_lock_irqsave(&ctx->jpeg->slock, flags);
   1909
   1910	if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
   1911		ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
   1912
   1913	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
   1914	return ret;
   1915}
   1916
   1917static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
   1918{
   1919	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
   1920	unsigned long flags;
   1921
   1922	spin_lock_irqsave(&ctx->jpeg->slock, flags);
   1923
   1924	switch (ctrl->id) {
   1925	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
   1926		ctx->compr_quality = ctrl->val;
   1927		break;
   1928	case V4L2_CID_JPEG_RESTART_INTERVAL:
   1929		ctx->restart_interval = ctrl->val;
   1930		break;
   1931	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
   1932		ctx->subsampling = ctrl->val;
   1933		break;
   1934	}
   1935
   1936	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
   1937	return 0;
   1938}
   1939
   1940static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
   1941	.g_volatile_ctrl	= s5p_jpeg_g_volatile_ctrl,
   1942	.try_ctrl		= s5p_jpeg_try_ctrl,
   1943	.s_ctrl			= s5p_jpeg_s_ctrl,
   1944};
   1945
   1946static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
   1947{
   1948	unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
   1949	struct v4l2_ctrl *ctrl;
   1950	int ret;
   1951
   1952	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
   1953
   1954	if (ctx->mode == S5P_JPEG_ENCODE) {
   1955		v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
   1956				  V4L2_CID_JPEG_COMPRESSION_QUALITY,
   1957				  0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
   1958
   1959		v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
   1960				  V4L2_CID_JPEG_RESTART_INTERVAL,
   1961				  0, 0xffff, 1, 0);
   1962		if (ctx->jpeg->variant->version == SJPEG_S5P)
   1963			mask = ~0x06; /* 422, 420 */
   1964	}
   1965
   1966	ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
   1967				      V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
   1968				      V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
   1969				      V4L2_JPEG_CHROMA_SUBSAMPLING_422);
   1970
   1971	if (ctx->ctrl_handler.error) {
   1972		ret = ctx->ctrl_handler.error;
   1973		goto error_free;
   1974	}
   1975
   1976	if (ctx->mode == S5P_JPEG_DECODE)
   1977		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
   1978			V4L2_CTRL_FLAG_READ_ONLY;
   1979
   1980	ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
   1981	if (ret < 0)
   1982		goto error_free;
   1983
   1984	return ret;
   1985
   1986error_free:
   1987	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
   1988	return ret;
   1989}
   1990
   1991static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
   1992	.vidioc_querycap		= s5p_jpeg_querycap,
   1993
   1994	.vidioc_enum_fmt_vid_cap	= s5p_jpeg_enum_fmt_vid_cap,
   1995	.vidioc_enum_fmt_vid_out	= s5p_jpeg_enum_fmt_vid_out,
   1996
   1997	.vidioc_g_fmt_vid_cap		= s5p_jpeg_g_fmt,
   1998	.vidioc_g_fmt_vid_out		= s5p_jpeg_g_fmt,
   1999
   2000	.vidioc_try_fmt_vid_cap		= s5p_jpeg_try_fmt_vid_cap,
   2001	.vidioc_try_fmt_vid_out		= s5p_jpeg_try_fmt_vid_out,
   2002
   2003	.vidioc_s_fmt_vid_cap		= s5p_jpeg_s_fmt_vid_cap,
   2004	.vidioc_s_fmt_vid_out		= s5p_jpeg_s_fmt_vid_out,
   2005
   2006	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
   2007	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
   2008	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
   2009	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
   2010
   2011	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
   2012	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
   2013
   2014	.vidioc_g_selection		= s5p_jpeg_g_selection,
   2015	.vidioc_s_selection		= s5p_jpeg_s_selection,
   2016
   2017	.vidioc_subscribe_event		= s5p_jpeg_subscribe_event,
   2018	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
   2019};
   2020
   2021/*
   2022 * ============================================================================
   2023 * mem2mem callbacks
   2024 * ============================================================================
   2025 */
   2026
   2027static void s5p_jpeg_device_run(void *priv)
   2028{
   2029	struct s5p_jpeg_ctx *ctx = priv;
   2030	struct s5p_jpeg *jpeg = ctx->jpeg;
   2031	struct vb2_v4l2_buffer *src_buf, *dst_buf;
   2032	unsigned long src_addr, dst_addr, flags;
   2033
   2034	spin_lock_irqsave(&ctx->jpeg->slock, flags);
   2035
   2036	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
   2037	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
   2038	src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
   2039	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
   2040
   2041	s5p_jpeg_reset(jpeg->regs);
   2042	s5p_jpeg_poweron(jpeg->regs);
   2043	s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
   2044	if (ctx->mode == S5P_JPEG_ENCODE) {
   2045		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
   2046			s5p_jpeg_input_raw_mode(jpeg->regs,
   2047							S5P_JPEG_RAW_IN_565);
   2048		else
   2049			s5p_jpeg_input_raw_mode(jpeg->regs,
   2050							S5P_JPEG_RAW_IN_422);
   2051		s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
   2052		s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
   2053		s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
   2054		s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
   2055		s5p_jpeg_imgadr(jpeg->regs, src_addr);
   2056		s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
   2057
   2058		/* ultimately comes from sizeimage from userspace */
   2059		s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
   2060
   2061		/* JPEG RGB to YCbCr conversion matrix */
   2062		s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
   2063		s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
   2064		s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
   2065		s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
   2066		s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
   2067		s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
   2068		s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
   2069		s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
   2070		s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
   2071
   2072		/*
   2073		 * JPEG IP allows storing 4 quantization tables
   2074		 * We fill table 0 for luma and table 1 for chroma
   2075		 */
   2076		s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
   2077		s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
   2078		/* use table 0 for Y */
   2079		s5p_jpeg_qtbl(jpeg->regs, 1, 0);
   2080		/* use table 1 for Cb and Cr*/
   2081		s5p_jpeg_qtbl(jpeg->regs, 2, 1);
   2082		s5p_jpeg_qtbl(jpeg->regs, 3, 1);
   2083
   2084		/* Y, Cb, Cr use Huffman table 0 */
   2085		s5p_jpeg_htbl_ac(jpeg->regs, 1);
   2086		s5p_jpeg_htbl_dc(jpeg->regs, 1);
   2087		s5p_jpeg_htbl_ac(jpeg->regs, 2);
   2088		s5p_jpeg_htbl_dc(jpeg->regs, 2);
   2089		s5p_jpeg_htbl_ac(jpeg->regs, 3);
   2090		s5p_jpeg_htbl_dc(jpeg->regs, 3);
   2091	} else { /* S5P_JPEG_DECODE */
   2092		s5p_jpeg_rst_int_enable(jpeg->regs, true);
   2093		s5p_jpeg_data_num_int_enable(jpeg->regs, true);
   2094		s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
   2095		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
   2096			s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
   2097		else
   2098			s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
   2099		s5p_jpeg_jpgadr(jpeg->regs, src_addr);
   2100		s5p_jpeg_imgadr(jpeg->regs, dst_addr);
   2101	}
   2102
   2103	s5p_jpeg_start(jpeg->regs);
   2104
   2105	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
   2106}
   2107
   2108static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
   2109{
   2110	struct s5p_jpeg *jpeg = ctx->jpeg;
   2111	struct s5p_jpeg_fmt *fmt;
   2112	struct vb2_v4l2_buffer *vb;
   2113	struct s5p_jpeg_addr jpeg_addr = {};
   2114	u32 pix_size, padding_bytes = 0;
   2115
   2116	jpeg_addr.cb = 0;
   2117	jpeg_addr.cr = 0;
   2118
   2119	pix_size = ctx->cap_q.w * ctx->cap_q.h;
   2120
   2121	if (ctx->mode == S5P_JPEG_ENCODE) {
   2122		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
   2123		fmt = ctx->out_q.fmt;
   2124		if (ctx->out_q.w % 2 && fmt->h_align > 0)
   2125			padding_bytes = ctx->out_q.h;
   2126	} else {
   2127		fmt = ctx->cap_q.fmt;
   2128		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
   2129	}
   2130
   2131	jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
   2132
   2133	if (fmt->colplanes == 2) {
   2134		jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
   2135	} else if (fmt->colplanes == 3) {
   2136		jpeg_addr.cb = jpeg_addr.y + pix_size;
   2137		if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
   2138			jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
   2139		else
   2140			jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
   2141	}
   2142
   2143	exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
   2144}
   2145
   2146static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
   2147{
   2148	struct s5p_jpeg *jpeg = ctx->jpeg;
   2149	struct vb2_v4l2_buffer *vb;
   2150	unsigned int jpeg_addr = 0;
   2151
   2152	if (ctx->mode == S5P_JPEG_ENCODE)
   2153		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
   2154	else
   2155		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
   2156
   2157	jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
   2158	if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
   2159	    ctx->mode == S5P_JPEG_DECODE)
   2160		jpeg_addr += ctx->out_q.sos;
   2161	exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
   2162}
   2163
   2164static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
   2165					    unsigned int img_fmt)
   2166{
   2167	__exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
   2168}
   2169
   2170static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
   2171					       unsigned int img_fmt)
   2172{
   2173	__exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
   2174}
   2175
   2176static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
   2177						unsigned int out_fmt)
   2178{
   2179	__exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
   2180}
   2181
   2182static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
   2183						   unsigned int out_fmt)
   2184{
   2185	__exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
   2186}
   2187
   2188static void exynos4_jpeg_device_run(void *priv)
   2189{
   2190	struct s5p_jpeg_ctx *ctx = priv;
   2191	struct s5p_jpeg *jpeg = ctx->jpeg;
   2192	unsigned int bitstream_size;
   2193	unsigned long flags;
   2194
   2195	spin_lock_irqsave(&jpeg->slock, flags);
   2196
   2197	if (ctx->mode == S5P_JPEG_ENCODE) {
   2198		exynos4_jpeg_sw_reset(jpeg->regs);
   2199		exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
   2200		exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
   2201
   2202		exynos4_jpeg_set_huff_tbl(jpeg->regs);
   2203
   2204		/*
   2205		 * JPEG IP allows storing 4 quantization tables
   2206		 * We fill table 0 for luma and table 1 for chroma
   2207		 */
   2208		exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
   2209		exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
   2210
   2211		exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
   2212							ctx->compr_quality);
   2213		exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
   2214							ctx->cap_q.h);
   2215
   2216		if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
   2217			exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
   2218						     ctx->subsampling);
   2219			exynos4_jpeg_set_img_fmt(jpeg->regs,
   2220						 ctx->out_q.fmt->fourcc);
   2221		} else {
   2222			exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
   2223							ctx->subsampling);
   2224			exynos5433_jpeg_set_img_fmt(jpeg->regs,
   2225						    ctx->out_q.fmt->fourcc);
   2226		}
   2227		exynos4_jpeg_set_img_addr(ctx);
   2228		exynos4_jpeg_set_jpeg_addr(ctx);
   2229		exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
   2230							ctx->out_q.fmt->fourcc);
   2231	} else {
   2232		exynos4_jpeg_sw_reset(jpeg->regs);
   2233		exynos4_jpeg_set_interrupt(jpeg->regs,
   2234					   jpeg->variant->version);
   2235		exynos4_jpeg_set_img_addr(ctx);
   2236		exynos4_jpeg_set_jpeg_addr(ctx);
   2237
   2238		if (jpeg->variant->version == SJPEG_EXYNOS5433) {
   2239			exynos4_jpeg_parse_huff_tbl(ctx);
   2240			exynos4_jpeg_parse_decode_h_tbl(ctx);
   2241
   2242			exynos4_jpeg_parse_q_tbl(ctx);
   2243			exynos4_jpeg_parse_decode_q_tbl(ctx);
   2244
   2245			exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
   2246
   2247			exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
   2248					ctx->cap_q.h);
   2249			exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
   2250							ctx->subsampling);
   2251			exynos5433_jpeg_set_img_fmt(jpeg->regs,
   2252						    ctx->cap_q.fmt->fourcc);
   2253			bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
   2254		} else {
   2255			exynos4_jpeg_set_img_fmt(jpeg->regs,
   2256						 ctx->cap_q.fmt->fourcc);
   2257			bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
   2258		}
   2259
   2260		exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
   2261	}
   2262
   2263	exynos4_jpeg_set_sys_int_enable(jpeg->regs, 1);
   2264	exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
   2265
   2266	spin_unlock_irqrestore(&jpeg->slock, flags);
   2267}
   2268
   2269static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
   2270{
   2271	struct s5p_jpeg *jpeg = ctx->jpeg;
   2272	struct s5p_jpeg_fmt *fmt;
   2273	struct vb2_v4l2_buffer *vb;
   2274	struct s5p_jpeg_addr jpeg_addr = {};
   2275	u32 pix_size;
   2276
   2277	pix_size = ctx->cap_q.w * ctx->cap_q.h;
   2278
   2279	if (ctx->mode == S5P_JPEG_ENCODE) {
   2280		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
   2281		fmt = ctx->out_q.fmt;
   2282	} else {
   2283		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
   2284		fmt = ctx->cap_q.fmt;
   2285	}
   2286
   2287	jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
   2288
   2289	if (fmt->colplanes == 2) {
   2290		jpeg_addr.cb = jpeg_addr.y + pix_size;
   2291	} else if (fmt->colplanes == 3) {
   2292		jpeg_addr.cb = jpeg_addr.y + pix_size;
   2293		if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
   2294			jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
   2295		else
   2296			jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
   2297	}
   2298
   2299	exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
   2300}
   2301
   2302static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
   2303{
   2304	struct s5p_jpeg *jpeg = ctx->jpeg;
   2305	struct vb2_v4l2_buffer *vb;
   2306	unsigned int jpeg_addr = 0;
   2307
   2308	if (ctx->mode == S5P_JPEG_ENCODE)
   2309		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
   2310	else
   2311		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
   2312
   2313	jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
   2314	exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
   2315}
   2316
   2317static void exynos3250_jpeg_device_run(void *priv)
   2318{
   2319	struct s5p_jpeg_ctx *ctx = priv;
   2320	struct s5p_jpeg *jpeg = ctx->jpeg;
   2321	unsigned long flags;
   2322
   2323	spin_lock_irqsave(&ctx->jpeg->slock, flags);
   2324
   2325	exynos3250_jpeg_reset(jpeg->regs);
   2326	exynos3250_jpeg_set_dma_num(jpeg->regs);
   2327	exynos3250_jpeg_poweron(jpeg->regs);
   2328	exynos3250_jpeg_clk_set(jpeg->regs);
   2329	exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
   2330
   2331	if (ctx->mode == S5P_JPEG_ENCODE) {
   2332		exynos3250_jpeg_input_raw_fmt(jpeg->regs,
   2333					      ctx->out_q.fmt->fourcc);
   2334		exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
   2335
   2336		/*
   2337		 * JPEG IP allows storing 4 quantization tables
   2338		 * We fill table 0 for luma and table 1 for chroma
   2339		 */
   2340		s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
   2341		s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
   2342		/* use table 0 for Y */
   2343		exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
   2344		/* use table 1 for Cb and Cr*/
   2345		exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
   2346		exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
   2347
   2348		/*
   2349		 * Some SoCs require setting Huffman tables before each run
   2350		 */
   2351		if (jpeg->variant->htbl_reinit) {
   2352			s5p_jpeg_set_hdctbl(jpeg->regs);
   2353			s5p_jpeg_set_hdctblg(jpeg->regs);
   2354			s5p_jpeg_set_hactbl(jpeg->regs);
   2355			s5p_jpeg_set_hactblg(jpeg->regs);
   2356		}
   2357
   2358		/* Y, Cb, Cr use Huffman table 0 */
   2359		exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
   2360		exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
   2361		exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
   2362		exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
   2363		exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
   2364		exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
   2365
   2366		exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
   2367		exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
   2368		exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
   2369								ctx->out_q.w);
   2370		exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
   2371							ctx->crop_rect.top);
   2372		exynos3250_jpeg_set_img_addr(ctx);
   2373		exynos3250_jpeg_set_jpeg_addr(ctx);
   2374		exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
   2375
   2376		/* ultimately comes from sizeimage from userspace */
   2377		exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
   2378
   2379		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
   2380		    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
   2381		    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
   2382			exynos3250_jpeg_set_y16(jpeg->regs, true);
   2383	} else {
   2384		exynos3250_jpeg_set_img_addr(ctx);
   2385		exynos3250_jpeg_set_jpeg_addr(ctx);
   2386		exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
   2387								ctx->cap_q.w);
   2388		exynos3250_jpeg_offset(jpeg->regs, 0, 0);
   2389		exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
   2390							ctx->scale_factor);
   2391		exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
   2392		exynos3250_jpeg_output_raw_fmt(jpeg->regs,
   2393						ctx->cap_q.fmt->fourcc);
   2394	}
   2395
   2396	exynos3250_jpeg_interrupts_enable(jpeg->regs);
   2397
   2398	/* JPEG RGB to YCbCr conversion matrix */
   2399	exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
   2400
   2401	exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
   2402	jpeg->irq_status = 0;
   2403	exynos3250_jpeg_start(jpeg->regs);
   2404
   2405	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
   2406}
   2407
   2408static int s5p_jpeg_job_ready(void *priv)
   2409{
   2410	struct s5p_jpeg_ctx *ctx = priv;
   2411
   2412	if (ctx->mode == S5P_JPEG_DECODE) {
   2413		/*
   2414		 * We have only one input buffer and one output buffer. If there
   2415		 * is a resolution change event, no need to continue decoding.
   2416		 */
   2417		if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
   2418			return 0;
   2419
   2420		return ctx->hdr_parsed;
   2421	}
   2422
   2423	return 1;
   2424}
   2425
   2426static const struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
   2427	.device_run	= s5p_jpeg_device_run,
   2428	.job_ready	= s5p_jpeg_job_ready,
   2429};
   2430
   2431static const struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
   2432	.device_run	= exynos3250_jpeg_device_run,
   2433	.job_ready	= s5p_jpeg_job_ready,
   2434};
   2435
   2436static const struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
   2437	.device_run	= exynos4_jpeg_device_run,
   2438	.job_ready	= s5p_jpeg_job_ready,
   2439};
   2440
   2441/*
   2442 * ============================================================================
   2443 * Queue operations
   2444 * ============================================================================
   2445 */
   2446
   2447static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
   2448			   unsigned int *nbuffers, unsigned int *nplanes,
   2449			   unsigned int sizes[], struct device *alloc_devs[])
   2450{
   2451	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
   2452	struct s5p_jpeg_q_data *q_data = NULL;
   2453	unsigned int size, count = *nbuffers;
   2454
   2455	q_data = get_q_data(ctx, vq->type);
   2456	BUG_ON(q_data == NULL);
   2457
   2458	size = q_data->size;
   2459
   2460	/*
   2461	 * header is parsed during decoding and parsed information stored
   2462	 * in the context so we do not allow another buffer to overwrite it
   2463	 */
   2464	if (ctx->mode == S5P_JPEG_DECODE)
   2465		count = 1;
   2466
   2467	*nbuffers = count;
   2468	*nplanes = 1;
   2469	sizes[0] = size;
   2470
   2471	return 0;
   2472}
   2473
   2474static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
   2475{
   2476	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
   2477	struct s5p_jpeg_q_data *q_data = NULL;
   2478
   2479	q_data = get_q_data(ctx, vb->vb2_queue->type);
   2480	BUG_ON(q_data == NULL);
   2481
   2482	if (vb2_plane_size(vb, 0) < q_data->size) {
   2483		pr_err("%s data will not fit into plane (%lu < %lu)\n",
   2484				__func__, vb2_plane_size(vb, 0),
   2485				(long)q_data->size);
   2486		return -EINVAL;
   2487	}
   2488
   2489	vb2_set_plane_payload(vb, 0, q_data->size);
   2490
   2491	return 0;
   2492}
   2493
   2494static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
   2495{
   2496	struct s5p_jpeg_q_data *q_data = &ctx->cap_q;
   2497
   2498	q_data->w = ctx->out_q.w;
   2499	q_data->h = ctx->out_q.h;
   2500
   2501	/*
   2502	 * This call to jpeg_bound_align_image() takes care of width and
   2503	 * height values alignment when user space calls the QBUF of
   2504	 * OUTPUT buffer after the S_FMT of CAPTURE buffer.
   2505	 * Please note that on Exynos4x12 SoCs, resigning from executing
   2506	 * S_FMT on capture buffer for each JPEG image can result in a
   2507	 * hardware hangup if subsampling is lower than the one of input
   2508	 * JPEG.
   2509	 */
   2510	jpeg_bound_align_image(ctx, &q_data->w, S5P_JPEG_MIN_WIDTH,
   2511			       S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
   2512			       &q_data->h, S5P_JPEG_MIN_HEIGHT,
   2513			       S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
   2514
   2515	q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
   2516}
   2517
   2518static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
   2519{
   2520	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
   2521	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
   2522
   2523	if (ctx->mode == S5P_JPEG_DECODE &&
   2524	    vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
   2525		static const struct v4l2_event ev_src_ch = {
   2526			.type = V4L2_EVENT_SOURCE_CHANGE,
   2527			.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
   2528		};
   2529		struct vb2_queue *dst_vq;
   2530		u32 ori_w;
   2531		u32 ori_h;
   2532
   2533		dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
   2534					 V4L2_BUF_TYPE_VIDEO_CAPTURE);
   2535		ori_w = ctx->out_q.w;
   2536		ori_h = ctx->out_q.h;
   2537
   2538		ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q,
   2539		     (unsigned long)vb2_plane_vaddr(vb, 0),
   2540		     min((unsigned long)ctx->out_q.size,
   2541			 vb2_get_plane_payload(vb, 0)), ctx);
   2542		if (!ctx->hdr_parsed) {
   2543			vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
   2544			return;
   2545		}
   2546
   2547		/*
   2548		 * If there is a resolution change event, only update capture
   2549		 * queue when it is not streaming. Otherwise, update it in
   2550		 * STREAMOFF. See s5p_jpeg_stop_streaming for detail.
   2551		 */
   2552		if (ctx->out_q.w != ori_w || ctx->out_q.h != ori_h) {
   2553			v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
   2554			if (vb2_is_streaming(dst_vq))
   2555				ctx->state = JPEGCTX_RESOLUTION_CHANGE;
   2556			else
   2557				s5p_jpeg_set_capture_queue_data(ctx);
   2558		}
   2559	}
   2560
   2561	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
   2562}
   2563
   2564static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
   2565{
   2566	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
   2567
   2568	return pm_runtime_resume_and_get(ctx->jpeg->dev);
   2569}
   2570
   2571static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
   2572{
   2573	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
   2574
   2575	/*
   2576	 * STREAMOFF is an acknowledgment for resolution change event.
   2577	 * Before STREAMOFF, we still have to return the old resolution and
   2578	 * subsampling. Update capture queue when the stream is off.
   2579	 */
   2580	if (ctx->state == JPEGCTX_RESOLUTION_CHANGE &&
   2581	    q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
   2582		s5p_jpeg_set_capture_queue_data(ctx);
   2583		ctx->state = JPEGCTX_RUNNING;
   2584	}
   2585
   2586	pm_runtime_put(ctx->jpeg->dev);
   2587}
   2588
   2589static const struct vb2_ops s5p_jpeg_qops = {
   2590	.queue_setup		= s5p_jpeg_queue_setup,
   2591	.buf_prepare		= s5p_jpeg_buf_prepare,
   2592	.buf_queue		= s5p_jpeg_buf_queue,
   2593	.wait_prepare		= vb2_ops_wait_prepare,
   2594	.wait_finish		= vb2_ops_wait_finish,
   2595	.start_streaming	= s5p_jpeg_start_streaming,
   2596	.stop_streaming		= s5p_jpeg_stop_streaming,
   2597};
   2598
   2599static int queue_init(void *priv, struct vb2_queue *src_vq,
   2600		      struct vb2_queue *dst_vq)
   2601{
   2602	struct s5p_jpeg_ctx *ctx = priv;
   2603	int ret;
   2604
   2605	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
   2606	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
   2607	src_vq->drv_priv = ctx;
   2608	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
   2609	src_vq->ops = &s5p_jpeg_qops;
   2610	src_vq->mem_ops = &vb2_dma_contig_memops;
   2611	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
   2612	src_vq->lock = &ctx->jpeg->lock;
   2613	src_vq->dev = ctx->jpeg->dev;
   2614
   2615	ret = vb2_queue_init(src_vq);
   2616	if (ret)
   2617		return ret;
   2618
   2619	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   2620	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
   2621	dst_vq->drv_priv = ctx;
   2622	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
   2623	dst_vq->ops = &s5p_jpeg_qops;
   2624	dst_vq->mem_ops = &vb2_dma_contig_memops;
   2625	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
   2626	dst_vq->lock = &ctx->jpeg->lock;
   2627	dst_vq->dev = ctx->jpeg->dev;
   2628
   2629	return vb2_queue_init(dst_vq);
   2630}
   2631
   2632/*
   2633 * ============================================================================
   2634 * ISR
   2635 * ============================================================================
   2636 */
   2637
   2638static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
   2639{
   2640	struct s5p_jpeg *jpeg = dev_id;
   2641	struct s5p_jpeg_ctx *curr_ctx;
   2642	struct vb2_v4l2_buffer *src_buf, *dst_buf;
   2643	unsigned long payload_size = 0;
   2644	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
   2645	bool enc_jpeg_too_large = false;
   2646	bool timer_elapsed = false;
   2647	bool op_completed = false;
   2648
   2649	spin_lock(&jpeg->slock);
   2650
   2651	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
   2652
   2653	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
   2654	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
   2655
   2656	if (curr_ctx->mode == S5P_JPEG_ENCODE)
   2657		enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
   2658	timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
   2659	op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
   2660	if (curr_ctx->mode == S5P_JPEG_DECODE)
   2661		op_completed = op_completed &&
   2662					s5p_jpeg_stream_stat_ok(jpeg->regs);
   2663
   2664	if (enc_jpeg_too_large) {
   2665		state = VB2_BUF_STATE_ERROR;
   2666		s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
   2667	} else if (timer_elapsed) {
   2668		state = VB2_BUF_STATE_ERROR;
   2669		s5p_jpeg_clear_timer_stat(jpeg->regs);
   2670	} else if (!op_completed) {
   2671		state = VB2_BUF_STATE_ERROR;
   2672	} else {
   2673		payload_size = s5p_jpeg_compressed_size(jpeg->regs);
   2674	}
   2675
   2676	dst_buf->timecode = src_buf->timecode;
   2677	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
   2678	dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
   2679	dst_buf->flags |=
   2680		src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
   2681
   2682	v4l2_m2m_buf_done(src_buf, state);
   2683	if (curr_ctx->mode == S5P_JPEG_ENCODE)
   2684		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
   2685	v4l2_m2m_buf_done(dst_buf, state);
   2686
   2687	curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
   2688	spin_unlock(&jpeg->slock);
   2689
   2690	s5p_jpeg_clear_int(jpeg->regs);
   2691
   2692	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
   2693	return IRQ_HANDLED;
   2694}
   2695
   2696static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
   2697{
   2698	unsigned int int_status;
   2699	struct vb2_v4l2_buffer *src_vb, *dst_vb;
   2700	struct s5p_jpeg *jpeg = priv;
   2701	struct s5p_jpeg_ctx *curr_ctx;
   2702	unsigned long payload_size = 0;
   2703
   2704	spin_lock(&jpeg->slock);
   2705
   2706	exynos4_jpeg_set_sys_int_enable(jpeg->regs, 0);
   2707
   2708	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
   2709
   2710	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
   2711	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
   2712
   2713	int_status = exynos4_jpeg_get_int_status(jpeg->regs);
   2714
   2715	if (int_status) {
   2716		switch (int_status & 0x1f) {
   2717		case 0x1:
   2718			jpeg->irq_ret = ERR_PROT;
   2719			break;
   2720		case 0x2:
   2721			jpeg->irq_ret = OK_ENC_OR_DEC;
   2722			break;
   2723		case 0x4:
   2724			jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
   2725			break;
   2726		case 0x8:
   2727			jpeg->irq_ret = ERR_MULTI_SCAN;
   2728			break;
   2729		case 0x10:
   2730			jpeg->irq_ret = ERR_FRAME;
   2731			break;
   2732		default:
   2733			jpeg->irq_ret = ERR_UNKNOWN;
   2734			break;
   2735		}
   2736	} else {
   2737		jpeg->irq_ret = ERR_UNKNOWN;
   2738	}
   2739
   2740	if (jpeg->irq_ret == OK_ENC_OR_DEC) {
   2741		if (curr_ctx->mode == S5P_JPEG_ENCODE) {
   2742			payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
   2743			vb2_set_plane_payload(&dst_vb->vb2_buf,
   2744					0, payload_size);
   2745		}
   2746		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
   2747		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
   2748	} else {
   2749		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
   2750		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
   2751	}
   2752
   2753	if (jpeg->variant->version == SJPEG_EXYNOS4)
   2754		curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
   2755
   2756	exynos4_jpeg_set_enc_dec_mode(jpeg->regs, S5P_JPEG_DISABLE);
   2757
   2758	spin_unlock(&jpeg->slock);
   2759
   2760	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
   2761	return IRQ_HANDLED;
   2762}
   2763
   2764static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
   2765{
   2766	struct s5p_jpeg *jpeg = dev_id;
   2767	struct s5p_jpeg_ctx *curr_ctx;
   2768	struct vb2_v4l2_buffer *src_buf, *dst_buf;
   2769	unsigned long payload_size = 0;
   2770	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
   2771	bool interrupt_timeout = false;
   2772	bool stream_error = false;
   2773	u32 irq_status;
   2774
   2775	spin_lock(&jpeg->slock);
   2776
   2777	irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
   2778	if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
   2779		exynos3250_jpeg_clear_timer_status(jpeg->regs);
   2780		interrupt_timeout = true;
   2781		dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
   2782	}
   2783
   2784	irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
   2785	exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
   2786
   2787	jpeg->irq_status |= irq_status;
   2788
   2789	if (jpeg->variant->version == SJPEG_EXYNOS5420 &&
   2790	    irq_status & EXYNOS3250_STREAM_STAT) {
   2791		stream_error = true;
   2792		dev_err(jpeg->dev, "Syntax error or unrecoverable error occurred.\n");
   2793	}
   2794
   2795	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
   2796
   2797	if (!curr_ctx)
   2798		goto exit_unlock;
   2799
   2800	if ((irq_status & EXYNOS3250_HEADER_STAT) &&
   2801	    (curr_ctx->mode == S5P_JPEG_DECODE)) {
   2802		exynos3250_jpeg_rstart(jpeg->regs);
   2803		goto exit_unlock;
   2804	}
   2805
   2806	if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
   2807				EXYNOS3250_WDMA_DONE |
   2808				EXYNOS3250_RDMA_DONE |
   2809				EXYNOS3250_RESULT_STAT))
   2810		payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
   2811	else if (interrupt_timeout || stream_error)
   2812		state = VB2_BUF_STATE_ERROR;
   2813	else
   2814		goto exit_unlock;
   2815
   2816	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
   2817	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
   2818
   2819	dst_buf->timecode = src_buf->timecode;
   2820	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
   2821
   2822	v4l2_m2m_buf_done(src_buf, state);
   2823	if (curr_ctx->mode == S5P_JPEG_ENCODE)
   2824		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
   2825	v4l2_m2m_buf_done(dst_buf, state);
   2826
   2827	curr_ctx->subsampling =
   2828			exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
   2829
   2830	spin_unlock(&jpeg->slock);
   2831
   2832	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
   2833	return IRQ_HANDLED;
   2834
   2835exit_unlock:
   2836	spin_unlock(&jpeg->slock);
   2837	return IRQ_HANDLED;
   2838}
   2839
   2840static void *jpeg_get_drv_data(struct device *dev);
   2841
   2842/*
   2843 * ============================================================================
   2844 * Driver basic infrastructure
   2845 * ============================================================================
   2846 */
   2847
   2848static int s5p_jpeg_probe(struct platform_device *pdev)
   2849{
   2850	struct s5p_jpeg *jpeg;
   2851	int i, ret;
   2852
   2853	/* JPEG IP abstraction struct */
   2854	jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
   2855	if (!jpeg)
   2856		return -ENOMEM;
   2857
   2858	jpeg->variant = jpeg_get_drv_data(&pdev->dev);
   2859	if (!jpeg->variant)
   2860		return -ENODEV;
   2861
   2862	mutex_init(&jpeg->lock);
   2863	spin_lock_init(&jpeg->slock);
   2864	jpeg->dev = &pdev->dev;
   2865
   2866	/* memory-mapped registers */
   2867	jpeg->regs = devm_platform_ioremap_resource(pdev, 0);
   2868	if (IS_ERR(jpeg->regs))
   2869		return PTR_ERR(jpeg->regs);
   2870
   2871	/* interrupt service routine registration */
   2872	jpeg->irq = ret = platform_get_irq(pdev, 0);
   2873	if (ret < 0) {
   2874		dev_err(&pdev->dev, "cannot find IRQ\n");
   2875		return ret;
   2876	}
   2877
   2878	ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
   2879				0, dev_name(&pdev->dev), jpeg);
   2880	if (ret) {
   2881		dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
   2882		return ret;
   2883	}
   2884
   2885	/* clocks */
   2886	for (i = 0; i < jpeg->variant->num_clocks; i++) {
   2887		jpeg->clocks[i] = devm_clk_get(&pdev->dev,
   2888					      jpeg->variant->clk_names[i]);
   2889		if (IS_ERR(jpeg->clocks[i])) {
   2890			dev_err(&pdev->dev, "failed to get clock: %s\n",
   2891				jpeg->variant->clk_names[i]);
   2892			return PTR_ERR(jpeg->clocks[i]);
   2893		}
   2894	}
   2895
   2896	/* v4l2 device */
   2897	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
   2898	if (ret) {
   2899		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
   2900		return ret;
   2901	}
   2902
   2903	/* mem2mem device */
   2904	jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
   2905	if (IS_ERR(jpeg->m2m_dev)) {
   2906		v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
   2907		ret = PTR_ERR(jpeg->m2m_dev);
   2908		goto device_register_rollback;
   2909	}
   2910
   2911	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
   2912
   2913	/* JPEG encoder /dev/videoX node */
   2914	jpeg->vfd_encoder = video_device_alloc();
   2915	if (!jpeg->vfd_encoder) {
   2916		v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
   2917		ret = -ENOMEM;
   2918		goto m2m_init_rollback;
   2919	}
   2920	snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
   2921				"%s-enc", S5P_JPEG_M2M_NAME);
   2922	jpeg->vfd_encoder->fops		= &s5p_jpeg_fops;
   2923	jpeg->vfd_encoder->ioctl_ops	= &s5p_jpeg_ioctl_ops;
   2924	jpeg->vfd_encoder->minor	= -1;
   2925	jpeg->vfd_encoder->release	= video_device_release;
   2926	jpeg->vfd_encoder->lock		= &jpeg->lock;
   2927	jpeg->vfd_encoder->v4l2_dev	= &jpeg->v4l2_dev;
   2928	jpeg->vfd_encoder->vfl_dir	= VFL_DIR_M2M;
   2929	jpeg->vfd_encoder->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
   2930
   2931	ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_VIDEO, -1);
   2932	if (ret) {
   2933		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
   2934		video_device_release(jpeg->vfd_encoder);
   2935		goto m2m_init_rollback;
   2936	}
   2937
   2938	video_set_drvdata(jpeg->vfd_encoder, jpeg);
   2939	v4l2_info(&jpeg->v4l2_dev,
   2940		  "encoder device registered as /dev/video%d\n",
   2941		  jpeg->vfd_encoder->num);
   2942
   2943	/* JPEG decoder /dev/videoX node */
   2944	jpeg->vfd_decoder = video_device_alloc();
   2945	if (!jpeg->vfd_decoder) {
   2946		v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
   2947		ret = -ENOMEM;
   2948		goto enc_vdev_register_rollback;
   2949	}
   2950	snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
   2951				"%s-dec", S5P_JPEG_M2M_NAME);
   2952	jpeg->vfd_decoder->fops		= &s5p_jpeg_fops;
   2953	jpeg->vfd_decoder->ioctl_ops	= &s5p_jpeg_ioctl_ops;
   2954	jpeg->vfd_decoder->minor	= -1;
   2955	jpeg->vfd_decoder->release	= video_device_release;
   2956	jpeg->vfd_decoder->lock		= &jpeg->lock;
   2957	jpeg->vfd_decoder->v4l2_dev	= &jpeg->v4l2_dev;
   2958	jpeg->vfd_decoder->vfl_dir	= VFL_DIR_M2M;
   2959	jpeg->vfd_decoder->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
   2960
   2961	ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_VIDEO, -1);
   2962	if (ret) {
   2963		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
   2964		video_device_release(jpeg->vfd_decoder);
   2965		goto enc_vdev_register_rollback;
   2966	}
   2967
   2968	video_set_drvdata(jpeg->vfd_decoder, jpeg);
   2969	v4l2_info(&jpeg->v4l2_dev,
   2970		  "decoder device registered as /dev/video%d\n",
   2971		  jpeg->vfd_decoder->num);
   2972
   2973	/* final statements & power management */
   2974	platform_set_drvdata(pdev, jpeg);
   2975
   2976	pm_runtime_enable(&pdev->dev);
   2977
   2978	v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
   2979
   2980	return 0;
   2981
   2982enc_vdev_register_rollback:
   2983	video_unregister_device(jpeg->vfd_encoder);
   2984
   2985m2m_init_rollback:
   2986	v4l2_m2m_release(jpeg->m2m_dev);
   2987
   2988device_register_rollback:
   2989	v4l2_device_unregister(&jpeg->v4l2_dev);
   2990
   2991	return ret;
   2992}
   2993
   2994static int s5p_jpeg_remove(struct platform_device *pdev)
   2995{
   2996	struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
   2997	int i;
   2998
   2999	pm_runtime_disable(jpeg->dev);
   3000
   3001	video_unregister_device(jpeg->vfd_decoder);
   3002	video_unregister_device(jpeg->vfd_encoder);
   3003	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
   3004	v4l2_m2m_release(jpeg->m2m_dev);
   3005	v4l2_device_unregister(&jpeg->v4l2_dev);
   3006
   3007	if (!pm_runtime_status_suspended(&pdev->dev)) {
   3008		for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
   3009			clk_disable_unprepare(jpeg->clocks[i]);
   3010	}
   3011
   3012	return 0;
   3013}
   3014
   3015#ifdef CONFIG_PM
   3016static int s5p_jpeg_runtime_suspend(struct device *dev)
   3017{
   3018	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
   3019	int i;
   3020
   3021	for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
   3022		clk_disable_unprepare(jpeg->clocks[i]);
   3023
   3024	return 0;
   3025}
   3026
   3027static int s5p_jpeg_runtime_resume(struct device *dev)
   3028{
   3029	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
   3030	unsigned long flags;
   3031	int i, ret;
   3032
   3033	for (i = 0; i < jpeg->variant->num_clocks; i++) {
   3034		ret = clk_prepare_enable(jpeg->clocks[i]);
   3035		if (ret) {
   3036			while (--i >= 0)
   3037				clk_disable_unprepare(jpeg->clocks[i]);
   3038			return ret;
   3039		}
   3040	}
   3041
   3042	spin_lock_irqsave(&jpeg->slock, flags);
   3043
   3044	/*
   3045	 * JPEG IP allows storing two Huffman tables for each component.
   3046	 * We fill table 0 for each component and do this here only
   3047	 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
   3048	 * require programming their Huffman tables each time the encoding
   3049	 * process is initialized, and thus it is accomplished in the
   3050	 * device_run callback of m2m_ops.
   3051	 */
   3052	if (!jpeg->variant->htbl_reinit) {
   3053		s5p_jpeg_set_hdctbl(jpeg->regs);
   3054		s5p_jpeg_set_hdctblg(jpeg->regs);
   3055		s5p_jpeg_set_hactbl(jpeg->regs);
   3056		s5p_jpeg_set_hactblg(jpeg->regs);
   3057	}
   3058
   3059	spin_unlock_irqrestore(&jpeg->slock, flags);
   3060
   3061	return 0;
   3062}
   3063#endif /* CONFIG_PM */
   3064
   3065static const struct dev_pm_ops s5p_jpeg_pm_ops = {
   3066	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
   3067				pm_runtime_force_resume)
   3068	SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume,
   3069			   NULL)
   3070};
   3071
   3072static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
   3073	.version	= SJPEG_S5P,
   3074	.jpeg_irq	= s5p_jpeg_irq,
   3075	.m2m_ops	= &s5p_jpeg_m2m_ops,
   3076	.fmt_ver_flag	= SJPEG_FMT_FLAG_S5P,
   3077	.clk_names	= {"jpeg"},
   3078	.num_clocks	= 1,
   3079};
   3080
   3081static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
   3082	.version	= SJPEG_EXYNOS3250,
   3083	.jpeg_irq	= exynos3250_jpeg_irq,
   3084	.m2m_ops	= &exynos3250_jpeg_m2m_ops,
   3085	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS3250,
   3086	.hw3250_compat	= 1,
   3087	.clk_names	= {"jpeg", "sclk"},
   3088	.num_clocks	= 2,
   3089};
   3090
   3091static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
   3092	.version	= SJPEG_EXYNOS4,
   3093	.jpeg_irq	= exynos4_jpeg_irq,
   3094	.m2m_ops	= &exynos4_jpeg_m2m_ops,
   3095	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS4,
   3096	.htbl_reinit	= 1,
   3097	.clk_names	= {"jpeg"},
   3098	.num_clocks	= 1,
   3099	.hw_ex4_compat	= 1,
   3100};
   3101
   3102static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
   3103	.version	= SJPEG_EXYNOS5420,
   3104	.jpeg_irq	= exynos3250_jpeg_irq,		/* intentionally 3250 */
   3105	.m2m_ops	= &exynos3250_jpeg_m2m_ops,	/* intentionally 3250 */
   3106	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS3250,	/* intentionally 3250 */
   3107	.hw3250_compat	= 1,
   3108	.htbl_reinit	= 1,
   3109	.clk_names	= {"jpeg"},
   3110	.num_clocks	= 1,
   3111};
   3112
   3113static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
   3114	.version	= SJPEG_EXYNOS5433,
   3115	.jpeg_irq	= exynos4_jpeg_irq,
   3116	.m2m_ops	= &exynos4_jpeg_m2m_ops,
   3117	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS4,
   3118	.htbl_reinit	= 1,
   3119	.clk_names	= {"pclk", "aclk", "aclk_xiu", "sclk"},
   3120	.num_clocks	= 4,
   3121	.hw_ex4_compat	= 1,
   3122};
   3123
   3124static const struct of_device_id samsung_jpeg_match[] = {
   3125	{
   3126		.compatible = "samsung,s5pv210-jpeg",
   3127		.data = &s5p_jpeg_drvdata,
   3128	}, {
   3129		.compatible = "samsung,exynos3250-jpeg",
   3130		.data = &exynos3250_jpeg_drvdata,
   3131	}, {
   3132		.compatible = "samsung,exynos4210-jpeg",
   3133		.data = &exynos4_jpeg_drvdata,
   3134	}, {
   3135		.compatible = "samsung,exynos4212-jpeg",
   3136		.data = &exynos4_jpeg_drvdata,
   3137	}, {
   3138		.compatible = "samsung,exynos5420-jpeg",
   3139		.data = &exynos5420_jpeg_drvdata,
   3140	}, {
   3141		.compatible = "samsung,exynos5433-jpeg",
   3142		.data = &exynos5433_jpeg_drvdata,
   3143	},
   3144	{},
   3145};
   3146
   3147MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
   3148
   3149static void *jpeg_get_drv_data(struct device *dev)
   3150{
   3151	struct s5p_jpeg_variant *driver_data = NULL;
   3152	const struct of_device_id *match;
   3153
   3154	if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
   3155		return &s5p_jpeg_drvdata;
   3156
   3157	match = of_match_node(samsung_jpeg_match, dev->of_node);
   3158
   3159	if (match)
   3160		driver_data = (struct s5p_jpeg_variant *)match->data;
   3161
   3162	return driver_data;
   3163}
   3164
   3165static struct platform_driver s5p_jpeg_driver = {
   3166	.probe = s5p_jpeg_probe,
   3167	.remove = s5p_jpeg_remove,
   3168	.driver = {
   3169		.of_match_table	= of_match_ptr(samsung_jpeg_match),
   3170		.name		= S5P_JPEG_M2M_NAME,
   3171		.pm		= &s5p_jpeg_pm_ops,
   3172	},
   3173};
   3174
   3175module_platform_driver(s5p_jpeg_driver);
   3176
   3177MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>");
   3178MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
   3179MODULE_DESCRIPTION("Samsung JPEG codec driver");
   3180MODULE_LICENSE("GPL");