1f4104b78SMauro Carvalho Chehab /* SPDX-License-Identifier: GPL-2.0-only */
2f4104b78SMauro Carvalho Chehab /* linux/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.h
3f4104b78SMauro Carvalho Chehab  *
4f4104b78SMauro Carvalho Chehab  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5f4104b78SMauro Carvalho Chehab  *		http://www.samsung.com
6f4104b78SMauro Carvalho Chehab  *
7f4104b78SMauro Carvalho Chehab  * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
8f4104b78SMauro Carvalho Chehab  */
9f4104b78SMauro Carvalho Chehab 
10f4104b78SMauro Carvalho Chehab #ifndef JPEG_CORE_H_
11f4104b78SMauro Carvalho Chehab #define JPEG_CORE_H_
12f4104b78SMauro Carvalho Chehab 
13f4104b78SMauro Carvalho Chehab #include <linux/interrupt.h>
14*72a6127eSGeert Uytterhoeven #include <media/jpeg.h>
15f4104b78SMauro Carvalho Chehab #include <media/v4l2-device.h>
16f4104b78SMauro Carvalho Chehab #include <media/v4l2-fh.h>
17f4104b78SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
18f4104b78SMauro Carvalho Chehab 
19f4104b78SMauro Carvalho Chehab #define S5P_JPEG_M2M_NAME		"s5p-jpeg"
20f4104b78SMauro Carvalho Chehab 
21f4104b78SMauro Carvalho Chehab #define JPEG_MAX_CLOCKS			4
22f4104b78SMauro Carvalho Chehab 
23f4104b78SMauro Carvalho Chehab /* JPEG compression quality setting */
24f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COMPR_QUAL_BEST	0
25f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COMPR_QUAL_WORST	3
26f4104b78SMauro Carvalho Chehab 
27f4104b78SMauro Carvalho Chehab /* JPEG RGB to YCbCr conversion matrix coefficients */
28f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF11			0x4d
29f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF12			0x97
30f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF13			0x1e
31f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF21			0x2c
32f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF22			0x57
33f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF23			0x83
34f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF31			0x83
35f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF32			0x6e
36f4104b78SMauro Carvalho Chehab #define S5P_JPEG_COEF33			0x13
37f4104b78SMauro Carvalho Chehab 
38f4104b78SMauro Carvalho Chehab #define EXYNOS3250_IRQ_TIMEOUT		0x10000000
39f4104b78SMauro Carvalho Chehab 
40f4104b78SMauro Carvalho Chehab /* Flags that indicate a format can be used for capture/output */
41f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_ENC_CAPTURE	(1 << 0)
42f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_ENC_OUTPUT	(1 << 1)
43f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_DEC_CAPTURE	(1 << 2)
44f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_DEC_OUTPUT	(1 << 3)
45f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_S5P		(1 << 4)
46f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_EXYNOS3250	(1 << 5)
47f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_FLAG_EXYNOS4		(1 << 6)
48f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_RGB			(1 << 7)
49f4104b78SMauro Carvalho Chehab #define SJPEG_FMT_NON_RGB		(1 << 8)
50f4104b78SMauro Carvalho Chehab 
51f4104b78SMauro Carvalho Chehab #define S5P_JPEG_ENCODE		0
52f4104b78SMauro Carvalho Chehab #define S5P_JPEG_DECODE		1
53f4104b78SMauro Carvalho Chehab #define S5P_JPEG_DISABLE	-1
54f4104b78SMauro Carvalho Chehab 
55f4104b78SMauro Carvalho Chehab #define FMT_TYPE_OUTPUT		0
56f4104b78SMauro Carvalho Chehab #define FMT_TYPE_CAPTURE	1
57f4104b78SMauro Carvalho Chehab 
58f4104b78SMauro Carvalho Chehab #define SJPEG_SUBSAMPLING_444	0x11
59f4104b78SMauro Carvalho Chehab #define SJPEG_SUBSAMPLING_422	0x21
60f4104b78SMauro Carvalho Chehab #define SJPEG_SUBSAMPLING_420	0x22
61f4104b78SMauro Carvalho Chehab 
62f4104b78SMauro Carvalho Chehab #define S5P_JPEG_MAX_MARKER	4
63f4104b78SMauro Carvalho Chehab 
64f4104b78SMauro Carvalho Chehab /* Version numbers */
65f4104b78SMauro Carvalho Chehab enum sjpeg_version {
66f4104b78SMauro Carvalho Chehab 	SJPEG_S5P,
67f4104b78SMauro Carvalho Chehab 	SJPEG_EXYNOS3250,
68f4104b78SMauro Carvalho Chehab 	SJPEG_EXYNOS4,
69f4104b78SMauro Carvalho Chehab 	SJPEG_EXYNOS5420,
70f4104b78SMauro Carvalho Chehab 	SJPEG_EXYNOS5433,
71f4104b78SMauro Carvalho Chehab };
72f4104b78SMauro Carvalho Chehab 
73f4104b78SMauro Carvalho Chehab enum exynos4_jpeg_result {
74f4104b78SMauro Carvalho Chehab 	OK_ENC_OR_DEC,
75f4104b78SMauro Carvalho Chehab 	ERR_PROT,
76f4104b78SMauro Carvalho Chehab 	ERR_DEC_INVALID_FORMAT,
77f4104b78SMauro Carvalho Chehab 	ERR_MULTI_SCAN,
78f4104b78SMauro Carvalho Chehab 	ERR_FRAME,
79f4104b78SMauro Carvalho Chehab 	ERR_UNKNOWN,
80f4104b78SMauro Carvalho Chehab };
81f4104b78SMauro Carvalho Chehab 
82f4104b78SMauro Carvalho Chehab enum  exynos4_jpeg_img_quality_level {
83f4104b78SMauro Carvalho Chehab 	QUALITY_LEVEL_1 = 0,	/* high */
84f4104b78SMauro Carvalho Chehab 	QUALITY_LEVEL_2,
85f4104b78SMauro Carvalho Chehab 	QUALITY_LEVEL_3,
86f4104b78SMauro Carvalho Chehab 	QUALITY_LEVEL_4,	/* low */
87f4104b78SMauro Carvalho Chehab };
88f4104b78SMauro Carvalho Chehab 
89f4104b78SMauro Carvalho Chehab enum s5p_jpeg_ctx_state {
90f4104b78SMauro Carvalho Chehab 	JPEGCTX_RUNNING = 0,
91f4104b78SMauro Carvalho Chehab 	JPEGCTX_RESOLUTION_CHANGE,
92f4104b78SMauro Carvalho Chehab };
93f4104b78SMauro Carvalho Chehab 
94f4104b78SMauro Carvalho Chehab /**
95f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg - JPEG IP abstraction
96f4104b78SMauro Carvalho Chehab  * @lock:		the mutex protecting this structure
97f4104b78SMauro Carvalho Chehab  * @slock:		spinlock protecting the device contexts
98f4104b78SMauro Carvalho Chehab  * @v4l2_dev:		v4l2 device for mem2mem mode
99f4104b78SMauro Carvalho Chehab  * @vfd_encoder:	video device node for encoder mem2mem mode
100f4104b78SMauro Carvalho Chehab  * @vfd_decoder:	video device node for decoder mem2mem mode
101f4104b78SMauro Carvalho Chehab  * @m2m_dev:		v4l2 mem2mem device data
102f4104b78SMauro Carvalho Chehab  * @regs:		JPEG IP registers mapping
103f4104b78SMauro Carvalho Chehab  * @irq:		JPEG IP irq
104f4104b78SMauro Carvalho Chehab  * @irq_ret:		JPEG IP irq result value
105f4104b78SMauro Carvalho Chehab  * @clocks:		JPEG IP clock(s)
106f4104b78SMauro Carvalho Chehab  * @dev:		JPEG IP struct device
107f4104b78SMauro Carvalho Chehab  * @variant:		driver variant to be used
108f4104b78SMauro Carvalho Chehab  * @irq_status:		interrupt flags set during single encode/decode
109f4104b78SMauro Carvalho Chehab  *			operation
110f4104b78SMauro Carvalho Chehab  */
111f4104b78SMauro Carvalho Chehab struct s5p_jpeg {
112f4104b78SMauro Carvalho Chehab 	struct mutex		lock;
113f4104b78SMauro Carvalho Chehab 	spinlock_t		slock;
114f4104b78SMauro Carvalho Chehab 
115f4104b78SMauro Carvalho Chehab 	struct v4l2_device	v4l2_dev;
116f4104b78SMauro Carvalho Chehab 	struct video_device	*vfd_encoder;
117f4104b78SMauro Carvalho Chehab 	struct video_device	*vfd_decoder;
118f4104b78SMauro Carvalho Chehab 	struct v4l2_m2m_dev	*m2m_dev;
119f4104b78SMauro Carvalho Chehab 
120f4104b78SMauro Carvalho Chehab 	void __iomem		*regs;
121f4104b78SMauro Carvalho Chehab 	unsigned int		irq;
122f4104b78SMauro Carvalho Chehab 	enum exynos4_jpeg_result irq_ret;
123f4104b78SMauro Carvalho Chehab 	struct clk		*clocks[JPEG_MAX_CLOCKS];
124f4104b78SMauro Carvalho Chehab 	struct device		*dev;
125f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg_variant *variant;
126f4104b78SMauro Carvalho Chehab 	u32			irq_status;
127f4104b78SMauro Carvalho Chehab };
128f4104b78SMauro Carvalho Chehab 
129f4104b78SMauro Carvalho Chehab struct s5p_jpeg_variant {
130f4104b78SMauro Carvalho Chehab 	unsigned int		version;
131f4104b78SMauro Carvalho Chehab 	unsigned int		fmt_ver_flag;
132f4104b78SMauro Carvalho Chehab 	unsigned int		hw3250_compat:1;
133f4104b78SMauro Carvalho Chehab 	unsigned int		htbl_reinit:1;
134f4104b78SMauro Carvalho Chehab 	unsigned int		hw_ex4_compat:1;
135f4104b78SMauro Carvalho Chehab 	const struct v4l2_m2m_ops *m2m_ops;
136f4104b78SMauro Carvalho Chehab 	irqreturn_t		(*jpeg_irq)(int irq, void *priv);
137f4104b78SMauro Carvalho Chehab 	const char		*clk_names[JPEG_MAX_CLOCKS];
138f4104b78SMauro Carvalho Chehab 	int			num_clocks;
139f4104b78SMauro Carvalho Chehab };
140f4104b78SMauro Carvalho Chehab 
141f4104b78SMauro Carvalho Chehab /**
142f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg_fmt - driver's internal color format data
143f4104b78SMauro Carvalho Chehab  * @fourcc:	the fourcc code, 0 if not applicable
144f4104b78SMauro Carvalho Chehab  * @depth:	number of bits per pixel
145f4104b78SMauro Carvalho Chehab  * @colplanes:	number of color planes (1 for packed formats)
146f4104b78SMauro Carvalho Chehab  * @memplanes:	number of memory planes (1 for packed formats)
147f4104b78SMauro Carvalho Chehab  * @h_align:	horizontal alignment order (align to 2^h_align)
148f4104b78SMauro Carvalho Chehab  * @v_align:	vertical alignment order (align to 2^v_align)
149f4104b78SMauro Carvalho Chehab  * @subsampling:subsampling of a raw format or a JPEG
150f4104b78SMauro Carvalho Chehab  * @flags:	flags describing format applicability
151f4104b78SMauro Carvalho Chehab  */
152f4104b78SMauro Carvalho Chehab struct s5p_jpeg_fmt {
153f4104b78SMauro Carvalho Chehab 	u32	fourcc;
154f4104b78SMauro Carvalho Chehab 	int	depth;
155f4104b78SMauro Carvalho Chehab 	int	colplanes;
156f4104b78SMauro Carvalho Chehab 	int	memplanes;
157f4104b78SMauro Carvalho Chehab 	int	h_align;
158f4104b78SMauro Carvalho Chehab 	int	v_align;
159f4104b78SMauro Carvalho Chehab 	int	subsampling;
160f4104b78SMauro Carvalho Chehab 	u32	flags;
161f4104b78SMauro Carvalho Chehab };
162f4104b78SMauro Carvalho Chehab 
163f4104b78SMauro Carvalho Chehab /**
164f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg_marker - collection of markers from jpeg header
165f4104b78SMauro Carvalho Chehab  * @marker:	markers' positions relative to the buffer beginning
166f4104b78SMauro Carvalho Chehab  * @len:	markers' payload lengths (without length field)
167f4104b78SMauro Carvalho Chehab  * @n:		number of markers in collection
168f4104b78SMauro Carvalho Chehab  */
169f4104b78SMauro Carvalho Chehab struct s5p_jpeg_marker {
170f4104b78SMauro Carvalho Chehab 	u32	marker[S5P_JPEG_MAX_MARKER];
171f4104b78SMauro Carvalho Chehab 	u32	len[S5P_JPEG_MAX_MARKER];
172f4104b78SMauro Carvalho Chehab 	u32	n;
173f4104b78SMauro Carvalho Chehab };
174f4104b78SMauro Carvalho Chehab 
175f4104b78SMauro Carvalho Chehab /**
176f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg_q_data - parameters of one queue
177f4104b78SMauro Carvalho Chehab  * @fmt:	driver-specific format of this queue
178f4104b78SMauro Carvalho Chehab  * @w:		image width
179f4104b78SMauro Carvalho Chehab  * @h:		image height
180f4104b78SMauro Carvalho Chehab  * @sos:	JPEG_MARKER_SOS's position relative to the buffer beginning
181f4104b78SMauro Carvalho Chehab  * @dht:	JPEG_MARKER_DHT' positions relative to the buffer beginning
182f4104b78SMauro Carvalho Chehab  * @dqt:	JPEG_MARKER_DQT' positions relative to the buffer beginning
183f4104b78SMauro Carvalho Chehab  * @sof:	JPEG_MARKER_SOF0's position relative to the buffer beginning
184f4104b78SMauro Carvalho Chehab  * @sof_len:	JPEG_MARKER_SOF0's payload length (without length field itself)
185f4104b78SMauro Carvalho Chehab  * @size:	image buffer size in bytes
186f4104b78SMauro Carvalho Chehab  */
187f4104b78SMauro Carvalho Chehab struct s5p_jpeg_q_data {
188f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg_fmt	*fmt;
189f4104b78SMauro Carvalho Chehab 	u32			w;
190f4104b78SMauro Carvalho Chehab 	u32			h;
191f4104b78SMauro Carvalho Chehab 	u32			sos;
192f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg_marker	dht;
193f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg_marker	dqt;
194f4104b78SMauro Carvalho Chehab 	u32			sof;
195f4104b78SMauro Carvalho Chehab 	u32			sof_len;
196f4104b78SMauro Carvalho Chehab 	u32			size;
197f4104b78SMauro Carvalho Chehab };
198f4104b78SMauro Carvalho Chehab 
199f4104b78SMauro Carvalho Chehab /**
200f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg_ctx - the device context data
201f4104b78SMauro Carvalho Chehab  * @jpeg:		JPEG IP device for this context
202f4104b78SMauro Carvalho Chehab  * @mode:		compression (encode) operation or decompression (decode)
203f4104b78SMauro Carvalho Chehab  * @compr_quality:	destination image quality in compression (encode) mode
204f4104b78SMauro Carvalho Chehab  * @restart_interval:	JPEG restart interval for JPEG encoding
205f4104b78SMauro Carvalho Chehab  * @subsampling:	subsampling of a raw format or a JPEG
206f4104b78SMauro Carvalho Chehab  * @out_q:		source (output) queue information
207f4104b78SMauro Carvalho Chehab  * @cap_q:		destination (capture) queue queue information
208f4104b78SMauro Carvalho Chehab  * @scale_factor:	scale factor for JPEG decoding
209f4104b78SMauro Carvalho Chehab  * @crop_rect:		a rectangle representing crop area of the output buffer
210f4104b78SMauro Carvalho Chehab  * @fh:			V4L2 file handle
211f4104b78SMauro Carvalho Chehab  * @hdr_parsed:		set if header has been parsed during decompression
212f4104b78SMauro Carvalho Chehab  * @crop_altered:	set if crop rectangle has been altered by the user space
213f4104b78SMauro Carvalho Chehab  * @ctrl_handler:	controls handler
214f4104b78SMauro Carvalho Chehab  * @state:		state of the context
215f4104b78SMauro Carvalho Chehab  */
216f4104b78SMauro Carvalho Chehab struct s5p_jpeg_ctx {
217f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg		*jpeg;
218f4104b78SMauro Carvalho Chehab 	unsigned int		mode;
219f4104b78SMauro Carvalho Chehab 	unsigned short		compr_quality;
220f4104b78SMauro Carvalho Chehab 	unsigned short		restart_interval;
221f4104b78SMauro Carvalho Chehab 	unsigned short		subsampling;
222f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg_q_data	out_q;
223f4104b78SMauro Carvalho Chehab 	struct s5p_jpeg_q_data	cap_q;
224f4104b78SMauro Carvalho Chehab 	unsigned int		scale_factor;
225f4104b78SMauro Carvalho Chehab 	struct v4l2_rect	crop_rect;
226f4104b78SMauro Carvalho Chehab 	struct v4l2_fh		fh;
227f4104b78SMauro Carvalho Chehab 	bool			hdr_parsed;
228f4104b78SMauro Carvalho Chehab 	bool			crop_altered;
229f4104b78SMauro Carvalho Chehab 	struct v4l2_ctrl_handler ctrl_handler;
230f4104b78SMauro Carvalho Chehab 	enum s5p_jpeg_ctx_state	state;
231f4104b78SMauro Carvalho Chehab };
232f4104b78SMauro Carvalho Chehab 
233f4104b78SMauro Carvalho Chehab /**
234f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg_buffer - description of memory containing input JPEG data
235f4104b78SMauro Carvalho Chehab  * @size:	buffer size
236f4104b78SMauro Carvalho Chehab  * @curr:	current position in the buffer
237f4104b78SMauro Carvalho Chehab  * @data:	pointer to the data
238f4104b78SMauro Carvalho Chehab  */
239f4104b78SMauro Carvalho Chehab struct s5p_jpeg_buffer {
240f4104b78SMauro Carvalho Chehab 	unsigned long size;
241f4104b78SMauro Carvalho Chehab 	unsigned long curr;
242f4104b78SMauro Carvalho Chehab 	unsigned long data;
243f4104b78SMauro Carvalho Chehab };
244f4104b78SMauro Carvalho Chehab 
245f4104b78SMauro Carvalho Chehab /**
246f4104b78SMauro Carvalho Chehab  * struct s5p_jpeg_addr - JPEG converter physical address set for DMA
247f4104b78SMauro Carvalho Chehab  * @y:   luminance plane physical address
248f4104b78SMauro Carvalho Chehab  * @cb:  Cb plane physical address
249f4104b78SMauro Carvalho Chehab  * @cr:  Cr plane physical address
250f4104b78SMauro Carvalho Chehab  */
251f4104b78SMauro Carvalho Chehab struct s5p_jpeg_addr {
252f4104b78SMauro Carvalho Chehab 	u32     y;
253f4104b78SMauro Carvalho Chehab 	u32     cb;
254f4104b78SMauro Carvalho Chehab 	u32     cr;
255f4104b78SMauro Carvalho Chehab };
256f4104b78SMauro Carvalho Chehab 
257f4104b78SMauro Carvalho Chehab #endif /* JPEG_CORE_H */
258