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

aspeed-video.c (61774B)


      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 */
    204enum {
    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
    215enum 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
    223struct aspeed_video_addr {
    224	unsigned int size;
    225	dma_addr_t dma;
    226	void *virt;
    227};
    228
    229struct aspeed_video_buffer {
    230	struct vb2_v4l2_buffer vb;
    231	struct list_head link;
    232};
    233
    234struct 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 */
    264struct 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
    308struct aspeed_video_config {
    309	u32 jpeg_mode;
    310	u32 comp_size_read;
    311};
    312
    313static 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
    318static 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
    323static 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
    328static 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
    333static 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
    356static 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
    444static 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
    461static unsigned int debug;
    462
    463static 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
    487static 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
    501static 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
    514static 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
    522static 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
    529static 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
    544static 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
    590static 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
    604static 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
    620static 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
    632static 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
    645static 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
    660static 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
    748static 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
    793static 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
    806static 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 */
    821static 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 */
    900static 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
    949static 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
   1047static 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
   1117err_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
   1124static 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
   1173static 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
   1191static 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
   1208static 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
   1219static 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
   1230static 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
   1240static 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
   1256static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
   1257{
   1258	*i = 0;
   1259
   1260	return 0;
   1261}
   1262
   1263static 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
   1271static 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
   1287static 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
   1315static 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
   1333static 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
   1359static 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
   1387static 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
   1398static 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
   1426static 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
   1433static 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
   1441static 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
   1452static 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
   1489static 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
   1499static 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
   1510static 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
   1537static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
   1538	.s_ctrl = aspeed_video_set_ctrl,
   1539};
   1540
   1541static 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
   1571done:
   1572	clear_bit(VIDEO_RES_CHANGE, &video->flags);
   1573	wake_up_interruptible_all(&video->wait);
   1574}
   1575
   1576static 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
   1597static 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
   1614static 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
   1624static 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
   1645static 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
   1655static 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
   1675static 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
   1703static 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
   1721static 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
   1732static 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
   1757static 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
   1762static 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
   1770static struct dentry *debugfs_entry;
   1771
   1772static void aspeed_video_debugfs_remove(struct aspeed_video *video)
   1773{
   1774	debugfs_remove_recursive(debugfs_entry);
   1775	debugfs_entry = NULL;
   1776}
   1777
   1778static 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
   1789static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
   1790static int aspeed_video_debugfs_create(struct aspeed_video *video)
   1791{
   1792	return 0;
   1793}
   1794#endif /* CONFIG_DEBUG_FS */
   1795
   1796static 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
   1882static 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
   1944err_release_reserved_mem:
   1945	of_reserved_mem_device_release(dev);
   1946	clk_unprepare(video->vclk);
   1947err_unprepare_eclk:
   1948	clk_unprepare(video->eclk);
   1949
   1950	return rc;
   1951}
   1952
   1953static 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};
   1959MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
   1960
   1961static 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
   2009static 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
   2035static 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
   2044module_platform_driver(aspeed_video_driver);
   2045
   2046module_param(debug, int, 0644);
   2047MODULE_PARM_DESC(debug, "Debug level (0=off,1=info,2=debug,3=reg ops)");
   2048
   2049MODULE_DESCRIPTION("ASPEED Video Engine Driver");
   2050MODULE_AUTHOR("Eddie James");
   2051MODULE_LICENSE("GPL v2");