Linux Audio

Check our new training course

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