1 // SPDX-License-Identifier: GPL-2.0-or-later
2 // Copyright 2020 IBM Corp.
3 // Copyright (c) 2019-2020 Intel Corporation
5 #include <linux/atomic.h>
6 #include <linux/bitfield.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>
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>
37 #define ASPEED_VIDEO_V4L2_MIN_BUF_REQ 3
39 #define DEVICE_NAME "aspeed-video"
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
46 #define MAX_FRAME_RATE 60
47 #define MAX_HEIGHT 1200
48 #define MAX_WIDTH 1920
49 #define MIN_HEIGHT 480
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 */
60 #define VE_MAX_SRC_BUFFER_SIZE 0x8ca000 /* 1920 * 1200, 32bpp */
61 #define VE_JPEG_HEADER_SIZE 0x006000 /* 512 * 12 * 4 */
63 #define VE_PROTECTION_KEY 0x000
64 #define VE_PROTECTION_KEY_UNLOCK 0x1a038aa8
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)
82 #define AST2500_VE_SEQ_CTRL_JPEG_MODE BIT(13)
83 #define AST2400_VE_SEQ_CTRL_JPEG_MODE BIT(8)
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)
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)
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
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
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)
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)
138 #define AST2400_VE_COMP_SIZE_READ_BACK 0x078
139 #define AST2600_VE_COMP_SIZE_READ_BACK 0x084
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)
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)
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)
165 #define VE_SYNC_STATUS 0x09c
166 #define VE_SYNC_STATUS_HSYNC GENMASK(11, 0)
167 #define VE_SYNC_STATUS_VSYNC GENMASK(27, 16)
169 #define VE_H_TOTAL_PIXELS 0x0A0
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)
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)
192 #define VE_MEM_RESTRICT_START 0x310
193 #define VE_MEM_RESTRICT_END 0x314
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
205 VIDEO_MODE_DETECT_DONE,
214 // for VE_CTRL_CAPTURE_FMT
215 enum aspeed_video_capture_format {
216 VIDEO_CAP_FMT_YUV_STUDIO_SWING = 0,
217 VIDEO_CAP_FMT_YUV_FULL_SWING,
223 struct aspeed_video_addr {
229 struct aspeed_video_buffer {
230 struct vb2_v4l2_buffer vb;
231 struct list_head link;
234 struct aspeed_video_perf {
242 #define to_aspeed_video_buffer(x) \
243 container_of((x), struct aspeed_video_buffer, vb)
246 * struct aspeed_video - driver data
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
264 struct aspeed_video {
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 */
283 wait_queue_head_t wait;
284 spinlock_t lock; /* buffer list lock */
285 struct delayed_work res_work;
286 struct list_head buffers;
288 unsigned int sequence;
290 unsigned int max_compressed_size;
291 struct aspeed_video_addr srcs[2];
292 struct aspeed_video_addr jpeg;
295 unsigned int frame_rate;
296 unsigned int jpeg_quality;
298 unsigned int frame_bottom;
299 unsigned int frame_left;
300 unsigned int frame_right;
301 unsigned int frame_top;
303 struct aspeed_video_perf perf;
306 #define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
308 struct aspeed_video_config {
313 static const struct aspeed_video_config ast2400_config = {
314 .jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
315 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
318 static const struct aspeed_video_config ast2500_config = {
319 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
320 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
323 static const struct aspeed_video_config ast2600_config = {
324 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
325 .comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
328 static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
329 0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
330 0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
333 static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] = {
334 0x081100c0, 0x00000000, 0x00110103, 0x03011102, 0xc4ff0111, 0x00001f00,
335 0x01010501, 0x01010101, 0x00000000, 0x00000000, 0x04030201, 0x08070605,
336 0xff0b0a09, 0x10b500c4, 0x03010200, 0x03040203, 0x04040505, 0x7d010000,
337 0x00030201, 0x12051104, 0x06413121, 0x07615113, 0x32147122, 0x08a19181,
338 0xc1b14223, 0xf0d15215, 0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
339 0x35342a29, 0x39383736, 0x4544433a, 0x49484746, 0x5554534a, 0x59585756,
340 0x6564635a, 0x69686766, 0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
341 0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4, 0xb2aaa9a8, 0xb6b5b4b3,
342 0xbab9b8b7, 0xc5c4c3c2, 0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
343 0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5, 0xc4fffaf9, 0x00011f00,
344 0x01010103, 0x01010101, 0x00000101, 0x00000000, 0x04030201, 0x08070605,
345 0xff0b0a09, 0x11b500c4, 0x02010200, 0x04030404, 0x04040507, 0x77020100,
346 0x03020100, 0x21050411, 0x41120631, 0x71610751, 0x81322213, 0x91421408,
347 0x09c1b1a1, 0xf0523323, 0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
348 0x2a292827, 0x38373635, 0x44433a39, 0x48474645, 0x54534a49, 0x58575655,
349 0x64635a59, 0x68676665, 0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
350 0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2, 0xa9a8a7a6, 0xb4b3b2aa,
351 0xb8b7b6b5, 0xc3c2bab9, 0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
352 0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5, 0xdafffaf9, 0x01030c00,
353 0x03110200, 0x003f0011
356 static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
357 [ASPEED_VIDEO_JPEG_DCT_SIZE] = {
358 { 0x0d140043, 0x0c0f110f, 0x11101114, 0x17141516, 0x1e20321e,
359 0x3d1e1b1b, 0x32242e2b, 0x4b4c3f48, 0x44463f47, 0x61735a50,
360 0x566c5550, 0x88644644, 0x7a766c65, 0x4d808280, 0x8c978d60,
361 0x7e73967d, 0xdbff7b80, 0x1f014300, 0x272d2121, 0x3030582d,
362 0x697bb958, 0xb8b9b97b, 0xb9b8a6a6, 0xb9b9b9b9, 0xb9b9b9b9,
363 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9,
364 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xffb9b9b9 },
365 { 0x0c110043, 0x0a0d0f0d, 0x0f0e0f11, 0x14111213, 0x1a1c2b1a,
366 0x351a1818, 0x2b1f2826, 0x4142373f, 0x3c3d373e, 0x55644e46,
367 0x4b5f4a46, 0x77573d3c, 0x6b675f58, 0x43707170, 0x7a847b54,
368 0x6e64836d, 0xdbff6c70, 0x1b014300, 0x22271d1d, 0x2a2a4c27,
369 0x5b6ba04c, 0xa0a0a06b, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
370 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
371 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xffa0a0a0 },
372 { 0x090e0043, 0x090a0c0a, 0x0c0b0c0e, 0x110e0f10, 0x15172415,
373 0x2c151313, 0x241a211f, 0x36372e34, 0x31322e33, 0x4653413a,
374 0x3e4e3d3a, 0x62483231, 0x58564e49, 0x385d5e5d, 0x656d6645,
375 0x5b536c5a, 0xdbff595d, 0x16014300, 0x1c201818, 0x22223f20,
376 0x4b58853f, 0x85858558, 0x85858585, 0x85858585, 0x85858585,
377 0x85858585, 0x85858585, 0x85858585, 0x85858585, 0x85858585,
378 0x85858585, 0x85858585, 0x85858585, 0xff858585 },
379 { 0x070b0043, 0x07080a08, 0x0a090a0b, 0x0d0b0c0c, 0x11121c11,
380 0x23110f0f, 0x1c141a19, 0x2b2b2429, 0x27282428, 0x3842332e,
381 0x313e302e, 0x4e392827, 0x46443e3a, 0x2c4a4a4a, 0x50565137,
382 0x48425647, 0xdbff474a, 0x12014300, 0x161a1313, 0x1c1c331a,
383 0x3d486c33, 0x6c6c6c48, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
384 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
385 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0xff6c6c6c },
386 { 0x06090043, 0x05060706, 0x07070709, 0x0a09090a, 0x0d0e160d,
387 0x1b0d0c0c, 0x16101413, 0x21221c20, 0x1e1f1c20, 0x2b332824,
388 0x26302624, 0x3d2d1f1e, 0x3735302d, 0x22393a39, 0x3f443f2b,
389 0x38334338, 0xdbff3739, 0x0d014300, 0x11130e0e, 0x15152613,
390 0x2d355026, 0x50505035, 0x50505050, 0x50505050, 0x50505050,
391 0x50505050, 0x50505050, 0x50505050, 0x50505050, 0x50505050,
392 0x50505050, 0x50505050, 0x50505050, 0xff505050 },
393 { 0x04060043, 0x03040504, 0x05040506, 0x07060606, 0x09090f09,
394 0x12090808, 0x0f0a0d0d, 0x16161315, 0x14151315, 0x1d221b18,
395 0x19201918, 0x281e1514, 0x2423201e, 0x17262726, 0x2a2d2a1c,
396 0x25222d25, 0xdbff2526, 0x09014300, 0x0b0d0a0a, 0x0e0e1a0d,
397 0x1f25371a, 0x37373725, 0x37373737, 0x37373737, 0x37373737,
398 0x37373737, 0x37373737, 0x37373737, 0x37373737, 0x37373737,
399 0x37373737, 0x37373737, 0x37373737, 0xff373737 },
400 { 0x02030043, 0x01020202, 0x02020203, 0x03030303, 0x04040704,
401 0x09040404, 0x07050606, 0x0b0b090a, 0x0a0a090a, 0x0e110d0c,
402 0x0c100c0c, 0x140f0a0a, 0x1211100f, 0x0b131313, 0x1516150e,
403 0x12111612, 0xdbff1213, 0x04014300, 0x05060505, 0x07070d06,
404 0x0f121b0d, 0x1b1b1b12, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
405 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
406 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0xff1b1b1b },
407 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
408 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
409 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
410 0x0c0b0f0c, 0xdbff0c0c, 0x03014300, 0x03040303, 0x04040804,
411 0x0a0c1208, 0x1212120c, 0x12121212, 0x12121212, 0x12121212,
412 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
413 0x12121212, 0x12121212, 0x12121212, 0xff121212 },
414 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
415 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
416 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
417 0x0c0b0f0c, 0xdbff0c0c, 0x02014300, 0x03030202, 0x04040703,
418 0x080a0f07, 0x0f0f0f0a, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
419 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
420 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xff0f0f0f },
421 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x02020302,
422 0x04020202, 0x03020303, 0x05050405, 0x05050405, 0x07080606,
423 0x06080606, 0x0a070505, 0x09080807, 0x05090909, 0x0a0b0a07,
424 0x09080b09, 0xdbff0909, 0x02014300, 0x02030202, 0x03030503,
425 0x07080c05, 0x0c0c0c08, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
426 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
427 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xff0c0c0c },
428 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010201,
429 0x03010101, 0x02010202, 0x03030303, 0x03030303, 0x04050404,
430 0x04050404, 0x06050303, 0x06050505, 0x03060606, 0x07070704,
431 0x06050706, 0xdbff0606, 0x01014300, 0x01020101, 0x02020402,
432 0x05060904, 0x09090906, 0x09090909, 0x09090909, 0x09090909,
433 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
434 0x09090909, 0x09090909, 0x09090909, 0xff090909 },
435 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
436 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202,
437 0x02020202, 0x03020101, 0x03020202, 0x01030303, 0x03030302,
438 0x03020303, 0xdbff0403, 0x01014300, 0x01010101, 0x01010201,
439 0x03040602, 0x06060604, 0x06060606, 0x06060606, 0x06060606,
440 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
441 0x06060606, 0x06060606, 0x06060606, 0xff060606 }
444 static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
445 .type = V4L2_DV_BT_656_1120,
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,
461 static unsigned int debug;
463 static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
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));
473 base += ASPEED_VIDEO_JPEG_HEADER_SIZE;
474 memcpy(&table[base], aspeed_video_jpeg_dct[i],
475 sizeof(aspeed_video_jpeg_dct[i]));
477 base += ASPEED_VIDEO_JPEG_DCT_SIZE;
478 memcpy(&table[base], aspeed_video_jpeg_quant,
479 sizeof(aspeed_video_jpeg_quant));
482 table[base + 2] = 0x00220103;
486 // just update jpeg dct table per 420/444
487 static void aspeed_video_update_jpeg_table(u32 *table, bool yuv420)
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;
497 table[base + 2] = (yuv420) ? 0x00220103 : 0x00110103;
501 static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
504 u32 t = readl(video->base + reg);
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));
514 static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
516 u32 t = readl(video->base + reg);
518 v4l2_dbg(3, debug, &video->v4l2_dev, "read %03x[%08x]\n", reg, t);
522 static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
524 writel(val, video->base + reg);
525 v4l2_dbg(3, debug, &video->v4l2_dev, "write %03x[%08x]\n", reg,
526 readl(video->base + reg));
529 static void update_perf(struct aspeed_video_perf *p)
531 struct aspeed_video *v = container_of(p, struct aspeed_video,
535 ktime_to_ms(ktime_sub(ktime_get(), p->last_sample));
536 p->totaltime += p->duration;
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",
544 static int aspeed_video_start_frame(struct aspeed_video *video)
548 struct aspeed_video_buffer *buf;
549 u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
551 if (video->v4l2_input_status) {
552 v4l2_warn(&video->v4l2_dev, "No signal; don't start frame\n");
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");
562 spin_lock_irqsave(&video->lock, flags);
563 buf = list_first_entry_or_null(&video->buffers,
564 struct aspeed_video_buffer, link);
566 spin_unlock_irqrestore(&video->lock, flags);
567 v4l2_warn(&video->v4l2_dev, "No buffers; don't start frame\n");
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);
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);
579 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
580 VE_INTERRUPT_COMP_COMPLETE);
582 video->perf.last_sample = ktime_get();
584 aspeed_video_update(video, VE_SEQ_CTRL, 0,
585 VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
590 static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
592 /* Enable mode detect interrupts */
593 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
594 VE_INTERRUPT_MODE_DETECT);
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);
600 /* Trigger mode detect */
601 aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET);
604 static void aspeed_video_off(struct aspeed_video *video)
606 if (!test_bit(VIDEO_CLOCKS_ON, &video->flags))
609 /* Disable interrupts */
610 aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
611 aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
613 /* Turn off the relevant clocks */
614 clk_disable(video->eclk);
615 clk_disable(video->vclk);
617 clear_bit(VIDEO_CLOCKS_ON, &video->flags);
620 static void aspeed_video_on(struct aspeed_video *video)
622 if (test_bit(VIDEO_CLOCKS_ON, &video->flags))
625 /* Turn on the relevant clocks */
626 clk_enable(video->vclk);
627 clk_enable(video->eclk);
629 set_bit(VIDEO_CLOCKS_ON, &video->flags);
632 static void aspeed_video_bufs_done(struct aspeed_video *video,
633 enum vb2_buffer_state state)
636 struct aspeed_video_buffer *buf;
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);
645 static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
647 v4l2_dbg(1, debug, &video->v4l2_dev, "Resolution changed; resetting\n");
649 set_bit(VIDEO_RES_CHANGE, &video->flags);
650 clear_bit(VIDEO_FRAME_INPRG, &video->flags);
652 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
654 aspeed_video_off(video);
655 aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
657 schedule_delayed_work(&video->res_work, delay);
660 static irqreturn_t aspeed_video_irq(int irq, void *arg)
662 struct aspeed_video *video = arg;
663 u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
666 * Hardware sometimes asserts interrupts that we haven't actually
667 * enabled; ignore them if so.
669 sts &= aspeed_video_read(video, VE_INTERRUPT_CTRL);
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" : "");
678 * Resolution changed or signal was lost; reset the engine and
681 if (sts & VE_INTERRUPT_MODE_DETECT_WD) {
682 aspeed_video_irq_res_change(video, 0);
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);
697 * Signal acquired while NOT doing resolution
698 * detection; reset the engine and re-initialize
700 aspeed_video_irq_res_change(video,
701 RESOLUTION_CHANGE_DELAY);
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);
711 update_perf(&video->perf);
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,
719 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, frame_size);
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,
727 list_del(&buf->link);
730 spin_unlock(&video->lock);
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);
745 return sts ? IRQ_NONE : IRQ_HANDLED;
748 static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
751 int hsync_counter = 0;
752 int vsync_counter = 0;
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)
762 if (sts & VE_MODE_DETECT_STATUS_HSYNC)
768 ctrl = aspeed_video_read(video, VE_CTRL);
770 if (hsync_counter < 0) {
771 ctrl |= VE_CTRL_HSYNC_POL;
772 video->detected_timings.polarities &=
773 ~V4L2_DV_HSYNC_POS_POL;
775 ctrl &= ~VE_CTRL_HSYNC_POL;
776 video->detected_timings.polarities |=
777 V4L2_DV_HSYNC_POS_POL;
780 if (vsync_counter < 0) {
781 ctrl |= VE_CTRL_VSYNC_POL;
782 video->detected_timings.polarities &=
783 ~V4L2_DV_VSYNC_POS_POL;
785 ctrl &= ~VE_CTRL_VSYNC_POL;
786 video->detected_timings.polarities |=
787 V4L2_DV_VSYNC_POS_POL;
790 aspeed_video_write(video, VE_CTRL, ctrl);
793 static bool aspeed_video_alloc_buf(struct aspeed_video *video,
794 struct aspeed_video_addr *addr,
797 addr->virt = dma_alloc_coherent(video->dev, size, &addr->dma,
806 static void aspeed_video_free_buf(struct aspeed_video *video,
807 struct aspeed_video_addr *addr)
809 dma_free_coherent(video->dev, addr->size, addr->virt, addr->dma);
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
821 static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
822 unsigned int frame_size)
825 u32 compression_buffer_size_reg = 0;
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 */
831 video->max_compressed_size = UINT_MAX;
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)
840 if (size < video->max_compressed_size) {
841 compression_buffer_size_reg = (i << 3) | j;
842 video->max_compressed_size = size;
847 aspeed_video_write(video, VE_STREAM_BUF_SIZE,
848 compression_buffer_size_reg);
850 v4l2_dbg(1, debug, &video->v4l2_dev, "Max compressed size: %#x\n",
851 video->max_compressed_size);
855 * Update v4l2_bt_timings per current status.
856 * frame_top/frame_bottom/frame_left/frame_right need to be ready.
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
864 * +--+ +-------------------+ +--+
865 * | | | v i d e o | | |
866 * +--+ +-----+ +-----+ +---+
868 * frame_top+--------+
869 * frame_bottom+----------------------------+
871 * +-------------------+
873 * +--+ +-----+ +-----+ +---+
876 * vsync+-------------------------------+
878 * frame_bottom+-------------------------+
880 * [Horizontal timing]
881 * +--+ +-------------------+ +--+
882 * | | | v i d e o | | |
883 * +--+ +-----+ +-----+ +---+
885 * frame_left+--------+
886 * frame_right+----------------------------+
888 * +-------------------+
890 * +--+ +-----+ +-----+ +---+
893 * hsync+-------------------------------+
895 * frame_right+-------------------------+
897 * @v: the struct of aspeed_video
898 * @det: v4l2_bt_timings to be updated.
900 static void aspeed_video_get_timings(struct aspeed_video *v,
901 struct v4l2_bt_timings *det)
903 u32 mds, sync, htotal, vtotal, vsync, hsync;
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);
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.
917 if (vsync > det->height)
918 det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
920 det->polarities |= V4L2_DV_VSYNC_POS_POL;
921 if (hsync > det->width)
922 det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
924 det->polarities |= V4L2_DV_HSYNC_POS_POL;
926 if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
927 det->vbackporch = v->frame_top - vsync;
928 det->vfrontporch = vtotal - v->frame_bottom;
931 det->vbackporch = v->frame_top;
932 det->vfrontporch = vsync - v->frame_bottom;
933 det->vsync = vtotal - vsync;
936 if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
937 det->hbackporch = v->frame_left - hsync;
938 det->hfrontporch = htotal - v->frame_right;
941 det->hbackporch = v->frame_left;
942 det->hfrontporch = hsync - v->frame_right;
943 det->hsync = htotal - hsync;
947 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
949 static void aspeed_video_get_resolution(struct aspeed_video *video)
951 bool invalid_resolution = true;
957 struct v4l2_bt_timings *det = &video->detected_timings;
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));
966 set_current_state(TASK_INTERRUPTIBLE);
967 if (schedule_timeout(INVALID_RESOLUTION_DELAY))
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);
976 rc = wait_event_interruptible_timeout(video->wait,
978 MODE_DETECT_TIMEOUT);
980 v4l2_warn(&video->v4l2_dev, "Timed out; first mode detect\n");
981 clear_bit(VIDEO_RES_DETECT, &video->flags);
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))
992 aspeed_video_check_and_set_polarity(video);
994 aspeed_video_enable_mode_detect(video);
996 rc = wait_event_interruptible_timeout(video->wait,
998 MODE_DETECT_TIMEOUT);
999 clear_bit(VIDEO_RES_DETECT, &video->flags);
1001 v4l2_warn(&video->v4l2_dev, "Timed out; second mode detect\n");
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);
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);
1011 if (video->frame_top > video->frame_bottom)
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);
1017 if (video->frame_left > video->frame_right)
1020 invalid_resolution = false;
1021 } while (invalid_resolution && (tries++ < INVALID_RESOLUTION_RETRIES));
1023 if (invalid_resolution) {
1024 v4l2_warn(&video->v4l2_dev, "Invalid resolution detected\n");
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;
1032 aspeed_video_get_timings(video, det);
1035 * Enable mode-detect watchdog, resolution-change watchdog and
1036 * automatic compression after frame capture.
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);
1043 v4l2_dbg(1, debug, &video->v4l2_dev, "Got resolution: %dx%d\n",
1044 det->width, det->height);
1047 static void aspeed_video_set_resolution(struct aspeed_video *video)
1049 struct v4l2_bt_timings *act = &video->active_timings;
1050 unsigned int size = act->width * act->height;
1052 /* Set capture/compression frame sizes */
1053 aspeed_video_calc_compressed_size(video, size);
1055 if (!IS_ALIGNED(act->width, 64)) {
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.
1064 u32 width = ALIGN(act->width, 64);
1066 aspeed_video_write(video, VE_CAP_WINDOW, width << 16 | act->height);
1067 size = width * act->height;
1069 aspeed_video_write(video, VE_CAP_WINDOW,
1070 act->width << 16 | act->height);
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);
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);
1090 v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Direct Mode\n");
1091 aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH);
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]);
1102 if (!aspeed_video_alloc_buf(video, &video->srcs[0], size))
1104 if (!aspeed_video_alloc_buf(video, &video->srcs[1], size))
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);
1118 dev_err(video->dev, "Failed to allocate source buffers\n");
1120 if (video->srcs[0].size)
1121 aspeed_video_free_buf(video, &video->srcs[0]);
1124 static void aspeed_video_init_regs(struct aspeed_video *video)
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;
1133 if (video->frame_rate)
1134 ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
1137 seq_ctrl |= VE_SEQ_CTRL_YUV420;
1139 /* Unlock VE registers */
1140 aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
1142 /* Disable interrupts */
1143 aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
1144 aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
1146 /* Clear the offset */
1147 aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
1148 aspeed_video_write(video, VE_COMP_OFFSET, 0);
1150 aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
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);
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);
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));
1173 static void aspeed_video_start(struct aspeed_video *video)
1175 aspeed_video_on(video);
1177 aspeed_video_init_regs(video);
1179 /* Resolution set to 640x480 if no signal found */
1180 aspeed_video_get_resolution(video);
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);
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;
1191 static void aspeed_video_stop(struct aspeed_video *video)
1193 set_bit(VIDEO_STOPPED, &video->flags);
1194 cancel_delayed_work_sync(&video->res_work);
1196 aspeed_video_off(video);
1198 if (video->srcs[0].size)
1199 aspeed_video_free_buf(video, &video->srcs[0]);
1201 if (video->srcs[1].size)
1202 aspeed_video_free_buf(video, &video->srcs[1]);
1204 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1208 static int aspeed_video_querycap(struct file *file, void *fh,
1209 struct v4l2_capability *cap)
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",
1219 static int aspeed_video_enum_format(struct file *file, void *fh,
1220 struct v4l2_fmtdesc *f)
1225 f->pixelformat = V4L2_PIX_FMT_JPEG;
1230 static int aspeed_video_get_format(struct file *file, void *fh,
1231 struct v4l2_format *f)
1233 struct aspeed_video *video = video_drvdata(file);
1235 f->fmt.pix = video->pix_fmt;
1240 static int aspeed_video_enum_input(struct file *file, void *fh,
1241 struct v4l2_input *inp)
1243 struct aspeed_video *video = video_drvdata(file);
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;
1256 static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
1263 static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
1271 static int aspeed_video_get_parm(struct file *file, void *fh,
1272 struct v4l2_streamparm *a)
1274 struct aspeed_video *video = video_drvdata(file);
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;
1282 a->parm.capture.timeperframe.denominator = video->frame_rate;
1287 static int aspeed_video_set_parm(struct file *file, void *fh,
1288 struct v4l2_streamparm *a)
1290 unsigned int frame_rate = 0;
1291 struct aspeed_video *video = video_drvdata(file);
1293 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1294 a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1296 if (a->parm.capture.timeperframe.numerator)
1297 frame_rate = a->parm.capture.timeperframe.denominator /
1298 a->parm.capture.timeperframe.numerator;
1300 if (!frame_rate || frame_rate > MAX_FRAME_RATE) {
1302 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1303 a->parm.capture.timeperframe.numerator = 1;
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));
1315 static int aspeed_video_enum_framesizes(struct file *file, void *fh,
1316 struct v4l2_frmsizeenum *fsize)
1318 struct aspeed_video *video = video_drvdata(file);
1323 if (fsize->pixel_format != V4L2_PIX_FMT_JPEG)
1326 fsize->discrete.width = video->pix_fmt.width;
1327 fsize->discrete.height = video->pix_fmt.height;
1328 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1333 static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
1334 struct v4l2_frmivalenum *fival)
1336 struct aspeed_video *video = video_drvdata(file);
1341 if (fival->width != video->detected_timings.width ||
1342 fival->height != video->detected_timings.height)
1345 if (fival->pixel_format != V4L2_PIX_FMT_JPEG)
1348 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
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;
1359 static int aspeed_video_set_dv_timings(struct file *file, void *fh,
1360 struct v4l2_dv_timings *timings)
1362 struct aspeed_video *video = video_drvdata(file);
1364 if (timings->bt.width == video->active_timings.width &&
1365 timings->bt.height == video->active_timings.height)
1368 if (vb2_is_busy(&video->queue))
1371 video->active_timings = timings->bt;
1373 aspeed_video_set_resolution(video);
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;
1379 timings->type = V4L2_DV_BT_656_1120;
1381 v4l2_dbg(1, debug, &video->v4l2_dev, "set new timings(%dx%d)\n",
1382 timings->bt.width, timings->bt.height);
1387 static int aspeed_video_get_dv_timings(struct file *file, void *fh,
1388 struct v4l2_dv_timings *timings)
1390 struct aspeed_video *video = video_drvdata(file);
1392 timings->type = V4L2_DV_BT_656_1120;
1393 timings->bt = video->active_timings;
1398 static int aspeed_video_query_dv_timings(struct file *file, void *fh,
1399 struct v4l2_dv_timings *timings)
1402 struct aspeed_video *video = video_drvdata(file);
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.
1409 if (file->f_flags & O_NONBLOCK) {
1410 if (test_bit(VIDEO_RES_CHANGE, &video->flags))
1413 rc = wait_event_interruptible(video->wait,
1414 !test_bit(VIDEO_RES_CHANGE,
1420 timings->type = V4L2_DV_BT_656_1120;
1421 timings->bt = video->detected_timings;
1423 return video->v4l2_input_status ? -ENOLINK : 0;
1426 static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
1427 struct v4l2_enum_dv_timings *timings)
1429 return v4l2_enum_dv_timings_cap(timings, &aspeed_video_timings_cap,
1433 static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
1434 struct v4l2_dv_timings_cap *cap)
1436 *cap = aspeed_video_timings_cap;
1441 static int aspeed_video_sub_event(struct v4l2_fh *fh,
1442 const struct v4l2_event_subscription *sub)
1444 switch (sub->type) {
1445 case V4L2_EVENT_SOURCE_CHANGE:
1446 return v4l2_src_change_event_subscribe(fh, sub);
1449 return v4l2_ctrl_subscribe_event(fh, sub);
1452 static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = {
1453 .vidioc_querycap = aspeed_video_querycap,
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,
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,
1470 .vidioc_enum_input = aspeed_video_enum_input,
1471 .vidioc_g_input = aspeed_video_get_input,
1472 .vidioc_s_input = aspeed_video_set_input,
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,
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,
1485 .vidioc_subscribe_event = aspeed_video_sub_event,
1486 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1489 static void aspeed_video_update_jpeg_quality(struct aspeed_video *video)
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);
1494 aspeed_video_update(video, VE_COMP_CTRL,
1495 VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR,
1499 static void aspeed_video_update_subsampling(struct aspeed_video *video)
1501 if (video->jpeg.virt)
1502 aspeed_video_update_jpeg_table(video->jpeg.virt, video->yuv420);
1505 aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420);
1507 aspeed_video_update(video, VE_SEQ_CTRL, VE_SEQ_CTRL_YUV420, 0);
1510 static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
1512 struct aspeed_video *video = container_of(ctrl->handler,
1513 struct aspeed_video,
1517 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1518 video->jpeg_quality = ctrl->val;
1519 aspeed_video_update_jpeg_quality(video);
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);
1526 video->yuv420 = false;
1527 aspeed_video_update_subsampling(video);
1537 static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
1538 .s_ctrl = aspeed_video_set_ctrl,
1541 static void aspeed_video_resolution_work(struct work_struct *work)
1543 struct delayed_work *dwork = to_delayed_work(work);
1544 struct aspeed_video *video = container_of(dwork, struct aspeed_video,
1547 aspeed_video_on(video);
1549 /* Exit early in case no clients remain */
1550 if (test_bit(VIDEO_STOPPED, &video->flags))
1553 aspeed_video_init_regs(video);
1555 aspeed_video_get_resolution(video);
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,
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);
1572 clear_bit(VIDEO_RES_CHANGE, &video->flags);
1573 wake_up_interruptible_all(&video->wait);
1576 static int aspeed_video_open(struct file *file)
1579 struct aspeed_video *video = video_drvdata(file);
1581 mutex_lock(&video->video_lock);
1583 rc = v4l2_fh_open(file);
1585 mutex_unlock(&video->video_lock);
1589 if (v4l2_fh_is_singular_file(file))
1590 aspeed_video_start(video);
1592 mutex_unlock(&video->video_lock);
1597 static int aspeed_video_release(struct file *file)
1600 struct aspeed_video *video = video_drvdata(file);
1602 mutex_lock(&video->video_lock);
1604 if (v4l2_fh_is_singular_file(file))
1605 aspeed_video_stop(video);
1607 rc = _vb2_fop_release(file, NULL);
1609 mutex_unlock(&video->video_lock);
1614 static const struct v4l2_file_operations aspeed_video_v4l2_fops = {
1615 .owner = THIS_MODULE,
1616 .read = vb2_fop_read,
1617 .poll = vb2_fop_poll,
1618 .unlocked_ioctl = video_ioctl2,
1619 .mmap = vb2_fop_mmap,
1620 .open = aspeed_video_open,
1621 .release = aspeed_video_release,
1624 static int aspeed_video_queue_setup(struct vb2_queue *q,
1625 unsigned int *num_buffers,
1626 unsigned int *num_planes,
1627 unsigned int sizes[],
1628 struct device *alloc_devs[])
1630 struct aspeed_video *video = vb2_get_drv_priv(q);
1633 if (sizes[0] < video->max_compressed_size)
1640 sizes[0] = video->max_compressed_size;
1645 static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
1647 struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1649 if (vb2_plane_size(vb, 0) < video->max_compressed_size)
1655 static int aspeed_video_start_streaming(struct vb2_queue *q,
1659 struct aspeed_video *video = vb2_get_drv_priv(q);
1661 video->sequence = 0;
1662 video->perf.duration_max = 0;
1663 video->perf.duration_min = 0xffffffff;
1665 rc = aspeed_video_start_frame(video);
1667 aspeed_video_bufs_done(video, VB2_BUF_STATE_QUEUED);
1671 set_bit(VIDEO_STREAMING, &video->flags);
1675 static void aspeed_video_stop_streaming(struct vb2_queue *q)
1678 struct aspeed_video *video = vb2_get_drv_priv(q);
1680 clear_bit(VIDEO_STREAMING, &video->flags);
1682 rc = wait_event_timeout(video->wait,
1683 !test_bit(VIDEO_FRAME_INPRG, &video->flags),
1686 v4l2_warn(&video->v4l2_dev, "Timed out when stopping streaming\n");
1689 * Need to force stop any DMA and try and get HW into a good
1690 * state for future calls to start streaming again.
1692 aspeed_video_off(video);
1693 aspeed_video_on(video);
1695 aspeed_video_init_regs(video);
1697 aspeed_video_get_resolution(video);
1700 aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
1703 static void aspeed_video_buf_queue(struct vb2_buffer *vb)
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;
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);
1716 if (test_bit(VIDEO_STREAMING, &video->flags) &&
1717 !test_bit(VIDEO_FRAME_INPRG, &video->flags) && empty)
1718 aspeed_video_start_frame(video);
1721 static const struct vb2_ops aspeed_video_vb2_ops = {
1722 .queue_setup = aspeed_video_queue_setup,
1723 .wait_prepare = vb2_ops_wait_prepare,
1724 .wait_finish = vb2_ops_wait_finish,
1725 .buf_prepare = aspeed_video_buf_prepare,
1726 .start_streaming = aspeed_video_start_streaming,
1727 .stop_streaming = aspeed_video_stop_streaming,
1728 .buf_queue = aspeed_video_buf_queue,
1731 #ifdef CONFIG_DEBUG_FS
1732 static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
1734 struct aspeed_video *v = s->private;
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);
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));
1757 static int aspeed_video_proc_open(struct inode *inode, struct file *file)
1759 return single_open(file, aspeed_video_debugfs_show, inode->i_private);
1762 static const struct file_operations aspeed_video_debugfs_ops = {
1763 .owner = THIS_MODULE,
1764 .open = aspeed_video_proc_open,
1766 .llseek = seq_lseek,
1767 .release = single_release,
1770 static struct dentry *debugfs_entry;
1772 static void aspeed_video_debugfs_remove(struct aspeed_video *video)
1774 debugfs_remove_recursive(debugfs_entry);
1775 debugfs_entry = NULL;
1778 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1780 debugfs_entry = debugfs_create_file(DEVICE_NAME, 0444, NULL,
1782 &aspeed_video_debugfs_ops);
1784 aspeed_video_debugfs_remove(video);
1786 return !debugfs_entry ? -EIO : 0;
1789 static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
1790 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1794 #endif /* CONFIG_DEBUG_FS */
1796 static int aspeed_video_setup_video(struct aspeed_video *video)
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;
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;
1811 rc = v4l2_device_register(video->dev, v4l2_dev);
1813 dev_err(video->dev, "Failed to register v4l2 device\n");
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);
1826 rc = video->ctrl_handler.error;
1828 v4l2_ctrl_handler_free(&video->ctrl_handler);
1829 v4l2_device_unregister(v4l2_dev);
1831 dev_err(video->dev, "Failed to init controls: %d\n", rc);
1835 v4l2_dev->ctrl_handler = &video->ctrl_handler;
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;
1848 rc = vb2_queue_init(vbq);
1850 v4l2_ctrl_handler_free(&video->ctrl_handler);
1851 v4l2_device_unregister(v4l2_dev);
1853 dev_err(video->dev, "Failed to init vb2 queue\n");
1858 vdev->fops = &aspeed_video_v4l2_fops;
1859 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
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;
1869 video_set_drvdata(vdev, video);
1870 rc = video_register_device(vdev, VFL_TYPE_VIDEO, 0);
1872 v4l2_ctrl_handler_free(&video->ctrl_handler);
1873 v4l2_device_unregister(v4l2_dev);
1875 dev_err(video->dev, "Failed to register video device\n");
1882 static int aspeed_video_init(struct aspeed_video *video)
1886 struct device *dev = video->dev;
1888 irq = irq_of_parse_and_map(dev->of_node, 0);
1890 dev_err(dev, "Unable to find IRQ\n");
1894 rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
1895 IRQF_ONESHOT, DEVICE_NAME, video);
1897 dev_err(dev, "Unable to request IRQ %d\n", irq);
1900 dev_info(video->dev, "irq %d\n", irq);
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);
1908 rc = clk_prepare(video->eclk);
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;
1919 rc = clk_prepare(video->vclk);
1921 goto err_unprepare_eclk;
1923 of_reserved_mem_device_init(dev);
1925 rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1927 dev_err(dev, "Failed to set DMA mask\n");
1928 goto err_release_reserved_mem;
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");
1935 goto err_release_reserved_mem;
1937 dev_info(video->dev, "alloc mem size(%d) at %pad for jpeg header\n",
1938 VE_JPEG_HEADER_SIZE, &video->jpeg.dma);
1940 aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
1944 err_release_reserved_mem:
1945 of_reserved_mem_device_release(dev);
1946 clk_unprepare(video->vclk);
1948 clk_unprepare(video->eclk);
1953 static const struct of_device_id aspeed_video_of_match[] = {
1954 { .compatible = "aspeed,ast2400-video-engine", .data = &ast2400_config },
1955 { .compatible = "aspeed,ast2500-video-engine", .data = &ast2500_config },
1956 { .compatible = "aspeed,ast2600-video-engine", .data = &ast2600_config },
1959 MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
1961 static int aspeed_video_probe(struct platform_device *pdev)
1963 const struct aspeed_video_config *config;
1964 struct aspeed_video *video;
1967 video = devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
1971 video->base = devm_platform_ioremap_resource(pdev, 0);
1972 if (IS_ERR(video->base))
1973 return PTR_ERR(video->base);
1975 config = of_device_get_match_data(&pdev->dev);
1979 video->jpeg_mode = config->jpeg_mode;
1980 video->comp_size_read = config->comp_size_read;
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);
1990 rc = aspeed_video_init(video);
1994 rc = aspeed_video_setup_video(video);
1996 aspeed_video_free_buf(video, &video->jpeg);
1997 clk_unprepare(video->vclk);
1998 clk_unprepare(video->eclk);
2002 rc = aspeed_video_debugfs_create(video);
2004 dev_err(video->dev, "debugfs create failed\n");
2009 static int aspeed_video_remove(struct platform_device *pdev)
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);
2015 aspeed_video_off(video);
2017 aspeed_video_debugfs_remove(video);
2019 clk_unprepare(video->vclk);
2020 clk_unprepare(video->eclk);
2022 vb2_video_unregister_device(&video->vdev);
2024 v4l2_ctrl_handler_free(&video->ctrl_handler);
2026 v4l2_device_unregister(v4l2_dev);
2028 aspeed_video_free_buf(video, &video->jpeg);
2030 of_reserved_mem_device_release(dev);
2035 static struct platform_driver aspeed_video_driver = {
2037 .name = DEVICE_NAME,
2038 .of_match_table = aspeed_video_of_match,
2040 .probe = aspeed_video_probe,
2041 .remove = aspeed_video_remove,
2044 module_platform_driver(aspeed_video_driver);
2046 module_param(debug, int, 0644);
2047 MODULE_PARM_DESC(debug, "Debug level (0=off,1=info,2=debug,3=reg ops)");
2049 MODULE_DESCRIPTION("ASPEED Video Engine Driver");
2050 MODULE_AUTHOR("Eddie James");
2051 MODULE_LICENSE("GPL v2");