xref: /linux/drivers/media/platform/aspeed/aspeed-video.c (revision a63f7778f76e1cf8ed3bcb7a1d9453c9609121ad)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 // Copyright 2020 IBM Corp.
3 // Copyright (c) 2019-2020 Intel Corporation
4 
5 #include <linux/atomic.h>
6 #include <linux/bitfield.h>
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/interrupt.h>
12 #include <linux/jiffies.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/of.h>
16 #include <linux/of_device.h>
17 #include <linux/of_irq.h>
18 #include <linux/of_reserved_mem.h>
19 #include <linux/platform_device.h>
20 #include <linux/sched.h>
21 #include <linux/spinlock.h>
22 #include <linux/string.h>
23 #include <linux/v4l2-controls.h>
24 #include <linux/videodev2.h>
25 #include <linux/wait.h>
26 #include <linux/workqueue.h>
27 #include <linux/debugfs.h>
28 #include <linux/ktime.h>
29 #include <media/v4l2-ctrls.h>
30 #include <media/v4l2-dev.h>
31 #include <media/v4l2-device.h>
32 #include <media/v4l2-dv-timings.h>
33 #include <media/v4l2-event.h>
34 #include <media/v4l2-ioctl.h>
35 #include <media/videobuf2-dma-contig.h>
36 
37 #define ASPEED_VIDEO_V4L2_MIN_BUF_REQ 3
38 
39 #define DEVICE_NAME			"aspeed-video"
40 
41 #define ASPEED_VIDEO_JPEG_NUM_QUALITIES	12
42 #define ASPEED_VIDEO_JPEG_HEADER_SIZE	10
43 #define ASPEED_VIDEO_JPEG_QUANT_SIZE	116
44 #define ASPEED_VIDEO_JPEG_DCT_SIZE	34
45 
46 #define MAX_FRAME_RATE			60
47 #define MAX_HEIGHT			1200
48 #define MAX_WIDTH			1920
49 #define MIN_HEIGHT			480
50 #define MIN_WIDTH			640
51 
52 #define NUM_POLARITY_CHECKS		10
53 #define INVALID_RESOLUTION_RETRIES	2
54 #define INVALID_RESOLUTION_DELAY	msecs_to_jiffies(250)
55 #define RESOLUTION_CHANGE_DELAY		msecs_to_jiffies(500)
56 #define MODE_DETECT_TIMEOUT		msecs_to_jiffies(500)
57 #define STOP_TIMEOUT			msecs_to_jiffies(1000)
58 #define DIRECT_FETCH_THRESHOLD		0x0c0000 /* 1024 * 768 */
59 
60 #define VE_MAX_SRC_BUFFER_SIZE		0x8ca000 /* 1920 * 1200, 32bpp */
61 #define VE_JPEG_HEADER_SIZE		0x006000 /* 512 * 12 * 4 */
62 
63 #define VE_PROTECTION_KEY		0x000
64 #define  VE_PROTECTION_KEY_UNLOCK	0x1a038aa8
65 
66 #define VE_SEQ_CTRL			0x004
67 #define  VE_SEQ_CTRL_TRIG_MODE_DET	BIT(0)
68 #define  VE_SEQ_CTRL_TRIG_CAPTURE	BIT(1)
69 #define  VE_SEQ_CTRL_FORCE_IDLE		BIT(2)
70 #define  VE_SEQ_CTRL_MULT_FRAME		BIT(3)
71 #define  VE_SEQ_CTRL_TRIG_COMP		BIT(4)
72 #define  VE_SEQ_CTRL_AUTO_COMP		BIT(5)
73 #define  VE_SEQ_CTRL_EN_WATCHDOG	BIT(7)
74 #define  VE_SEQ_CTRL_YUV420		BIT(10)
75 #define  VE_SEQ_CTRL_COMP_FMT		GENMASK(11, 10)
76 #define  VE_SEQ_CTRL_HALT		BIT(12)
77 #define  VE_SEQ_CTRL_EN_WATCHDOG_COMP	BIT(14)
78 #define  VE_SEQ_CTRL_TRIG_JPG		BIT(15)
79 #define  VE_SEQ_CTRL_CAP_BUSY		BIT(16)
80 #define  VE_SEQ_CTRL_COMP_BUSY		BIT(18)
81 
82 #define AST2500_VE_SEQ_CTRL_JPEG_MODE	BIT(13)
83 #define AST2400_VE_SEQ_CTRL_JPEG_MODE	BIT(8)
84 
85 #define VE_CTRL				0x008
86 #define  VE_CTRL_HSYNC_POL		BIT(0)
87 #define  VE_CTRL_VSYNC_POL		BIT(1)
88 #define  VE_CTRL_SOURCE			BIT(2)
89 #define  VE_CTRL_INT_DE			BIT(4)
90 #define  VE_CTRL_DIRECT_FETCH		BIT(5)
91 #define  VE_CTRL_CAPTURE_FMT		GENMASK(7, 6)
92 #define  VE_CTRL_AUTO_OR_CURSOR		BIT(8)
93 #define  VE_CTRL_CLK_INVERSE		BIT(11)
94 #define  VE_CTRL_CLK_DELAY		GENMASK(11, 9)
95 #define  VE_CTRL_INTERLACE		BIT(14)
96 #define  VE_CTRL_HSYNC_POL_CTRL		BIT(15)
97 #define  VE_CTRL_FRC			GENMASK(23, 16)
98 
99 #define VE_TGS_0			0x00c
100 #define VE_TGS_1			0x010
101 #define  VE_TGS_FIRST			GENMASK(28, 16)
102 #define  VE_TGS_LAST			GENMASK(12, 0)
103 
104 #define VE_SCALING_FACTOR		0x014
105 #define VE_SCALING_FILTER0		0x018
106 #define VE_SCALING_FILTER1		0x01c
107 #define VE_SCALING_FILTER2		0x020
108 #define VE_SCALING_FILTER3		0x024
109 
110 #define VE_CAP_WINDOW			0x030
111 #define VE_COMP_WINDOW			0x034
112 #define VE_COMP_PROC_OFFSET		0x038
113 #define VE_COMP_OFFSET			0x03c
114 #define VE_JPEG_ADDR			0x040
115 #define VE_SRC0_ADDR			0x044
116 #define VE_SRC_SCANLINE_OFFSET		0x048
117 #define VE_SRC1_ADDR			0x04c
118 #define VE_COMP_ADDR			0x054
119 
120 #define VE_STREAM_BUF_SIZE		0x058
121 #define  VE_STREAM_BUF_SIZE_N_PACKETS	GENMASK(5, 3)
122 #define  VE_STREAM_BUF_SIZE_P_SIZE	GENMASK(2, 0)
123 
124 #define VE_COMP_CTRL			0x060
125 #define  VE_COMP_CTRL_VQ_DCT_ONLY	BIT(0)
126 #define  VE_COMP_CTRL_VQ_4COLOR		BIT(1)
127 #define  VE_COMP_CTRL_QUANTIZE		BIT(2)
128 #define  VE_COMP_CTRL_EN_BQ		BIT(4)
129 #define  VE_COMP_CTRL_EN_CRYPTO		BIT(5)
130 #define  VE_COMP_CTRL_DCT_CHR		GENMASK(10, 6)
131 #define  VE_COMP_CTRL_DCT_LUM		GENMASK(15, 11)
132 #define  VE_COMP_CTRL_EN_HQ		BIT(16)
133 #define  VE_COMP_CTRL_RSVD		BIT(19)
134 #define  VE_COMP_CTRL_ENCODE		GENMASK(21, 20)
135 #define  VE_COMP_CTRL_HQ_DCT_CHR	GENMASK(26, 22)
136 #define  VE_COMP_CTRL_HQ_DCT_LUM	GENMASK(31, 27)
137 
138 #define AST2400_VE_COMP_SIZE_READ_BACK	0x078
139 #define AST2600_VE_COMP_SIZE_READ_BACK	0x084
140 
141 #define VE_SRC_LR_EDGE_DET		0x090
142 #define  VE_SRC_LR_EDGE_DET_LEFT	GENMASK(11, 0)
143 #define  VE_SRC_LR_EDGE_DET_NO_V	BIT(12)
144 #define  VE_SRC_LR_EDGE_DET_NO_H	BIT(13)
145 #define  VE_SRC_LR_EDGE_DET_NO_DISP	BIT(14)
146 #define  VE_SRC_LR_EDGE_DET_NO_CLK	BIT(15)
147 #define  VE_SRC_LR_EDGE_DET_RT		GENMASK(27, 16)
148 #define  VE_SRC_LR_EDGE_DET_INTERLACE	BIT(31)
149 
150 #define VE_SRC_TB_EDGE_DET		0x094
151 #define  VE_SRC_TB_EDGE_DET_TOP		GENMASK(12, 0)
152 #define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, 16)
153 
154 #define VE_MODE_DETECT_STATUS		0x098
155 #define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
156 #define  VE_MODE_DETECT_EXTSRC_ADC	BIT(12)
157 #define  VE_MODE_DETECT_H_STABLE	BIT(13)
158 #define  VE_MODE_DETECT_V_STABLE	BIT(14)
159 #define  VE_MODE_DETECT_V_LINES		GENMASK(27, 16)
160 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
161 #define  VE_MODE_DETECT_STATUS_HSYNC	BIT(29)
162 #define  VE_MODE_DETECT_VSYNC_RDY	BIT(30)
163 #define  VE_MODE_DETECT_HSYNC_RDY	BIT(31)
164 
165 #define VE_SYNC_STATUS			0x09c
166 #define  VE_SYNC_STATUS_HSYNC		GENMASK(11, 0)
167 #define  VE_SYNC_STATUS_VSYNC		GENMASK(27, 16)
168 
169 #define VE_H_TOTAL_PIXELS		0x0A0
170 
171 #define VE_INTERRUPT_CTRL		0x304
172 #define VE_INTERRUPT_STATUS		0x308
173 #define  VE_INTERRUPT_MODE_DETECT_WD	BIT(0)
174 #define  VE_INTERRUPT_CAPTURE_COMPLETE	BIT(1)
175 #define  VE_INTERRUPT_COMP_READY	BIT(2)
176 #define  VE_INTERRUPT_COMP_COMPLETE	BIT(3)
177 #define  VE_INTERRUPT_MODE_DETECT	BIT(4)
178 #define  VE_INTERRUPT_FRAME_COMPLETE	BIT(5)
179 #define  VE_INTERRUPT_DECODE_ERR	BIT(6)
180 #define  VE_INTERRUPT_HALT_READY	BIT(8)
181 #define  VE_INTERRUPT_HANG_WD		BIT(9)
182 #define  VE_INTERRUPT_STREAM_DESC	BIT(10)
183 #define  VE_INTERRUPT_VSYNC_DESC	BIT(11)
184 
185 #define VE_MODE_DETECT			0x30c
186 #define  VE_MODE_DT_HOR_TOLER		GENMASK(31, 28)
187 #define  VE_MODE_DT_VER_TOLER		GENMASK(27, 24)
188 #define  VE_MODE_DT_HOR_STABLE		GENMASK(23, 20)
189 #define  VE_MODE_DT_VER_STABLE		GENMASK(19, 16)
190 #define  VE_MODE_DT_EDG_THROD		GENMASK(15, 8)
191 
192 #define VE_MEM_RESTRICT_START		0x310
193 #define VE_MEM_RESTRICT_END		0x314
194 
195 /*
196  * VIDEO_MODE_DETECT_DONE:	a flag raised if signal lock
197  * VIDEO_RES_CHANGE:		a flag raised if res_change work on-going
198  * VIDEO_RES_DETECT:		a flag raised if res. detection on-going
199  * VIDEO_STREAMING:		a flag raised if user requires stream-on
200  * VIDEO_FRAME_INPRG:		a flag raised if hw working on a frame
201  * VIDEO_STOPPED:		a flag raised if device release
202  * VIDEO_CLOCKS_ON:		a flag raised if clk is on
203  */
204 enum {
205 	VIDEO_MODE_DETECT_DONE,
206 	VIDEO_RES_CHANGE,
207 	VIDEO_RES_DETECT,
208 	VIDEO_STREAMING,
209 	VIDEO_FRAME_INPRG,
210 	VIDEO_STOPPED,
211 	VIDEO_CLOCKS_ON,
212 };
213 
214 // for VE_CTRL_CAPTURE_FMT
215 enum aspeed_video_capture_format {
216 	VIDEO_CAP_FMT_YUV_STUDIO_SWING = 0,
217 	VIDEO_CAP_FMT_YUV_FULL_SWING,
218 	VIDEO_CAP_FMT_RGB,
219 	VIDEO_CAP_FMT_GRAY,
220 	VIDEO_CAP_FMT_MAX
221 };
222 
223 struct aspeed_video_addr {
224 	unsigned int size;
225 	dma_addr_t dma;
226 	void *virt;
227 };
228 
229 struct aspeed_video_buffer {
230 	struct vb2_v4l2_buffer vb;
231 	struct list_head link;
232 };
233 
234 struct aspeed_video_perf {
235 	ktime_t last_sample;
236 	u32 totaltime;
237 	u32 duration;
238 	u32 duration_min;
239 	u32 duration_max;
240 };
241 
242 #define to_aspeed_video_buffer(x) \
243 	container_of((x), struct aspeed_video_buffer, vb)
244 
245 /*
246  * struct aspeed_video - driver data
247  *
248  * res_work:           holds the delayed_work for res-detection if unlock
249  * buffers:            holds the list of buffer queued from user
250  * flags:		holds the state of video
251  * sequence:		holds the last number of frame completed
252  * max_compressed_size:	holds max compressed stream's size
253  * srcs:		holds the buffer information for srcs
254  * jpeg:		holds the buffer information for jpeg header
255  * yuv420:		a flag raised if JPEG subsampling is 420
256  * frame_rate:		holds the frame_rate
257  * jpeg_quality:	holds jpeq's quality (0~11)
258  * frame_bottom:	end position of video data in vertical direction
259  * frame_left:		start position of video data in horizontal direction
260  * frame_right:		end position of video data in horizontal direction
261  * frame_top:		start position of video data in vertical direction
262  * perf:		holds the statistics primary for debugfs
263  */
264 struct aspeed_video {
265 	void __iomem *base;
266 	struct clk *eclk;
267 	struct clk *vclk;
268 
269 	struct device *dev;
270 	struct v4l2_ctrl_handler ctrl_handler;
271 	struct v4l2_device v4l2_dev;
272 	struct v4l2_pix_format pix_fmt;
273 	struct v4l2_bt_timings active_timings;
274 	struct v4l2_bt_timings detected_timings;
275 	u32 v4l2_input_status;
276 	struct vb2_queue queue;
277 	struct video_device vdev;
278 	struct mutex video_lock;	/* v4l2 and videobuf2 lock */
279 
280 	u32 jpeg_mode;
281 	u32 comp_size_read;
282 
283 	wait_queue_head_t wait;
284 	spinlock_t lock;		/* buffer list lock */
285 	struct delayed_work res_work;
286 	struct list_head buffers;
287 	unsigned long flags;
288 	unsigned int sequence;
289 
290 	unsigned int max_compressed_size;
291 	struct aspeed_video_addr srcs[2];
292 	struct aspeed_video_addr jpeg;
293 
294 	bool yuv420;
295 	unsigned int frame_rate;
296 	unsigned int jpeg_quality;
297 
298 	unsigned int frame_bottom;
299 	unsigned int frame_left;
300 	unsigned int frame_right;
301 	unsigned int frame_top;
302 
303 	struct aspeed_video_perf perf;
304 };
305 
306 #define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
307 
308 struct aspeed_video_config {
309 	u32 jpeg_mode;
310 	u32 comp_size_read;
311 };
312 
313 static const struct aspeed_video_config ast2400_config = {
314 	.jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
315 	.comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
316 };
317 
318 static const struct aspeed_video_config ast2500_config = {
319 	.jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
320 	.comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
321 };
322 
323 static const struct aspeed_video_config ast2600_config = {
324 	.jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
325 	.comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
326 };
327 
328 static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
329 	0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
330 	0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
331 };
332 
333 static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] = {
334 	0x081100c0, 0x00000000, 0x00110103, 0x03011102, 0xc4ff0111, 0x00001f00,
335 	0x01010501, 0x01010101, 0x00000000, 0x00000000, 0x04030201, 0x08070605,
336 	0xff0b0a09, 0x10b500c4, 0x03010200, 0x03040203, 0x04040505, 0x7d010000,
337 	0x00030201, 0x12051104, 0x06413121, 0x07615113, 0x32147122, 0x08a19181,
338 	0xc1b14223, 0xf0d15215, 0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
339 	0x35342a29, 0x39383736, 0x4544433a, 0x49484746, 0x5554534a, 0x59585756,
340 	0x6564635a, 0x69686766, 0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
341 	0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4, 0xb2aaa9a8, 0xb6b5b4b3,
342 	0xbab9b8b7, 0xc5c4c3c2, 0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
343 	0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5, 0xc4fffaf9, 0x00011f00,
344 	0x01010103, 0x01010101, 0x00000101, 0x00000000, 0x04030201, 0x08070605,
345 	0xff0b0a09, 0x11b500c4, 0x02010200, 0x04030404, 0x04040507, 0x77020100,
346 	0x03020100, 0x21050411, 0x41120631, 0x71610751, 0x81322213, 0x91421408,
347 	0x09c1b1a1, 0xf0523323, 0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
348 	0x2a292827, 0x38373635, 0x44433a39, 0x48474645, 0x54534a49, 0x58575655,
349 	0x64635a59, 0x68676665, 0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
350 	0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2, 0xa9a8a7a6, 0xb4b3b2aa,
351 	0xb8b7b6b5, 0xc3c2bab9, 0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
352 	0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5, 0xdafffaf9, 0x01030c00,
353 	0x03110200, 0x003f0011
354 };
355 
356 static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
357 				      [ASPEED_VIDEO_JPEG_DCT_SIZE] = {
358 	{ 0x0d140043, 0x0c0f110f, 0x11101114, 0x17141516, 0x1e20321e,
359 	  0x3d1e1b1b, 0x32242e2b, 0x4b4c3f48, 0x44463f47, 0x61735a50,
360 	  0x566c5550, 0x88644644, 0x7a766c65, 0x4d808280, 0x8c978d60,
361 	  0x7e73967d, 0xdbff7b80, 0x1f014300, 0x272d2121, 0x3030582d,
362 	  0x697bb958, 0xb8b9b97b, 0xb9b8a6a6, 0xb9b9b9b9, 0xb9b9b9b9,
363 	  0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9,
364 	  0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xffb9b9b9 },
365 	{ 0x0c110043, 0x0a0d0f0d, 0x0f0e0f11, 0x14111213, 0x1a1c2b1a,
366 	  0x351a1818, 0x2b1f2826, 0x4142373f, 0x3c3d373e, 0x55644e46,
367 	  0x4b5f4a46, 0x77573d3c, 0x6b675f58, 0x43707170, 0x7a847b54,
368 	  0x6e64836d, 0xdbff6c70, 0x1b014300, 0x22271d1d, 0x2a2a4c27,
369 	  0x5b6ba04c, 0xa0a0a06b, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
370 	  0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
371 	  0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xffa0a0a0 },
372 	{ 0x090e0043, 0x090a0c0a, 0x0c0b0c0e, 0x110e0f10, 0x15172415,
373 	  0x2c151313, 0x241a211f, 0x36372e34, 0x31322e33, 0x4653413a,
374 	  0x3e4e3d3a, 0x62483231, 0x58564e49, 0x385d5e5d, 0x656d6645,
375 	  0x5b536c5a, 0xdbff595d, 0x16014300, 0x1c201818, 0x22223f20,
376 	  0x4b58853f, 0x85858558, 0x85858585, 0x85858585, 0x85858585,
377 	  0x85858585, 0x85858585, 0x85858585, 0x85858585, 0x85858585,
378 	  0x85858585, 0x85858585, 0x85858585, 0xff858585 },
379 	{ 0x070b0043, 0x07080a08, 0x0a090a0b, 0x0d0b0c0c, 0x11121c11,
380 	  0x23110f0f, 0x1c141a19, 0x2b2b2429, 0x27282428, 0x3842332e,
381 	  0x313e302e, 0x4e392827, 0x46443e3a, 0x2c4a4a4a, 0x50565137,
382 	  0x48425647, 0xdbff474a, 0x12014300, 0x161a1313, 0x1c1c331a,
383 	  0x3d486c33, 0x6c6c6c48, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
384 	  0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
385 	  0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0xff6c6c6c },
386 	{ 0x06090043, 0x05060706, 0x07070709, 0x0a09090a, 0x0d0e160d,
387 	  0x1b0d0c0c, 0x16101413, 0x21221c20, 0x1e1f1c20, 0x2b332824,
388 	  0x26302624, 0x3d2d1f1e, 0x3735302d, 0x22393a39, 0x3f443f2b,
389 	  0x38334338, 0xdbff3739, 0x0d014300, 0x11130e0e, 0x15152613,
390 	  0x2d355026, 0x50505035, 0x50505050, 0x50505050, 0x50505050,
391 	  0x50505050, 0x50505050, 0x50505050, 0x50505050, 0x50505050,
392 	  0x50505050, 0x50505050, 0x50505050, 0xff505050 },
393 	{ 0x04060043, 0x03040504, 0x05040506, 0x07060606, 0x09090f09,
394 	  0x12090808, 0x0f0a0d0d, 0x16161315, 0x14151315, 0x1d221b18,
395 	  0x19201918, 0x281e1514, 0x2423201e, 0x17262726, 0x2a2d2a1c,
396 	  0x25222d25, 0xdbff2526, 0x09014300, 0x0b0d0a0a, 0x0e0e1a0d,
397 	  0x1f25371a, 0x37373725, 0x37373737, 0x37373737, 0x37373737,
398 	  0x37373737, 0x37373737, 0x37373737, 0x37373737, 0x37373737,
399 	  0x37373737, 0x37373737, 0x37373737, 0xff373737 },
400 	{ 0x02030043, 0x01020202, 0x02020203, 0x03030303, 0x04040704,
401 	  0x09040404, 0x07050606, 0x0b0b090a, 0x0a0a090a, 0x0e110d0c,
402 	  0x0c100c0c, 0x140f0a0a, 0x1211100f, 0x0b131313, 0x1516150e,
403 	  0x12111612, 0xdbff1213, 0x04014300, 0x05060505, 0x07070d06,
404 	  0x0f121b0d, 0x1b1b1b12, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
405 	  0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
406 	  0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0xff1b1b1b },
407 	{ 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
408 	  0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
409 	  0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
410 	  0x0c0b0f0c, 0xdbff0c0c, 0x03014300, 0x03040303, 0x04040804,
411 	  0x0a0c1208, 0x1212120c, 0x12121212, 0x12121212, 0x12121212,
412 	  0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
413 	  0x12121212, 0x12121212, 0x12121212, 0xff121212 },
414 	{ 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
415 	  0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
416 	  0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
417 	  0x0c0b0f0c, 0xdbff0c0c, 0x02014300, 0x03030202, 0x04040703,
418 	  0x080a0f07, 0x0f0f0f0a, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
419 	  0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
420 	  0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xff0f0f0f },
421 	{ 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x02020302,
422 	  0x04020202, 0x03020303, 0x05050405, 0x05050405, 0x07080606,
423 	  0x06080606, 0x0a070505, 0x09080807, 0x05090909, 0x0a0b0a07,
424 	  0x09080b09, 0xdbff0909, 0x02014300, 0x02030202, 0x03030503,
425 	  0x07080c05, 0x0c0c0c08, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
426 	  0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
427 	  0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xff0c0c0c },
428 	{ 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010201,
429 	  0x03010101, 0x02010202, 0x03030303, 0x03030303, 0x04050404,
430 	  0x04050404, 0x06050303, 0x06050505, 0x03060606, 0x07070704,
431 	  0x06050706, 0xdbff0606, 0x01014300, 0x01020101, 0x02020402,
432 	  0x05060904, 0x09090906, 0x09090909, 0x09090909, 0x09090909,
433 	  0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
434 	  0x09090909, 0x09090909, 0x09090909, 0xff090909 },
435 	{ 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
436 	  0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202,
437 	  0x02020202, 0x03020101, 0x03020202, 0x01030303, 0x03030302,
438 	  0x03020303, 0xdbff0403, 0x01014300, 0x01010101, 0x01010201,
439 	  0x03040602, 0x06060604, 0x06060606, 0x06060606, 0x06060606,
440 	  0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
441 	  0x06060606, 0x06060606, 0x06060606, 0xff060606 }
442 };
443 
444 static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
445 	.type = V4L2_DV_BT_656_1120,
446 	.bt = {
447 		.min_width = MIN_WIDTH,
448 		.max_width = MAX_WIDTH,
449 		.min_height = MIN_HEIGHT,
450 		.max_height = MAX_HEIGHT,
451 		.min_pixelclock = 6574080, /* 640 x 480 x 24Hz */
452 		.max_pixelclock = 138240000, /* 1920 x 1200 x 60Hz */
453 		.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
454 			V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
455 		.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
456 			V4L2_DV_BT_CAP_REDUCED_BLANKING |
457 			V4L2_DV_BT_CAP_CUSTOM,
458 	},
459 };
460 
461 static unsigned int debug;
462 
463 static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
464 {
465 	int i;
466 	unsigned int base;
467 
468 	for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
469 		base = 256 * i;	/* AST HW requires this header spacing */
470 		memcpy(&table[base], aspeed_video_jpeg_header,
471 		       sizeof(aspeed_video_jpeg_header));
472 
473 		base += ASPEED_VIDEO_JPEG_HEADER_SIZE;
474 		memcpy(&table[base], aspeed_video_jpeg_dct[i],
475 		       sizeof(aspeed_video_jpeg_dct[i]));
476 
477 		base += ASPEED_VIDEO_JPEG_DCT_SIZE;
478 		memcpy(&table[base], aspeed_video_jpeg_quant,
479 		       sizeof(aspeed_video_jpeg_quant));
480 
481 		if (yuv420)
482 			table[base + 2] = 0x00220103;
483 	}
484 }
485 
486 // just update jpeg dct table per 420/444
487 static void aspeed_video_update_jpeg_table(u32 *table, bool yuv420)
488 {
489 	int i;
490 	unsigned int base;
491 
492 	for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
493 		base = 256 * i;	/* AST HW requires this header spacing */
494 		base += ASPEED_VIDEO_JPEG_HEADER_SIZE +
495 			ASPEED_VIDEO_JPEG_DCT_SIZE;
496 
497 		table[base + 2] = (yuv420) ? 0x00220103 : 0x00110103;
498 	}
499 }
500 
501 static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
502 				u32 bits)
503 {
504 	u32 t = readl(video->base + reg);
505 	u32 before = t;
506 
507 	t &= ~clear;
508 	t |= bits;
509 	writel(t, video->base + reg);
510 	v4l2_dbg(3, debug, &video->v4l2_dev, "update %03x[%08x -> %08x]\n",
511 		 reg, before, readl(video->base + reg));
512 }
513 
514 static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
515 {
516 	u32 t = readl(video->base + reg);
517 
518 	v4l2_dbg(3, debug, &video->v4l2_dev, "read %03x[%08x]\n", reg, t);
519 	return t;
520 }
521 
522 static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
523 {
524 	writel(val, video->base + reg);
525 	v4l2_dbg(3, debug, &video->v4l2_dev, "write %03x[%08x]\n", reg,
526 		 readl(video->base + reg));
527 }
528 
529 static void update_perf(struct aspeed_video_perf *p)
530 {
531 	struct aspeed_video *v = container_of(p, struct aspeed_video,
532 					      perf);
533 
534 	p->duration =
535 		ktime_to_ms(ktime_sub(ktime_get(),  p->last_sample));
536 	p->totaltime += p->duration;
537 
538 	p->duration_max = max(p->duration, p->duration_max);
539 	p->duration_min = min(p->duration, p->duration_min);
540 	v4l2_dbg(2, debug, &v->v4l2_dev, "time consumed: %d ms\n",
541 		 p->duration);
542 }
543 
544 static int aspeed_video_start_frame(struct aspeed_video *video)
545 {
546 	dma_addr_t addr;
547 	unsigned long flags;
548 	struct aspeed_video_buffer *buf;
549 	u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
550 
551 	if (video->v4l2_input_status) {
552 		v4l2_warn(&video->v4l2_dev, "No signal; don't start frame\n");
553 		return 0;
554 	}
555 
556 	if (!(seq_ctrl & VE_SEQ_CTRL_COMP_BUSY) ||
557 	    !(seq_ctrl & VE_SEQ_CTRL_CAP_BUSY)) {
558 		v4l2_warn(&video->v4l2_dev, "Engine busy; don't start frame\n");
559 		return -EBUSY;
560 	}
561 
562 	spin_lock_irqsave(&video->lock, flags);
563 	buf = list_first_entry_or_null(&video->buffers,
564 				       struct aspeed_video_buffer, link);
565 	if (!buf) {
566 		spin_unlock_irqrestore(&video->lock, flags);
567 		v4l2_warn(&video->v4l2_dev, "No buffers; don't start frame\n");
568 		return -EPROTO;
569 	}
570 
571 	set_bit(VIDEO_FRAME_INPRG, &video->flags);
572 	addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
573 	spin_unlock_irqrestore(&video->lock, flags);
574 
575 	aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
576 	aspeed_video_write(video, VE_COMP_OFFSET, 0);
577 	aspeed_video_write(video, VE_COMP_ADDR, addr);
578 
579 	aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
580 			    VE_INTERRUPT_COMP_COMPLETE);
581 
582 	video->perf.last_sample = ktime_get();
583 
584 	aspeed_video_update(video, VE_SEQ_CTRL, 0,
585 			    VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
586 
587 	return 0;
588 }
589 
590 static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
591 {
592 	/* Enable mode detect interrupts */
593 	aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
594 			    VE_INTERRUPT_MODE_DETECT);
595 
596 	/* Disable mode detect in order to re-trigger */
597 	aspeed_video_update(video, VE_SEQ_CTRL,
598 			    VE_SEQ_CTRL_TRIG_MODE_DET, 0);
599 
600 	/* Trigger mode detect */
601 	aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET);
602 }
603 
604 static void aspeed_video_off(struct aspeed_video *video)
605 {
606 	if (!test_bit(VIDEO_CLOCKS_ON, &video->flags))
607 		return;
608 
609 	/* Disable interrupts */
610 	aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
611 	aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
612 
613 	/* Turn off the relevant clocks */
614 	clk_disable(video->eclk);
615 	clk_disable(video->vclk);
616 
617 	clear_bit(VIDEO_CLOCKS_ON, &video->flags);
618 }
619 
620 static void aspeed_video_on(struct aspeed_video *video)
621 {
622 	if (test_bit(VIDEO_CLOCKS_ON, &video->flags))
623 		return;
624 
625 	/* Turn on the relevant clocks */
626 	clk_enable(video->vclk);
627 	clk_enable(video->eclk);
628 
629 	set_bit(VIDEO_CLOCKS_ON, &video->flags);
630 }
631 
632 static void aspeed_video_bufs_done(struct aspeed_video *video,
633 				   enum vb2_buffer_state state)
634 {
635 	unsigned long flags;
636 	struct aspeed_video_buffer *buf;
637 
638 	spin_lock_irqsave(&video->lock, flags);
639 	list_for_each_entry(buf, &video->buffers, link)
640 		vb2_buffer_done(&buf->vb.vb2_buf, state);
641 	INIT_LIST_HEAD(&video->buffers);
642 	spin_unlock_irqrestore(&video->lock, flags);
643 }
644 
645 static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
646 {
647 	v4l2_dbg(1, debug, &video->v4l2_dev, "Resolution changed; resetting\n");
648 
649 	set_bit(VIDEO_RES_CHANGE, &video->flags);
650 	clear_bit(VIDEO_FRAME_INPRG, &video->flags);
651 
652 	video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
653 
654 	aspeed_video_off(video);
655 	aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
656 
657 	schedule_delayed_work(&video->res_work, delay);
658 }
659 
660 static irqreturn_t aspeed_video_irq(int irq, void *arg)
661 {
662 	struct aspeed_video *video = arg;
663 	u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
664 
665 	/*
666 	 * Hardware sometimes asserts interrupts that we haven't actually
667 	 * enabled; ignore them if so.
668 	 */
669 	sts &= aspeed_video_read(video, VE_INTERRUPT_CTRL);
670 
671 	v4l2_dbg(2, debug, &video->v4l2_dev, "irq sts=%#x %s%s%s%s\n", sts,
672 		 sts & VE_INTERRUPT_MODE_DETECT_WD ? ", unlock" : "",
673 		 sts & VE_INTERRUPT_MODE_DETECT ? ", lock" : "",
674 		 sts & VE_INTERRUPT_CAPTURE_COMPLETE ? ", capture-done" : "",
675 		 sts & VE_INTERRUPT_COMP_COMPLETE ? ", comp-done" : "");
676 
677 	/*
678 	 * Resolution changed or signal was lost; reset the engine and
679 	 * re-initialize
680 	 */
681 	if (sts & VE_INTERRUPT_MODE_DETECT_WD) {
682 		aspeed_video_irq_res_change(video, 0);
683 		return IRQ_HANDLED;
684 	}
685 
686 	if (sts & VE_INTERRUPT_MODE_DETECT) {
687 		if (test_bit(VIDEO_RES_DETECT, &video->flags)) {
688 			aspeed_video_update(video, VE_INTERRUPT_CTRL,
689 					    VE_INTERRUPT_MODE_DETECT, 0);
690 			aspeed_video_write(video, VE_INTERRUPT_STATUS,
691 					   VE_INTERRUPT_MODE_DETECT);
692 			sts &= ~VE_INTERRUPT_MODE_DETECT;
693 			set_bit(VIDEO_MODE_DETECT_DONE, &video->flags);
694 			wake_up_interruptible_all(&video->wait);
695 		} else {
696 			/*
697 			 * Signal acquired while NOT doing resolution
698 			 * detection; reset the engine and re-initialize
699 			 */
700 			aspeed_video_irq_res_change(video,
701 						    RESOLUTION_CHANGE_DELAY);
702 			return IRQ_HANDLED;
703 		}
704 	}
705 
706 	if (sts & VE_INTERRUPT_COMP_COMPLETE) {
707 		struct aspeed_video_buffer *buf;
708 		u32 frame_size = aspeed_video_read(video,
709 						   video->comp_size_read);
710 
711 		update_perf(&video->perf);
712 
713 		spin_lock(&video->lock);
714 		clear_bit(VIDEO_FRAME_INPRG, &video->flags);
715 		buf = list_first_entry_or_null(&video->buffers,
716 					       struct aspeed_video_buffer,
717 					       link);
718 		if (buf) {
719 			vb2_set_plane_payload(&buf->vb.vb2_buf, 0, frame_size);
720 
721 			if (!list_is_last(&buf->link, &video->buffers)) {
722 				buf->vb.vb2_buf.timestamp = ktime_get_ns();
723 				buf->vb.sequence = video->sequence++;
724 				buf->vb.field = V4L2_FIELD_NONE;
725 				vb2_buffer_done(&buf->vb.vb2_buf,
726 						VB2_BUF_STATE_DONE);
727 				list_del(&buf->link);
728 			}
729 		}
730 		spin_unlock(&video->lock);
731 
732 		aspeed_video_update(video, VE_SEQ_CTRL,
733 				    VE_SEQ_CTRL_TRIG_CAPTURE |
734 				    VE_SEQ_CTRL_FORCE_IDLE |
735 				    VE_SEQ_CTRL_TRIG_COMP, 0);
736 		aspeed_video_update(video, VE_INTERRUPT_CTRL,
737 				    VE_INTERRUPT_COMP_COMPLETE, 0);
738 		aspeed_video_write(video, VE_INTERRUPT_STATUS,
739 				   VE_INTERRUPT_COMP_COMPLETE);
740 		sts &= ~VE_INTERRUPT_COMP_COMPLETE;
741 		if (test_bit(VIDEO_STREAMING, &video->flags) && buf)
742 			aspeed_video_start_frame(video);
743 	}
744 
745 	return sts ? IRQ_NONE : IRQ_HANDLED;
746 }
747 
748 static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
749 {
750 	int i;
751 	int hsync_counter = 0;
752 	int vsync_counter = 0;
753 	u32 sts, ctrl;
754 
755 	for (i = 0; i < NUM_POLARITY_CHECKS; ++i) {
756 		sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
757 		if (sts & VE_MODE_DETECT_STATUS_VSYNC)
758 			vsync_counter--;
759 		else
760 			vsync_counter++;
761 
762 		if (sts & VE_MODE_DETECT_STATUS_HSYNC)
763 			hsync_counter--;
764 		else
765 			hsync_counter++;
766 	}
767 
768 	ctrl = aspeed_video_read(video, VE_CTRL);
769 
770 	if (hsync_counter < 0) {
771 		ctrl |= VE_CTRL_HSYNC_POL;
772 		video->detected_timings.polarities &=
773 			~V4L2_DV_HSYNC_POS_POL;
774 	} else {
775 		ctrl &= ~VE_CTRL_HSYNC_POL;
776 		video->detected_timings.polarities |=
777 			V4L2_DV_HSYNC_POS_POL;
778 	}
779 
780 	if (vsync_counter < 0) {
781 		ctrl |= VE_CTRL_VSYNC_POL;
782 		video->detected_timings.polarities &=
783 			~V4L2_DV_VSYNC_POS_POL;
784 	} else {
785 		ctrl &= ~VE_CTRL_VSYNC_POL;
786 		video->detected_timings.polarities |=
787 			V4L2_DV_VSYNC_POS_POL;
788 	}
789 
790 	aspeed_video_write(video, VE_CTRL, ctrl);
791 }
792 
793 static bool aspeed_video_alloc_buf(struct aspeed_video *video,
794 				   struct aspeed_video_addr *addr,
795 				   unsigned int size)
796 {
797 	addr->virt = dma_alloc_coherent(video->dev, size, &addr->dma,
798 					GFP_KERNEL);
799 	if (!addr->virt)
800 		return false;
801 
802 	addr->size = size;
803 	return true;
804 }
805 
806 static void aspeed_video_free_buf(struct aspeed_video *video,
807 				  struct aspeed_video_addr *addr)
808 {
809 	dma_free_coherent(video->dev, addr->size, addr->virt, addr->dma);
810 	addr->size = 0;
811 	addr->dma = 0ULL;
812 	addr->virt = NULL;
813 }
814 
815 /*
816  * Get the minimum HW-supported compression buffer size for the frame size.
817  * Assume worst-case JPEG compression size is 1/8 raw size. This should be
818  * plenty even for maximum quality; any worse and the engine will simply return
819  * incomplete JPEGs.
820  */
821 static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
822 					      unsigned int frame_size)
823 {
824 	int i, j;
825 	u32 compression_buffer_size_reg = 0;
826 	unsigned int size;
827 	const unsigned int num_compression_packets = 4;
828 	const unsigned int compression_packet_size = 1024;
829 	const unsigned int max_compressed_size = frame_size / 2; /* 4bpp / 8 */
830 
831 	video->max_compressed_size = UINT_MAX;
832 
833 	for (i = 0; i < 6; ++i) {
834 		for (j = 0; j < 8; ++j) {
835 			size = (num_compression_packets << i) *
836 				(compression_packet_size << j);
837 			if (size < max_compressed_size)
838 				continue;
839 
840 			if (size < video->max_compressed_size) {
841 				compression_buffer_size_reg = (i << 3) | j;
842 				video->max_compressed_size = size;
843 			}
844 		}
845 	}
846 
847 	aspeed_video_write(video, VE_STREAM_BUF_SIZE,
848 			   compression_buffer_size_reg);
849 
850 	v4l2_dbg(1, debug, &video->v4l2_dev, "Max compressed size: %#x\n",
851 		 video->max_compressed_size);
852 }
853 
854 /*
855  * Update v4l2_bt_timings per current status.
856  * frame_top/frame_bottom/frame_left/frame_right need to be ready.
857  *
858  * The following registers start counting from sync's rising edge:
859  * 1. VR090: frame edge's left and right
860  * 2. VR094: frame edge's top and bottom
861  * 3. VR09C: counting from sync's rising edge to falling edge
862  *
863  * [Vertical timing]
864  *             +--+     +-------------------+     +--+
865  *             |  |     |     v i d e o     |     |  |
866  *          +--+  +-----+                   +-----+  +---+
867  *        vsync+--+
868  *    frame_top+--------+
869  * frame_bottom+----------------------------+
870  *
871  *                   +-------------------+
872  *                   |     v i d e o     |
873  *       +--+  +-----+                   +-----+  +---+
874  *          |  |                               |  |
875  *          +--+                               +--+
876  *        vsync+-------------------------------+
877  *    frame_top+-----+
878  * frame_bottom+-------------------------+
879  *
880  * [Horizontal timing]
881  *             +--+     +-------------------+     +--+
882  *             |  |     |     v i d e o     |     |  |
883  *          +--+  +-----+                   +-----+  +---+
884  *        hsync+--+
885  *   frame_left+--------+
886  *  frame_right+----------------------------+
887  *
888  *                   +-------------------+
889  *                   |     v i d e o     |
890  *       +--+  +-----+                   +-----+  +---+
891  *          |  |                               |  |
892  *          +--+                               +--+
893  *        hsync+-------------------------------+
894  *   frame_left+-----+
895  *  frame_right+-------------------------+
896  *
897  * @v: the struct of aspeed_video
898  * @det: v4l2_bt_timings to be updated.
899  */
900 static void aspeed_video_get_timings(struct aspeed_video *v,
901 				     struct v4l2_bt_timings *det)
902 {
903 	u32 mds, sync, htotal, vtotal, vsync, hsync;
904 
905 	mds = aspeed_video_read(v, VE_MODE_DETECT_STATUS);
906 	sync = aspeed_video_read(v, VE_SYNC_STATUS);
907 	htotal = aspeed_video_read(v, VE_H_TOTAL_PIXELS);
908 	vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
909 	vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
910 	hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
911 
912 	/*
913 	 * This is a workaround for polarity detection.
914 	 * Because ast-soc counts sync from sync's rising edge, the reg value
915 	 * of sync would be larger than video's active area if negative.
916 	 */
917 	if (vsync > det->height)
918 		det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
919 	else
920 		det->polarities |= V4L2_DV_VSYNC_POS_POL;
921 	if (hsync > det->width)
922 		det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
923 	else
924 		det->polarities |= V4L2_DV_HSYNC_POS_POL;
925 
926 	if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
927 		det->vbackporch = v->frame_top - vsync;
928 		det->vfrontporch = vtotal - v->frame_bottom;
929 		det->vsync = vsync;
930 	} else {
931 		det->vbackporch = v->frame_top;
932 		det->vfrontporch = vsync - v->frame_bottom;
933 		det->vsync = vtotal - vsync;
934 	}
935 
936 	if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
937 		det->hbackporch = v->frame_left - hsync;
938 		det->hfrontporch = htotal - v->frame_right;
939 		det->hsync = hsync;
940 	} else {
941 		det->hbackporch = v->frame_left;
942 		det->hfrontporch = hsync - v->frame_right;
943 		det->hsync = htotal - hsync;
944 	}
945 }
946 
947 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
948 
949 static void aspeed_video_get_resolution(struct aspeed_video *video)
950 {
951 	bool invalid_resolution = true;
952 	int rc;
953 	int tries = 0;
954 	u32 mds;
955 	u32 src_lr_edge;
956 	u32 src_tb_edge;
957 	struct v4l2_bt_timings *det = &video->detected_timings;
958 
959 	det->width = MIN_WIDTH;
960 	det->height = MIN_HEIGHT;
961 	video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
962 	memset(&video->perf, 0, sizeof(video->perf));
963 
964 	do {
965 		if (tries) {
966 			set_current_state(TASK_INTERRUPTIBLE);
967 			if (schedule_timeout(INVALID_RESOLUTION_DELAY))
968 				return;
969 		}
970 
971 		set_bit(VIDEO_RES_DETECT, &video->flags);
972 		aspeed_video_update(video, VE_CTRL,
973 				    VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, 0);
974 		aspeed_video_enable_mode_detect(video);
975 
976 		rc = wait_event_interruptible_timeout(video->wait,
977 						      res_check(video),
978 						      MODE_DETECT_TIMEOUT);
979 		if (!rc) {
980 			v4l2_warn(&video->v4l2_dev, "Timed out; first mode detect\n");
981 			clear_bit(VIDEO_RES_DETECT, &video->flags);
982 			return;
983 		}
984 
985 		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
986 		// try detection again if current signal isn't stable
987 		if (!(mds & VE_MODE_DETECT_H_STABLE) ||
988 		    !(mds & VE_MODE_DETECT_V_STABLE) ||
989 		    (mds & VE_MODE_DETECT_EXTSRC_ADC))
990 			continue;
991 
992 		aspeed_video_check_and_set_polarity(video);
993 
994 		aspeed_video_enable_mode_detect(video);
995 
996 		rc = wait_event_interruptible_timeout(video->wait,
997 						      res_check(video),
998 						      MODE_DETECT_TIMEOUT);
999 		clear_bit(VIDEO_RES_DETECT, &video->flags);
1000 		if (!rc) {
1001 			v4l2_warn(&video->v4l2_dev, "Timed out; second mode detect\n");
1002 			return;
1003 		}
1004 
1005 		src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
1006 		src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
1007 
1008 		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
1009 		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
1010 
1011 		if (video->frame_top > video->frame_bottom)
1012 			continue;
1013 
1014 		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
1015 		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
1016 
1017 		if (video->frame_left > video->frame_right)
1018 			continue;
1019 
1020 		invalid_resolution = false;
1021 	} while (invalid_resolution && (tries++ < INVALID_RESOLUTION_RETRIES));
1022 
1023 	if (invalid_resolution) {
1024 		v4l2_warn(&video->v4l2_dev, "Invalid resolution detected\n");
1025 		return;
1026 	}
1027 
1028 	det->height = (video->frame_bottom - video->frame_top) + 1;
1029 	det->width = (video->frame_right - video->frame_left) + 1;
1030 	video->v4l2_input_status = 0;
1031 
1032 	aspeed_video_get_timings(video, det);
1033 
1034 	/*
1035 	 * Enable mode-detect watchdog, resolution-change watchdog and
1036 	 * automatic compression after frame capture.
1037 	 */
1038 	aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
1039 			    VE_INTERRUPT_MODE_DETECT_WD);
1040 	aspeed_video_update(video, VE_SEQ_CTRL, 0,
1041 			    VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
1042 
1043 	v4l2_dbg(1, debug, &video->v4l2_dev, "Got resolution: %dx%d\n",
1044 		 det->width, det->height);
1045 }
1046 
1047 static void aspeed_video_set_resolution(struct aspeed_video *video)
1048 {
1049 	struct v4l2_bt_timings *act = &video->active_timings;
1050 	unsigned int size = act->width * act->height;
1051 
1052 	/* Set capture/compression frame sizes */
1053 	aspeed_video_calc_compressed_size(video, size);
1054 
1055 	if (!IS_ALIGNED(act->width, 64)) {
1056 		/*
1057 		 * This is a workaround to fix a AST2500 silicon bug on A1 and
1058 		 * A2 revisions. Since it doesn't break capturing operation of
1059 		 * other revisions, use it for all revisions without checking
1060 		 * the revision ID. It picked new width which is a very next
1061 		 * 64-pixels aligned value to minimize memory bandwidth
1062 		 * and to get better access speed from video engine.
1063 		 */
1064 		u32 width = ALIGN(act->width, 64);
1065 
1066 		aspeed_video_write(video, VE_CAP_WINDOW, width << 16 | act->height);
1067 		size = width * act->height;
1068 	} else {
1069 		aspeed_video_write(video, VE_CAP_WINDOW,
1070 				   act->width << 16 | act->height);
1071 	}
1072 	aspeed_video_write(video, VE_COMP_WINDOW,
1073 			   act->width << 16 | act->height);
1074 	aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4);
1075 
1076 	/* Don't use direct mode below 1024 x 768 (irqs don't fire) */
1077 	if (size < DIRECT_FETCH_THRESHOLD) {
1078 		v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Sync Mode\n");
1079 		aspeed_video_write(video, VE_TGS_0,
1080 				   FIELD_PREP(VE_TGS_FIRST,
1081 					      video->frame_left - 1) |
1082 				   FIELD_PREP(VE_TGS_LAST,
1083 					      video->frame_right));
1084 		aspeed_video_write(video, VE_TGS_1,
1085 				   FIELD_PREP(VE_TGS_FIRST, video->frame_top) |
1086 				   FIELD_PREP(VE_TGS_LAST,
1087 					      video->frame_bottom + 1));
1088 		aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_INT_DE);
1089 	} else {
1090 		v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Direct Mode\n");
1091 		aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH);
1092 	}
1093 
1094 	size *= 4;
1095 
1096 	if (size != video->srcs[0].size) {
1097 		if (video->srcs[0].size)
1098 			aspeed_video_free_buf(video, &video->srcs[0]);
1099 		if (video->srcs[1].size)
1100 			aspeed_video_free_buf(video, &video->srcs[1]);
1101 
1102 		if (!aspeed_video_alloc_buf(video, &video->srcs[0], size))
1103 			goto err_mem;
1104 		if (!aspeed_video_alloc_buf(video, &video->srcs[1], size))
1105 			goto err_mem;
1106 
1107 		v4l2_dbg(1, debug, &video->v4l2_dev, "src buf0 addr(%pad) size(%d)\n",
1108 			 &video->srcs[0].dma, video->srcs[0].size);
1109 		v4l2_dbg(1, debug, &video->v4l2_dev, "src buf1 addr(%pad) size(%d)\n",
1110 			 &video->srcs[1].dma, video->srcs[1].size);
1111 		aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma);
1112 		aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma);
1113 	}
1114 
1115 	return;
1116 
1117 err_mem:
1118 	dev_err(video->dev, "Failed to allocate source buffers\n");
1119 
1120 	if (video->srcs[0].size)
1121 		aspeed_video_free_buf(video, &video->srcs[0]);
1122 }
1123 
1124 static void aspeed_video_init_regs(struct aspeed_video *video)
1125 {
1126 	u32 comp_ctrl = VE_COMP_CTRL_RSVD |
1127 		FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
1128 		FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
1129 	u32 ctrl = VE_CTRL_AUTO_OR_CURSOR |
1130 		FIELD_PREP(VE_CTRL_CAPTURE_FMT, VIDEO_CAP_FMT_YUV_FULL_SWING);
1131 	u32 seq_ctrl = video->jpeg_mode;
1132 
1133 	if (video->frame_rate)
1134 		ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
1135 
1136 	if (video->yuv420)
1137 		seq_ctrl |= VE_SEQ_CTRL_YUV420;
1138 
1139 	/* Unlock VE registers */
1140 	aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
1141 
1142 	/* Disable interrupts */
1143 	aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
1144 	aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
1145 
1146 	/* Clear the offset */
1147 	aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
1148 	aspeed_video_write(video, VE_COMP_OFFSET, 0);
1149 
1150 	aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
1151 
1152 	/* Set control registers */
1153 	aspeed_video_write(video, VE_SEQ_CTRL, seq_ctrl);
1154 	aspeed_video_write(video, VE_CTRL, ctrl);
1155 	aspeed_video_write(video, VE_COMP_CTRL, comp_ctrl);
1156 
1157 	/* Don't downscale */
1158 	aspeed_video_write(video, VE_SCALING_FACTOR, 0x10001000);
1159 	aspeed_video_write(video, VE_SCALING_FILTER0, 0x00200000);
1160 	aspeed_video_write(video, VE_SCALING_FILTER1, 0x00200000);
1161 	aspeed_video_write(video, VE_SCALING_FILTER2, 0x00200000);
1162 	aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
1163 
1164 	/* Set mode detection defaults */
1165 	aspeed_video_write(video, VE_MODE_DETECT,
1166 			   FIELD_PREP(VE_MODE_DT_HOR_TOLER, 2) |
1167 			   FIELD_PREP(VE_MODE_DT_VER_TOLER, 2) |
1168 			   FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) |
1169 			   FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) |
1170 			   FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65));
1171 }
1172 
1173 static void aspeed_video_start(struct aspeed_video *video)
1174 {
1175 	aspeed_video_on(video);
1176 
1177 	aspeed_video_init_regs(video);
1178 
1179 	/* Resolution set to 640x480 if no signal found */
1180 	aspeed_video_get_resolution(video);
1181 
1182 	/* Set timings since the device is being opened for the first time */
1183 	video->active_timings = video->detected_timings;
1184 	aspeed_video_set_resolution(video);
1185 
1186 	video->pix_fmt.width = video->active_timings.width;
1187 	video->pix_fmt.height = video->active_timings.height;
1188 	video->pix_fmt.sizeimage = video->max_compressed_size;
1189 }
1190 
1191 static void aspeed_video_stop(struct aspeed_video *video)
1192 {
1193 	set_bit(VIDEO_STOPPED, &video->flags);
1194 	cancel_delayed_work_sync(&video->res_work);
1195 
1196 	aspeed_video_off(video);
1197 
1198 	if (video->srcs[0].size)
1199 		aspeed_video_free_buf(video, &video->srcs[0]);
1200 
1201 	if (video->srcs[1].size)
1202 		aspeed_video_free_buf(video, &video->srcs[1]);
1203 
1204 	video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1205 	video->flags = 0;
1206 }
1207 
1208 static int aspeed_video_querycap(struct file *file, void *fh,
1209 				 struct v4l2_capability *cap)
1210 {
1211 	strscpy(cap->driver, DEVICE_NAME, sizeof(cap->driver));
1212 	strscpy(cap->card, "Aspeed Video Engine", sizeof(cap->card));
1213 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1214 		 DEVICE_NAME);
1215 
1216 	return 0;
1217 }
1218 
1219 static int aspeed_video_enum_format(struct file *file, void *fh,
1220 				    struct v4l2_fmtdesc *f)
1221 {
1222 	if (f->index)
1223 		return -EINVAL;
1224 
1225 	f->pixelformat = V4L2_PIX_FMT_JPEG;
1226 
1227 	return 0;
1228 }
1229 
1230 static int aspeed_video_get_format(struct file *file, void *fh,
1231 				   struct v4l2_format *f)
1232 {
1233 	struct aspeed_video *video = video_drvdata(file);
1234 
1235 	f->fmt.pix = video->pix_fmt;
1236 
1237 	return 0;
1238 }
1239 
1240 static int aspeed_video_enum_input(struct file *file, void *fh,
1241 				   struct v4l2_input *inp)
1242 {
1243 	struct aspeed_video *video = video_drvdata(file);
1244 
1245 	if (inp->index)
1246 		return -EINVAL;
1247 
1248 	strscpy(inp->name, "Host VGA capture", sizeof(inp->name));
1249 	inp->type = V4L2_INPUT_TYPE_CAMERA;
1250 	inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
1251 	inp->status = video->v4l2_input_status;
1252 
1253 	return 0;
1254 }
1255 
1256 static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
1257 {
1258 	*i = 0;
1259 
1260 	return 0;
1261 }
1262 
1263 static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
1264 {
1265 	if (i)
1266 		return -EINVAL;
1267 
1268 	return 0;
1269 }
1270 
1271 static int aspeed_video_get_parm(struct file *file, void *fh,
1272 				 struct v4l2_streamparm *a)
1273 {
1274 	struct aspeed_video *video = video_drvdata(file);
1275 
1276 	a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1277 	a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1278 	a->parm.capture.timeperframe.numerator = 1;
1279 	if (!video->frame_rate)
1280 		a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1281 	else
1282 		a->parm.capture.timeperframe.denominator = video->frame_rate;
1283 
1284 	return 0;
1285 }
1286 
1287 static int aspeed_video_set_parm(struct file *file, void *fh,
1288 				 struct v4l2_streamparm *a)
1289 {
1290 	unsigned int frame_rate = 0;
1291 	struct aspeed_video *video = video_drvdata(file);
1292 
1293 	a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1294 	a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1295 
1296 	if (a->parm.capture.timeperframe.numerator)
1297 		frame_rate = a->parm.capture.timeperframe.denominator /
1298 			a->parm.capture.timeperframe.numerator;
1299 
1300 	if (!frame_rate || frame_rate > MAX_FRAME_RATE) {
1301 		frame_rate = 0;
1302 		a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1303 		a->parm.capture.timeperframe.numerator = 1;
1304 	}
1305 
1306 	if (video->frame_rate != frame_rate) {
1307 		video->frame_rate = frame_rate;
1308 		aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC,
1309 				    FIELD_PREP(VE_CTRL_FRC, frame_rate));
1310 	}
1311 
1312 	return 0;
1313 }
1314 
1315 static int aspeed_video_enum_framesizes(struct file *file, void *fh,
1316 					struct v4l2_frmsizeenum *fsize)
1317 {
1318 	struct aspeed_video *video = video_drvdata(file);
1319 
1320 	if (fsize->index)
1321 		return -EINVAL;
1322 
1323 	if (fsize->pixel_format != V4L2_PIX_FMT_JPEG)
1324 		return -EINVAL;
1325 
1326 	fsize->discrete.width = video->pix_fmt.width;
1327 	fsize->discrete.height = video->pix_fmt.height;
1328 	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1329 
1330 	return 0;
1331 }
1332 
1333 static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
1334 					    struct v4l2_frmivalenum *fival)
1335 {
1336 	struct aspeed_video *video = video_drvdata(file);
1337 
1338 	if (fival->index)
1339 		return -EINVAL;
1340 
1341 	if (fival->width != video->detected_timings.width ||
1342 	    fival->height != video->detected_timings.height)
1343 		return -EINVAL;
1344 
1345 	if (fival->pixel_format != V4L2_PIX_FMT_JPEG)
1346 		return -EINVAL;
1347 
1348 	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1349 
1350 	fival->stepwise.min.denominator = MAX_FRAME_RATE;
1351 	fival->stepwise.min.numerator = 1;
1352 	fival->stepwise.max.denominator = 1;
1353 	fival->stepwise.max.numerator = 1;
1354 	fival->stepwise.step = fival->stepwise.max;
1355 
1356 	return 0;
1357 }
1358 
1359 static int aspeed_video_set_dv_timings(struct file *file, void *fh,
1360 				       struct v4l2_dv_timings *timings)
1361 {
1362 	struct aspeed_video *video = video_drvdata(file);
1363 
1364 	if (timings->bt.width == video->active_timings.width &&
1365 	    timings->bt.height == video->active_timings.height)
1366 		return 0;
1367 
1368 	if (vb2_is_busy(&video->queue))
1369 		return -EBUSY;
1370 
1371 	video->active_timings = timings->bt;
1372 
1373 	aspeed_video_set_resolution(video);
1374 
1375 	video->pix_fmt.width = timings->bt.width;
1376 	video->pix_fmt.height = timings->bt.height;
1377 	video->pix_fmt.sizeimage = video->max_compressed_size;
1378 
1379 	timings->type = V4L2_DV_BT_656_1120;
1380 
1381 	v4l2_dbg(1, debug, &video->v4l2_dev, "set new timings(%dx%d)\n",
1382 		 timings->bt.width, timings->bt.height);
1383 
1384 	return 0;
1385 }
1386 
1387 static int aspeed_video_get_dv_timings(struct file *file, void *fh,
1388 				       struct v4l2_dv_timings *timings)
1389 {
1390 	struct aspeed_video *video = video_drvdata(file);
1391 
1392 	timings->type = V4L2_DV_BT_656_1120;
1393 	timings->bt = video->active_timings;
1394 
1395 	return 0;
1396 }
1397 
1398 static int aspeed_video_query_dv_timings(struct file *file, void *fh,
1399 					 struct v4l2_dv_timings *timings)
1400 {
1401 	int rc;
1402 	struct aspeed_video *video = video_drvdata(file);
1403 
1404 	/*
1405 	 * This blocks only if the driver is currently in the process of
1406 	 * detecting a new resolution; in the event of no signal or timeout
1407 	 * this function is woken up.
1408 	 */
1409 	if (file->f_flags & O_NONBLOCK) {
1410 		if (test_bit(VIDEO_RES_CHANGE, &video->flags))
1411 			return -EAGAIN;
1412 	} else {
1413 		rc = wait_event_interruptible(video->wait,
1414 					      !test_bit(VIDEO_RES_CHANGE,
1415 							&video->flags));
1416 		if (rc)
1417 			return -EINTR;
1418 	}
1419 
1420 	timings->type = V4L2_DV_BT_656_1120;
1421 	timings->bt = video->detected_timings;
1422 
1423 	return video->v4l2_input_status ? -ENOLINK : 0;
1424 }
1425 
1426 static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
1427 					struct v4l2_enum_dv_timings *timings)
1428 {
1429 	return v4l2_enum_dv_timings_cap(timings, &aspeed_video_timings_cap,
1430 					NULL, NULL);
1431 }
1432 
1433 static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
1434 				       struct v4l2_dv_timings_cap *cap)
1435 {
1436 	*cap = aspeed_video_timings_cap;
1437 
1438 	return 0;
1439 }
1440 
1441 static int aspeed_video_sub_event(struct v4l2_fh *fh,
1442 				  const struct v4l2_event_subscription *sub)
1443 {
1444 	switch (sub->type) {
1445 	case V4L2_EVENT_SOURCE_CHANGE:
1446 		return v4l2_src_change_event_subscribe(fh, sub);
1447 	}
1448 
1449 	return v4l2_ctrl_subscribe_event(fh, sub);
1450 }
1451 
1452 static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = {
1453 	.vidioc_querycap = aspeed_video_querycap,
1454 
1455 	.vidioc_enum_fmt_vid_cap = aspeed_video_enum_format,
1456 	.vidioc_g_fmt_vid_cap = aspeed_video_get_format,
1457 	.vidioc_s_fmt_vid_cap = aspeed_video_get_format,
1458 	.vidioc_try_fmt_vid_cap = aspeed_video_get_format,
1459 
1460 	.vidioc_reqbufs = vb2_ioctl_reqbufs,
1461 	.vidioc_querybuf = vb2_ioctl_querybuf,
1462 	.vidioc_qbuf = vb2_ioctl_qbuf,
1463 	.vidioc_expbuf = vb2_ioctl_expbuf,
1464 	.vidioc_dqbuf = vb2_ioctl_dqbuf,
1465 	.vidioc_create_bufs = vb2_ioctl_create_bufs,
1466 	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1467 	.vidioc_streamon = vb2_ioctl_streamon,
1468 	.vidioc_streamoff = vb2_ioctl_streamoff,
1469 
1470 	.vidioc_enum_input = aspeed_video_enum_input,
1471 	.vidioc_g_input = aspeed_video_get_input,
1472 	.vidioc_s_input = aspeed_video_set_input,
1473 
1474 	.vidioc_g_parm = aspeed_video_get_parm,
1475 	.vidioc_s_parm = aspeed_video_set_parm,
1476 	.vidioc_enum_framesizes = aspeed_video_enum_framesizes,
1477 	.vidioc_enum_frameintervals = aspeed_video_enum_frameintervals,
1478 
1479 	.vidioc_s_dv_timings = aspeed_video_set_dv_timings,
1480 	.vidioc_g_dv_timings = aspeed_video_get_dv_timings,
1481 	.vidioc_query_dv_timings = aspeed_video_query_dv_timings,
1482 	.vidioc_enum_dv_timings = aspeed_video_enum_dv_timings,
1483 	.vidioc_dv_timings_cap = aspeed_video_dv_timings_cap,
1484 
1485 	.vidioc_subscribe_event = aspeed_video_sub_event,
1486 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1487 };
1488 
1489 static void aspeed_video_update_jpeg_quality(struct aspeed_video *video)
1490 {
1491 	u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
1492 		FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
1493 
1494 	aspeed_video_update(video, VE_COMP_CTRL,
1495 			    VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR,
1496 			    comp_ctrl);
1497 }
1498 
1499 static void aspeed_video_update_subsampling(struct aspeed_video *video)
1500 {
1501 	if (video->jpeg.virt)
1502 		aspeed_video_update_jpeg_table(video->jpeg.virt, video->yuv420);
1503 
1504 	if (video->yuv420)
1505 		aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420);
1506 	else
1507 		aspeed_video_update(video, VE_SEQ_CTRL, VE_SEQ_CTRL_YUV420, 0);
1508 }
1509 
1510 static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
1511 {
1512 	struct aspeed_video *video = container_of(ctrl->handler,
1513 						  struct aspeed_video,
1514 						  ctrl_handler);
1515 
1516 	switch (ctrl->id) {
1517 	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1518 		video->jpeg_quality = ctrl->val;
1519 		aspeed_video_update_jpeg_quality(video);
1520 		break;
1521 	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1522 		if (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
1523 			video->yuv420 = true;
1524 			aspeed_video_update_subsampling(video);
1525 		} else {
1526 			video->yuv420 = false;
1527 			aspeed_video_update_subsampling(video);
1528 		}
1529 		break;
1530 	default:
1531 		return -EINVAL;
1532 	}
1533 
1534 	return 0;
1535 }
1536 
1537 static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
1538 	.s_ctrl = aspeed_video_set_ctrl,
1539 };
1540 
1541 static void aspeed_video_resolution_work(struct work_struct *work)
1542 {
1543 	struct delayed_work *dwork = to_delayed_work(work);
1544 	struct aspeed_video *video = container_of(dwork, struct aspeed_video,
1545 						  res_work);
1546 
1547 	aspeed_video_on(video);
1548 
1549 	/* Exit early in case no clients remain */
1550 	if (test_bit(VIDEO_STOPPED, &video->flags))
1551 		goto done;
1552 
1553 	aspeed_video_init_regs(video);
1554 
1555 	aspeed_video_get_resolution(video);
1556 
1557 	if (video->detected_timings.width != video->active_timings.width ||
1558 	    video->detected_timings.height != video->active_timings.height) {
1559 		static const struct v4l2_event ev = {
1560 			.type = V4L2_EVENT_SOURCE_CHANGE,
1561 			.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1562 		};
1563 
1564 		v4l2_dbg(1, debug, &video->v4l2_dev, "fire source change event\n");
1565 		v4l2_event_queue(&video->vdev, &ev);
1566 	} else if (test_bit(VIDEO_STREAMING, &video->flags)) {
1567 		/* No resolution change so just restart streaming */
1568 		aspeed_video_start_frame(video);
1569 	}
1570 
1571 done:
1572 	clear_bit(VIDEO_RES_CHANGE, &video->flags);
1573 	wake_up_interruptible_all(&video->wait);
1574 }
1575 
1576 static int aspeed_video_open(struct file *file)
1577 {
1578 	int rc;
1579 	struct aspeed_video *video = video_drvdata(file);
1580 
1581 	mutex_lock(&video->video_lock);
1582 
1583 	rc = v4l2_fh_open(file);
1584 	if (rc) {
1585 		mutex_unlock(&video->video_lock);
1586 		return rc;
1587 	}
1588 
1589 	if (v4l2_fh_is_singular_file(file))
1590 		aspeed_video_start(video);
1591 
1592 	mutex_unlock(&video->video_lock);
1593 
1594 	return 0;
1595 }
1596 
1597 static int aspeed_video_release(struct file *file)
1598 {
1599 	int rc;
1600 	struct aspeed_video *video = video_drvdata(file);
1601 
1602 	mutex_lock(&video->video_lock);
1603 
1604 	if (v4l2_fh_is_singular_file(file))
1605 		aspeed_video_stop(video);
1606 
1607 	rc = _vb2_fop_release(file, NULL);
1608 
1609 	mutex_unlock(&video->video_lock);
1610 
1611 	return rc;
1612 }
1613 
1614 static const struct v4l2_file_operations aspeed_video_v4l2_fops = {
1615 	.owner = THIS_MODULE,
1616 	.read = vb2_fop_read,
1617 	.poll = vb2_fop_poll,
1618 	.unlocked_ioctl = video_ioctl2,
1619 	.mmap = vb2_fop_mmap,
1620 	.open = aspeed_video_open,
1621 	.release = aspeed_video_release,
1622 };
1623 
1624 static int aspeed_video_queue_setup(struct vb2_queue *q,
1625 				    unsigned int *num_buffers,
1626 				    unsigned int *num_planes,
1627 				    unsigned int sizes[],
1628 				    struct device *alloc_devs[])
1629 {
1630 	struct aspeed_video *video = vb2_get_drv_priv(q);
1631 
1632 	if (*num_planes) {
1633 		if (sizes[0] < video->max_compressed_size)
1634 			return -EINVAL;
1635 
1636 		return 0;
1637 	}
1638 
1639 	*num_planes = 1;
1640 	sizes[0] = video->max_compressed_size;
1641 
1642 	return 0;
1643 }
1644 
1645 static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
1646 {
1647 	struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1648 
1649 	if (vb2_plane_size(vb, 0) < video->max_compressed_size)
1650 		return -EINVAL;
1651 
1652 	return 0;
1653 }
1654 
1655 static int aspeed_video_start_streaming(struct vb2_queue *q,
1656 					unsigned int count)
1657 {
1658 	int rc;
1659 	struct aspeed_video *video = vb2_get_drv_priv(q);
1660 
1661 	video->sequence = 0;
1662 	video->perf.duration_max = 0;
1663 	video->perf.duration_min = 0xffffffff;
1664 
1665 	rc = aspeed_video_start_frame(video);
1666 	if (rc) {
1667 		aspeed_video_bufs_done(video, VB2_BUF_STATE_QUEUED);
1668 		return rc;
1669 	}
1670 
1671 	set_bit(VIDEO_STREAMING, &video->flags);
1672 	return 0;
1673 }
1674 
1675 static void aspeed_video_stop_streaming(struct vb2_queue *q)
1676 {
1677 	int rc;
1678 	struct aspeed_video *video = vb2_get_drv_priv(q);
1679 
1680 	clear_bit(VIDEO_STREAMING, &video->flags);
1681 
1682 	rc = wait_event_timeout(video->wait,
1683 				!test_bit(VIDEO_FRAME_INPRG, &video->flags),
1684 				STOP_TIMEOUT);
1685 	if (!rc) {
1686 		v4l2_warn(&video->v4l2_dev, "Timed out when stopping streaming\n");
1687 
1688 		/*
1689 		 * Need to force stop any DMA and try and get HW into a good
1690 		 * state for future calls to start streaming again.
1691 		 */
1692 		aspeed_video_off(video);
1693 		aspeed_video_on(video);
1694 
1695 		aspeed_video_init_regs(video);
1696 
1697 		aspeed_video_get_resolution(video);
1698 	}
1699 
1700 	aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
1701 }
1702 
1703 static void aspeed_video_buf_queue(struct vb2_buffer *vb)
1704 {
1705 	bool empty;
1706 	struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1707 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1708 	struct aspeed_video_buffer *avb = to_aspeed_video_buffer(vbuf);
1709 	unsigned long flags;
1710 
1711 	spin_lock_irqsave(&video->lock, flags);
1712 	empty = list_empty(&video->buffers);
1713 	list_add_tail(&avb->link, &video->buffers);
1714 	spin_unlock_irqrestore(&video->lock, flags);
1715 
1716 	if (test_bit(VIDEO_STREAMING, &video->flags) &&
1717 	    !test_bit(VIDEO_FRAME_INPRG, &video->flags) && empty)
1718 		aspeed_video_start_frame(video);
1719 }
1720 
1721 static const struct vb2_ops aspeed_video_vb2_ops = {
1722 	.queue_setup = aspeed_video_queue_setup,
1723 	.wait_prepare = vb2_ops_wait_prepare,
1724 	.wait_finish = vb2_ops_wait_finish,
1725 	.buf_prepare = aspeed_video_buf_prepare,
1726 	.start_streaming = aspeed_video_start_streaming,
1727 	.stop_streaming = aspeed_video_stop_streaming,
1728 	.buf_queue =  aspeed_video_buf_queue,
1729 };
1730 
1731 #ifdef CONFIG_DEBUG_FS
1732 static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
1733 {
1734 	struct aspeed_video *v = s->private;
1735 
1736 	seq_puts(s, "\n");
1737 
1738 	seq_printf(s, "  %-20s:\t%s\n", "Signal",
1739 		   v->v4l2_input_status ? "Unlock" : "Lock");
1740 	seq_printf(s, "  %-20s:\t%d\n", "Width", v->pix_fmt.width);
1741 	seq_printf(s, "  %-20s:\t%d\n", "Height", v->pix_fmt.height);
1742 	seq_printf(s, "  %-20s:\t%d\n", "FRC", v->frame_rate);
1743 
1744 	seq_puts(s, "\n");
1745 
1746 	seq_puts(s, "Performance:\n");
1747 	seq_printf(s, "  %-20s:\t%d\n", "Frame#", v->sequence);
1748 	seq_printf(s, "  %-20s:\n", "Frame Duration(ms)");
1749 	seq_printf(s, "    %-18s:\t%d\n", "Now", v->perf.duration);
1750 	seq_printf(s, "    %-18s:\t%d\n", "Min", v->perf.duration_min);
1751 	seq_printf(s, "    %-18s:\t%d\n", "Max", v->perf.duration_max);
1752 	seq_printf(s, "  %-20s:\t%d\n", "FPS", 1000 / (v->perf.totaltime / v->sequence));
1753 
1754 	return 0;
1755 }
1756 
1757 static int aspeed_video_proc_open(struct inode *inode, struct file *file)
1758 {
1759 	return single_open(file, aspeed_video_debugfs_show, inode->i_private);
1760 }
1761 
1762 static const struct file_operations aspeed_video_debugfs_ops = {
1763 	.owner   = THIS_MODULE,
1764 	.open    = aspeed_video_proc_open,
1765 	.read    = seq_read,
1766 	.llseek  = seq_lseek,
1767 	.release = single_release,
1768 };
1769 
1770 static struct dentry *debugfs_entry;
1771 
1772 static void aspeed_video_debugfs_remove(struct aspeed_video *video)
1773 {
1774 	debugfs_remove_recursive(debugfs_entry);
1775 	debugfs_entry = NULL;
1776 }
1777 
1778 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1779 {
1780 	debugfs_entry = debugfs_create_file(DEVICE_NAME, 0444, NULL,
1781 					    video,
1782 					    &aspeed_video_debugfs_ops);
1783 	if (!debugfs_entry)
1784 		aspeed_video_debugfs_remove(video);
1785 
1786 	return !debugfs_entry ? -EIO : 0;
1787 }
1788 #else
1789 static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
1790 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1791 {
1792 	return 0;
1793 }
1794 #endif /* CONFIG_DEBUG_FS */
1795 
1796 static int aspeed_video_setup_video(struct aspeed_video *video)
1797 {
1798 	const u64 mask = ~(BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_444) |
1799 			   BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_420));
1800 	struct v4l2_device *v4l2_dev = &video->v4l2_dev;
1801 	struct vb2_queue *vbq = &video->queue;
1802 	struct video_device *vdev = &video->vdev;
1803 	int rc;
1804 
1805 	video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG;
1806 	video->pix_fmt.field = V4L2_FIELD_NONE;
1807 	video->pix_fmt.colorspace = V4L2_COLORSPACE_SRGB;
1808 	video->pix_fmt.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1809 	video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1810 
1811 	rc = v4l2_device_register(video->dev, v4l2_dev);
1812 	if (rc) {
1813 		dev_err(video->dev, "Failed to register v4l2 device\n");
1814 		return rc;
1815 	}
1816 
1817 	v4l2_ctrl_handler_init(&video->ctrl_handler, 2);
1818 	v4l2_ctrl_new_std(&video->ctrl_handler, &aspeed_video_ctrl_ops,
1819 			  V4L2_CID_JPEG_COMPRESSION_QUALITY, 0,
1820 			  ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1, 1, 0);
1821 	v4l2_ctrl_new_std_menu(&video->ctrl_handler, &aspeed_video_ctrl_ops,
1822 			       V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1823 			       V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask,
1824 			       V4L2_JPEG_CHROMA_SUBSAMPLING_444);
1825 
1826 	rc = video->ctrl_handler.error;
1827 	if (rc) {
1828 		v4l2_ctrl_handler_free(&video->ctrl_handler);
1829 		v4l2_device_unregister(v4l2_dev);
1830 
1831 		dev_err(video->dev, "Failed to init controls: %d\n", rc);
1832 		return rc;
1833 	}
1834 
1835 	v4l2_dev->ctrl_handler = &video->ctrl_handler;
1836 
1837 	vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1838 	vbq->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1839 	vbq->dev = v4l2_dev->dev;
1840 	vbq->lock = &video->video_lock;
1841 	vbq->ops = &aspeed_video_vb2_ops;
1842 	vbq->mem_ops = &vb2_dma_contig_memops;
1843 	vbq->drv_priv = video;
1844 	vbq->buf_struct_size = sizeof(struct aspeed_video_buffer);
1845 	vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1846 	vbq->min_buffers_needed = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1847 
1848 	rc = vb2_queue_init(vbq);
1849 	if (rc) {
1850 		v4l2_ctrl_handler_free(&video->ctrl_handler);
1851 		v4l2_device_unregister(v4l2_dev);
1852 
1853 		dev_err(video->dev, "Failed to init vb2 queue\n");
1854 		return rc;
1855 	}
1856 
1857 	vdev->queue = vbq;
1858 	vdev->fops = &aspeed_video_v4l2_fops;
1859 	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1860 		V4L2_CAP_STREAMING;
1861 	vdev->v4l2_dev = v4l2_dev;
1862 	strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));
1863 	vdev->vfl_type = VFL_TYPE_VIDEO;
1864 	vdev->vfl_dir = VFL_DIR_RX;
1865 	vdev->release = video_device_release_empty;
1866 	vdev->ioctl_ops = &aspeed_video_ioctl_ops;
1867 	vdev->lock = &video->video_lock;
1868 
1869 	video_set_drvdata(vdev, video);
1870 	rc = video_register_device(vdev, VFL_TYPE_VIDEO, 0);
1871 	if (rc) {
1872 		v4l2_ctrl_handler_free(&video->ctrl_handler);
1873 		v4l2_device_unregister(v4l2_dev);
1874 
1875 		dev_err(video->dev, "Failed to register video device\n");
1876 		return rc;
1877 	}
1878 
1879 	return 0;
1880 }
1881 
1882 static int aspeed_video_init(struct aspeed_video *video)
1883 {
1884 	int irq;
1885 	int rc;
1886 	struct device *dev = video->dev;
1887 
1888 	irq = irq_of_parse_and_map(dev->of_node, 0);
1889 	if (!irq) {
1890 		dev_err(dev, "Unable to find IRQ\n");
1891 		return -ENODEV;
1892 	}
1893 
1894 	rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
1895 				       IRQF_ONESHOT, DEVICE_NAME, video);
1896 	if (rc < 0) {
1897 		dev_err(dev, "Unable to request IRQ %d\n", irq);
1898 		return rc;
1899 	}
1900 	dev_info(video->dev, "irq %d\n", irq);
1901 
1902 	video->eclk = devm_clk_get(dev, "eclk");
1903 	if (IS_ERR(video->eclk)) {
1904 		dev_err(dev, "Unable to get ECLK\n");
1905 		return PTR_ERR(video->eclk);
1906 	}
1907 
1908 	rc = clk_prepare(video->eclk);
1909 	if (rc)
1910 		return rc;
1911 
1912 	video->vclk = devm_clk_get(dev, "vclk");
1913 	if (IS_ERR(video->vclk)) {
1914 		dev_err(dev, "Unable to get VCLK\n");
1915 		rc = PTR_ERR(video->vclk);
1916 		goto err_unprepare_eclk;
1917 	}
1918 
1919 	rc = clk_prepare(video->vclk);
1920 	if (rc)
1921 		goto err_unprepare_eclk;
1922 
1923 	of_reserved_mem_device_init(dev);
1924 
1925 	rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1926 	if (rc) {
1927 		dev_err(dev, "Failed to set DMA mask\n");
1928 		goto err_release_reserved_mem;
1929 	}
1930 
1931 	if (!aspeed_video_alloc_buf(video, &video->jpeg,
1932 				    VE_JPEG_HEADER_SIZE)) {
1933 		dev_err(dev, "Failed to allocate DMA for JPEG header\n");
1934 		rc = -ENOMEM;
1935 		goto err_release_reserved_mem;
1936 	}
1937 	dev_info(video->dev, "alloc mem size(%d) at %pad for jpeg header\n",
1938 		 VE_JPEG_HEADER_SIZE, &video->jpeg.dma);
1939 
1940 	aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
1941 
1942 	return 0;
1943 
1944 err_release_reserved_mem:
1945 	of_reserved_mem_device_release(dev);
1946 	clk_unprepare(video->vclk);
1947 err_unprepare_eclk:
1948 	clk_unprepare(video->eclk);
1949 
1950 	return rc;
1951 }
1952 
1953 static const struct of_device_id aspeed_video_of_match[] = {
1954 	{ .compatible = "aspeed,ast2400-video-engine", .data = &ast2400_config },
1955 	{ .compatible = "aspeed,ast2500-video-engine", .data = &ast2500_config },
1956 	{ .compatible = "aspeed,ast2600-video-engine", .data = &ast2600_config },
1957 	{}
1958 };
1959 MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
1960 
1961 static int aspeed_video_probe(struct platform_device *pdev)
1962 {
1963 	const struct aspeed_video_config *config;
1964 	struct aspeed_video *video;
1965 	int rc;
1966 
1967 	video = devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
1968 	if (!video)
1969 		return -ENOMEM;
1970 
1971 	video->base = devm_platform_ioremap_resource(pdev, 0);
1972 	if (IS_ERR(video->base))
1973 		return PTR_ERR(video->base);
1974 
1975 	config = of_device_get_match_data(&pdev->dev);
1976 	if (!config)
1977 		return -ENODEV;
1978 
1979 	video->jpeg_mode = config->jpeg_mode;
1980 	video->comp_size_read = config->comp_size_read;
1981 
1982 	video->frame_rate = 30;
1983 	video->dev = &pdev->dev;
1984 	spin_lock_init(&video->lock);
1985 	mutex_init(&video->video_lock);
1986 	init_waitqueue_head(&video->wait);
1987 	INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
1988 	INIT_LIST_HEAD(&video->buffers);
1989 
1990 	rc = aspeed_video_init(video);
1991 	if (rc)
1992 		return rc;
1993 
1994 	rc = aspeed_video_setup_video(video);
1995 	if (rc) {
1996 		aspeed_video_free_buf(video, &video->jpeg);
1997 		clk_unprepare(video->vclk);
1998 		clk_unprepare(video->eclk);
1999 		return rc;
2000 	}
2001 
2002 	rc = aspeed_video_debugfs_create(video);
2003 	if (rc)
2004 		dev_err(video->dev, "debugfs create failed\n");
2005 
2006 	return 0;
2007 }
2008 
2009 static int aspeed_video_remove(struct platform_device *pdev)
2010 {
2011 	struct device *dev = &pdev->dev;
2012 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
2013 	struct aspeed_video *video = to_aspeed_video(v4l2_dev);
2014 
2015 	aspeed_video_off(video);
2016 
2017 	aspeed_video_debugfs_remove(video);
2018 
2019 	clk_unprepare(video->vclk);
2020 	clk_unprepare(video->eclk);
2021 
2022 	vb2_video_unregister_device(&video->vdev);
2023 
2024 	v4l2_ctrl_handler_free(&video->ctrl_handler);
2025 
2026 	v4l2_device_unregister(v4l2_dev);
2027 
2028 	aspeed_video_free_buf(video, &video->jpeg);
2029 
2030 	of_reserved_mem_device_release(dev);
2031 
2032 	return 0;
2033 }
2034 
2035 static struct platform_driver aspeed_video_driver = {
2036 	.driver = {
2037 		.name = DEVICE_NAME,
2038 		.of_match_table = aspeed_video_of_match,
2039 	},
2040 	.probe = aspeed_video_probe,
2041 	.remove = aspeed_video_remove,
2042 };
2043 
2044 module_platform_driver(aspeed_video_driver);
2045 
2046 module_param(debug, int, 0644);
2047 MODULE_PARM_DESC(debug, "Debug level (0=off,1=info,2=debug,3=reg ops)");
2048 
2049 MODULE_DESCRIPTION("ASPEED Video Engine Driver");
2050 MODULE_AUTHOR("Eddie James");
2051 MODULE_LICENSE("GPL v2");
2052