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>
36 #include <uapi/linux/aspeed-video.h>
38 #define ASPEED_VIDEO_V4L2_MIN_BUF_REQ 3
40 #define DEVICE_NAME "aspeed-video"
42 #define ASPEED_VIDEO_JPEG_NUM_QUALITIES 12
43 #define ASPEED_VIDEO_JPEG_HEADER_SIZE 10
44 #define ASPEED_VIDEO_JPEG_QUANT_SIZE 116
45 #define ASPEED_VIDEO_JPEG_DCT_SIZE 34
47 #define MAX_FRAME_RATE 60
48 #define MAX_HEIGHT 1200
49 #define MAX_WIDTH 1920
50 #define MIN_HEIGHT 480
53 #define NUM_POLARITY_CHECKS 10
54 #define INVALID_RESOLUTION_RETRIES 2
55 #define INVALID_RESOLUTION_DELAY msecs_to_jiffies(250)
56 #define RESOLUTION_CHANGE_DELAY msecs_to_jiffies(500)
57 #define MODE_DETECT_TIMEOUT msecs_to_jiffies(500)
58 #define STOP_TIMEOUT msecs_to_jiffies(1000)
59 #define DIRECT_FETCH_THRESHOLD 0x0c0000 /* 1024 * 768 */
61 #define VE_MAX_SRC_BUFFER_SIZE 0x8ca000 /* 1920 * 1200, 32bpp */
62 #define VE_JPEG_HEADER_SIZE 0x006000 /* 512 * 12 * 4 */
63 #define VE_BCD_BUFF_SIZE 0x9000 /* (1920/8) * (1200/8) */
65 #define VE_PROTECTION_KEY 0x000
66 #define VE_PROTECTION_KEY_UNLOCK 0x1a038aa8
68 #define VE_SEQ_CTRL 0x004
69 #define VE_SEQ_CTRL_TRIG_MODE_DET BIT(0)
70 #define VE_SEQ_CTRL_TRIG_CAPTURE BIT(1)
71 #define VE_SEQ_CTRL_FORCE_IDLE BIT(2)
72 #define VE_SEQ_CTRL_MULT_FRAME BIT(3)
73 #define VE_SEQ_CTRL_TRIG_COMP BIT(4)
74 #define VE_SEQ_CTRL_AUTO_COMP BIT(5)
75 #define VE_SEQ_CTRL_EN_WATCHDOG BIT(7)
76 #define VE_SEQ_CTRL_YUV420 BIT(10)
77 #define VE_SEQ_CTRL_COMP_FMT GENMASK(11, 10)
78 #define VE_SEQ_CTRL_HALT BIT(12)
79 #define VE_SEQ_CTRL_EN_WATCHDOG_COMP BIT(14)
80 #define VE_SEQ_CTRL_TRIG_JPG BIT(15)
81 #define VE_SEQ_CTRL_CAP_BUSY BIT(16)
82 #define VE_SEQ_CTRL_COMP_BUSY BIT(18)
84 #define AST2500_VE_SEQ_CTRL_JPEG_MODE BIT(13)
85 #define AST2400_VE_SEQ_CTRL_JPEG_MODE BIT(8)
88 #define VE_CTRL_HSYNC_POL BIT(0)
89 #define VE_CTRL_VSYNC_POL BIT(1)
90 #define VE_CTRL_SOURCE BIT(2)
91 #define VE_CTRL_INT_DE BIT(4)
92 #define VE_CTRL_DIRECT_FETCH BIT(5)
93 #define VE_CTRL_CAPTURE_FMT GENMASK(7, 6)
94 #define VE_CTRL_AUTO_OR_CURSOR BIT(8)
95 #define VE_CTRL_CLK_INVERSE BIT(11)
96 #define VE_CTRL_CLK_DELAY GENMASK(11, 9)
97 #define VE_CTRL_INTERLACE BIT(14)
98 #define VE_CTRL_HSYNC_POL_CTRL BIT(15)
99 #define VE_CTRL_FRC GENMASK(23, 16)
101 #define VE_TGS_0 0x00c
102 #define VE_TGS_1 0x010
103 #define VE_TGS_FIRST GENMASK(28, 16)
104 #define VE_TGS_LAST GENMASK(12, 0)
106 #define VE_SCALING_FACTOR 0x014
107 #define VE_SCALING_FILTER0 0x018
108 #define VE_SCALING_FILTER1 0x01c
109 #define VE_SCALING_FILTER2 0x020
110 #define VE_SCALING_FILTER3 0x024
112 #define VE_BCD_CTRL 0x02C
113 #define VE_BCD_CTRL_EN_BCD BIT(0)
114 #define VE_BCD_CTRL_EN_ABCD BIT(1)
115 #define VE_BCD_CTRL_EN_CB BIT(2)
116 #define VE_BCD_CTRL_THR GENMASK(23, 16)
117 #define VE_BCD_CTRL_ABCD_THR GENMASK(31, 24)
119 #define VE_CAP_WINDOW 0x030
120 #define VE_COMP_WINDOW 0x034
121 #define VE_COMP_PROC_OFFSET 0x038
122 #define VE_COMP_OFFSET 0x03c
123 #define VE_JPEG_ADDR 0x040
124 #define VE_SRC0_ADDR 0x044
125 #define VE_SRC_SCANLINE_OFFSET 0x048
126 #define VE_SRC1_ADDR 0x04c
127 #define VE_BCD_ADDR 0x050
128 #define VE_COMP_ADDR 0x054
130 #define VE_STREAM_BUF_SIZE 0x058
131 #define VE_STREAM_BUF_SIZE_N_PACKETS GENMASK(5, 3)
132 #define VE_STREAM_BUF_SIZE_P_SIZE GENMASK(2, 0)
134 #define VE_COMP_CTRL 0x060
135 #define VE_COMP_CTRL_VQ_DCT_ONLY BIT(0)
136 #define VE_COMP_CTRL_VQ_4COLOR BIT(1)
137 #define VE_COMP_CTRL_QUANTIZE BIT(2)
138 #define VE_COMP_CTRL_EN_BQ BIT(4)
139 #define VE_COMP_CTRL_EN_CRYPTO BIT(5)
140 #define VE_COMP_CTRL_DCT_CHR GENMASK(10, 6)
141 #define VE_COMP_CTRL_DCT_LUM GENMASK(15, 11)
142 #define VE_COMP_CTRL_EN_HQ BIT(16)
143 #define VE_COMP_CTRL_RSVD BIT(19)
144 #define VE_COMP_CTRL_ENCODE GENMASK(21, 20)
145 #define VE_COMP_CTRL_HQ_DCT_CHR GENMASK(26, 22)
146 #define VE_COMP_CTRL_HQ_DCT_LUM GENMASK(31, 27)
148 #define VE_CB_ADDR 0x06C
150 #define AST2400_VE_COMP_SIZE_READ_BACK 0x078
151 #define AST2600_VE_COMP_SIZE_READ_BACK 0x084
153 #define VE_SRC_LR_EDGE_DET 0x090
154 #define VE_SRC_LR_EDGE_DET_LEFT GENMASK(11, 0)
155 #define VE_SRC_LR_EDGE_DET_NO_V BIT(12)
156 #define VE_SRC_LR_EDGE_DET_NO_H BIT(13)
157 #define VE_SRC_LR_EDGE_DET_NO_DISP BIT(14)
158 #define VE_SRC_LR_EDGE_DET_NO_CLK BIT(15)
159 #define VE_SRC_LR_EDGE_DET_RT GENMASK(27, 16)
160 #define VE_SRC_LR_EDGE_DET_INTERLACE BIT(31)
162 #define VE_SRC_TB_EDGE_DET 0x094
163 #define VE_SRC_TB_EDGE_DET_TOP GENMASK(12, 0)
164 #define VE_SRC_TB_EDGE_DET_BOT GENMASK(28, 16)
166 #define VE_MODE_DETECT_STATUS 0x098
167 #define VE_MODE_DETECT_H_PERIOD GENMASK(11, 0)
168 #define VE_MODE_DETECT_EXTSRC_ADC BIT(12)
169 #define VE_MODE_DETECT_H_STABLE BIT(13)
170 #define VE_MODE_DETECT_V_STABLE BIT(14)
171 #define VE_MODE_DETECT_V_LINES GENMASK(27, 16)
172 #define VE_MODE_DETECT_STATUS_VSYNC BIT(28)
173 #define VE_MODE_DETECT_STATUS_HSYNC BIT(29)
174 #define VE_MODE_DETECT_VSYNC_RDY BIT(30)
175 #define VE_MODE_DETECT_HSYNC_RDY BIT(31)
177 #define VE_SYNC_STATUS 0x09c
178 #define VE_SYNC_STATUS_HSYNC GENMASK(11, 0)
179 #define VE_SYNC_STATUS_VSYNC GENMASK(27, 16)
181 #define VE_H_TOTAL_PIXELS 0x0A0
183 #define VE_INTERRUPT_CTRL 0x304
184 #define VE_INTERRUPT_STATUS 0x308
185 #define VE_INTERRUPT_MODE_DETECT_WD BIT(0)
186 #define VE_INTERRUPT_CAPTURE_COMPLETE BIT(1)
187 #define VE_INTERRUPT_COMP_READY BIT(2)
188 #define VE_INTERRUPT_COMP_COMPLETE BIT(3)
189 #define VE_INTERRUPT_MODE_DETECT BIT(4)
190 #define VE_INTERRUPT_FRAME_COMPLETE BIT(5)
191 #define VE_INTERRUPT_DECODE_ERR BIT(6)
192 #define VE_INTERRUPT_HALT_READY BIT(8)
193 #define VE_INTERRUPT_HANG_WD BIT(9)
194 #define VE_INTERRUPT_STREAM_DESC BIT(10)
195 #define VE_INTERRUPT_VSYNC_DESC BIT(11)
197 #define VE_MODE_DETECT 0x30c
198 #define VE_MODE_DT_HOR_TOLER GENMASK(31, 28)
199 #define VE_MODE_DT_VER_TOLER GENMASK(27, 24)
200 #define VE_MODE_DT_HOR_STABLE GENMASK(23, 20)
201 #define VE_MODE_DT_VER_STABLE GENMASK(19, 16)
202 #define VE_MODE_DT_EDG_THROD GENMASK(15, 8)
204 #define VE_MEM_RESTRICT_START 0x310
205 #define VE_MEM_RESTRICT_END 0x314
208 * VIDEO_MODE_DETECT_DONE: a flag raised if signal lock
209 * VIDEO_RES_CHANGE: a flag raised if res_change work on-going
210 * VIDEO_RES_DETECT: a flag raised if res. detection on-going
211 * VIDEO_STREAMING: a flag raised if user requires stream-on
212 * VIDEO_FRAME_INPRG: a flag raised if hw working on a frame
213 * VIDEO_STOPPED: a flag raised if device release
214 * VIDEO_CLOCKS_ON: a flag raised if clk is on
217 VIDEO_MODE_DETECT_DONE,
226 enum aspeed_video_format {
227 VIDEO_FMT_STANDARD = 0,
229 VIDEO_FMT_MAX = VIDEO_FMT_ASPEED
232 // for VE_CTRL_CAPTURE_FMT
233 enum aspeed_video_capture_format {
234 VIDEO_CAP_FMT_YUV_STUDIO_SWING = 0,
235 VIDEO_CAP_FMT_YUV_FULL_SWING,
241 struct aspeed_video_addr {
247 struct aspeed_video_buffer {
248 struct vb2_v4l2_buffer vb;
249 struct list_head link;
252 struct aspeed_video_perf {
260 #define to_aspeed_video_buffer(x) \
261 container_of((x), struct aspeed_video_buffer, vb)
264 * struct aspeed_video - driver data
266 * res_work: holds the delayed_work for res-detection if unlock
267 * buffers: holds the list of buffer queued from user
268 * flags: holds the state of video
269 * sequence: holds the last number of frame completed
270 * max_compressed_size: holds max compressed stream's size
271 * srcs: holds the buffer information for srcs
272 * jpeg: holds the buffer information for jpeg header
273 * bcd: holds the buffer information for bcd work
274 * yuv420: a flag raised if JPEG subsampling is 420
275 * format: holds the video format
276 * hq_mode: a flag raised if HQ is enabled. Only for VIDEO_FMT_ASPEED
277 * frame_rate: holds the frame_rate
278 * jpeg_quality: holds jpeq's quality (0~11)
279 * jpeg_hq_quality: holds hq's quality (1~12) only if hq_mode enabled
280 * frame_bottom: end position of video data in vertical direction
281 * frame_left: start position of video data in horizontal direction
282 * frame_right: end position of video data in horizontal direction
283 * frame_top: start position of video data in vertical direction
284 * perf: holds the statistics primary for debugfs
286 struct aspeed_video {
292 struct v4l2_ctrl_handler ctrl_handler;
293 struct v4l2_device v4l2_dev;
294 struct v4l2_pix_format pix_fmt;
295 struct v4l2_bt_timings active_timings;
296 struct v4l2_bt_timings detected_timings;
297 u32 v4l2_input_status;
298 struct vb2_queue queue;
299 struct video_device vdev;
300 struct mutex video_lock; /* v4l2 and videobuf2 lock */
305 wait_queue_head_t wait;
306 spinlock_t lock; /* buffer list lock */
307 struct delayed_work res_work;
308 struct list_head buffers;
310 unsigned int sequence;
312 unsigned int max_compressed_size;
313 struct aspeed_video_addr srcs[2];
314 struct aspeed_video_addr jpeg;
315 struct aspeed_video_addr bcd;
318 enum aspeed_video_format format;
320 unsigned int frame_rate;
321 unsigned int jpeg_quality;
322 unsigned int jpeg_hq_quality;
324 unsigned int frame_bottom;
325 unsigned int frame_left;
326 unsigned int frame_right;
327 unsigned int frame_top;
329 struct aspeed_video_perf perf;
332 #define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
334 struct aspeed_video_config {
339 static const struct aspeed_video_config ast2400_config = {
340 .jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
341 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
344 static const struct aspeed_video_config ast2500_config = {
345 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
346 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
349 static const struct aspeed_video_config ast2600_config = {
350 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
351 .comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
354 static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
355 0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
356 0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
359 static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] = {
360 0x081100c0, 0x00000000, 0x00110103, 0x03011102, 0xc4ff0111, 0x00001f00,
361 0x01010501, 0x01010101, 0x00000000, 0x00000000, 0x04030201, 0x08070605,
362 0xff0b0a09, 0x10b500c4, 0x03010200, 0x03040203, 0x04040505, 0x7d010000,
363 0x00030201, 0x12051104, 0x06413121, 0x07615113, 0x32147122, 0x08a19181,
364 0xc1b14223, 0xf0d15215, 0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
365 0x35342a29, 0x39383736, 0x4544433a, 0x49484746, 0x5554534a, 0x59585756,
366 0x6564635a, 0x69686766, 0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
367 0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4, 0xb2aaa9a8, 0xb6b5b4b3,
368 0xbab9b8b7, 0xc5c4c3c2, 0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
369 0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5, 0xc4fffaf9, 0x00011f00,
370 0x01010103, 0x01010101, 0x00000101, 0x00000000, 0x04030201, 0x08070605,
371 0xff0b0a09, 0x11b500c4, 0x02010200, 0x04030404, 0x04040507, 0x77020100,
372 0x03020100, 0x21050411, 0x41120631, 0x71610751, 0x81322213, 0x91421408,
373 0x09c1b1a1, 0xf0523323, 0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
374 0x2a292827, 0x38373635, 0x44433a39, 0x48474645, 0x54534a49, 0x58575655,
375 0x64635a59, 0x68676665, 0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
376 0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2, 0xa9a8a7a6, 0xb4b3b2aa,
377 0xb8b7b6b5, 0xc3c2bab9, 0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
378 0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5, 0xdafffaf9, 0x01030c00,
379 0x03110200, 0x003f0011
382 static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
383 [ASPEED_VIDEO_JPEG_DCT_SIZE] = {
384 { 0x0d140043, 0x0c0f110f, 0x11101114, 0x17141516, 0x1e20321e,
385 0x3d1e1b1b, 0x32242e2b, 0x4b4c3f48, 0x44463f47, 0x61735a50,
386 0x566c5550, 0x88644644, 0x7a766c65, 0x4d808280, 0x8c978d60,
387 0x7e73967d, 0xdbff7b80, 0x1f014300, 0x272d2121, 0x3030582d,
388 0x697bb958, 0xb8b9b97b, 0xb9b8a6a6, 0xb9b9b9b9, 0xb9b9b9b9,
389 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9,
390 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xffb9b9b9 },
391 { 0x0c110043, 0x0a0d0f0d, 0x0f0e0f11, 0x14111213, 0x1a1c2b1a,
392 0x351a1818, 0x2b1f2826, 0x4142373f, 0x3c3d373e, 0x55644e46,
393 0x4b5f4a46, 0x77573d3c, 0x6b675f58, 0x43707170, 0x7a847b54,
394 0x6e64836d, 0xdbff6c70, 0x1b014300, 0x22271d1d, 0x2a2a4c27,
395 0x5b6ba04c, 0xa0a0a06b, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
396 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
397 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xffa0a0a0 },
398 { 0x090e0043, 0x090a0c0a, 0x0c0b0c0e, 0x110e0f10, 0x15172415,
399 0x2c151313, 0x241a211f, 0x36372e34, 0x31322e33, 0x4653413a,
400 0x3e4e3d3a, 0x62483231, 0x58564e49, 0x385d5e5d, 0x656d6645,
401 0x5b536c5a, 0xdbff595d, 0x16014300, 0x1c201818, 0x22223f20,
402 0x4b58853f, 0x85858558, 0x85858585, 0x85858585, 0x85858585,
403 0x85858585, 0x85858585, 0x85858585, 0x85858585, 0x85858585,
404 0x85858585, 0x85858585, 0x85858585, 0xff858585 },
405 { 0x070b0043, 0x07080a08, 0x0a090a0b, 0x0d0b0c0c, 0x11121c11,
406 0x23110f0f, 0x1c141a19, 0x2b2b2429, 0x27282428, 0x3842332e,
407 0x313e302e, 0x4e392827, 0x46443e3a, 0x2c4a4a4a, 0x50565137,
408 0x48425647, 0xdbff474a, 0x12014300, 0x161a1313, 0x1c1c331a,
409 0x3d486c33, 0x6c6c6c48, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
410 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
411 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0xff6c6c6c },
412 { 0x06090043, 0x05060706, 0x07070709, 0x0a09090a, 0x0d0e160d,
413 0x1b0d0c0c, 0x16101413, 0x21221c20, 0x1e1f1c20, 0x2b332824,
414 0x26302624, 0x3d2d1f1e, 0x3735302d, 0x22393a39, 0x3f443f2b,
415 0x38334338, 0xdbff3739, 0x0d014300, 0x11130e0e, 0x15152613,
416 0x2d355026, 0x50505035, 0x50505050, 0x50505050, 0x50505050,
417 0x50505050, 0x50505050, 0x50505050, 0x50505050, 0x50505050,
418 0x50505050, 0x50505050, 0x50505050, 0xff505050 },
419 { 0x04060043, 0x03040504, 0x05040506, 0x07060606, 0x09090f09,
420 0x12090808, 0x0f0a0d0d, 0x16161315, 0x14151315, 0x1d221b18,
421 0x19201918, 0x281e1514, 0x2423201e, 0x17262726, 0x2a2d2a1c,
422 0x25222d25, 0xdbff2526, 0x09014300, 0x0b0d0a0a, 0x0e0e1a0d,
423 0x1f25371a, 0x37373725, 0x37373737, 0x37373737, 0x37373737,
424 0x37373737, 0x37373737, 0x37373737, 0x37373737, 0x37373737,
425 0x37373737, 0x37373737, 0x37373737, 0xff373737 },
426 { 0x02030043, 0x01020202, 0x02020203, 0x03030303, 0x04040704,
427 0x09040404, 0x07050606, 0x0b0b090a, 0x0a0a090a, 0x0e110d0c,
428 0x0c100c0c, 0x140f0a0a, 0x1211100f, 0x0b131313, 0x1516150e,
429 0x12111612, 0xdbff1213, 0x04014300, 0x05060505, 0x07070d06,
430 0x0f121b0d, 0x1b1b1b12, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
431 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
432 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0xff1b1b1b },
433 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
434 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
435 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
436 0x0c0b0f0c, 0xdbff0c0c, 0x03014300, 0x03040303, 0x04040804,
437 0x0a0c1208, 0x1212120c, 0x12121212, 0x12121212, 0x12121212,
438 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
439 0x12121212, 0x12121212, 0x12121212, 0xff121212 },
440 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
441 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
442 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
443 0x0c0b0f0c, 0xdbff0c0c, 0x02014300, 0x03030202, 0x04040703,
444 0x080a0f07, 0x0f0f0f0a, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
445 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
446 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xff0f0f0f },
447 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x02020302,
448 0x04020202, 0x03020303, 0x05050405, 0x05050405, 0x07080606,
449 0x06080606, 0x0a070505, 0x09080807, 0x05090909, 0x0a0b0a07,
450 0x09080b09, 0xdbff0909, 0x02014300, 0x02030202, 0x03030503,
451 0x07080c05, 0x0c0c0c08, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
452 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
453 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xff0c0c0c },
454 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010201,
455 0x03010101, 0x02010202, 0x03030303, 0x03030303, 0x04050404,
456 0x04050404, 0x06050303, 0x06050505, 0x03060606, 0x07070704,
457 0x06050706, 0xdbff0606, 0x01014300, 0x01020101, 0x02020402,
458 0x05060904, 0x09090906, 0x09090909, 0x09090909, 0x09090909,
459 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
460 0x09090909, 0x09090909, 0x09090909, 0xff090909 },
461 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
462 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202,
463 0x02020202, 0x03020101, 0x03020202, 0x01030303, 0x03030302,
464 0x03020303, 0xdbff0403, 0x01014300, 0x01010101, 0x01010201,
465 0x03040602, 0x06060604, 0x06060606, 0x06060606, 0x06060606,
466 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
467 0x06060606, 0x06060606, 0x06060606, 0xff060606 }
470 static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
471 .type = V4L2_DV_BT_656_1120,
473 .min_width = MIN_WIDTH,
474 .max_width = MAX_WIDTH,
475 .min_height = MIN_HEIGHT,
476 .max_height = MAX_HEIGHT,
477 .min_pixelclock = 6574080, /* 640 x 480 x 24Hz */
478 .max_pixelclock = 138240000, /* 1920 x 1200 x 60Hz */
479 .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
480 V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
481 .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
482 V4L2_DV_BT_CAP_REDUCED_BLANKING |
483 V4L2_DV_BT_CAP_CUSTOM,
487 static const char * const format_str[] = {"Standard JPEG",
490 static unsigned int debug;
492 static bool aspeed_video_alloc_buf(struct aspeed_video *video,
493 struct aspeed_video_addr *addr,
496 static void aspeed_video_free_buf(struct aspeed_video *video,
497 struct aspeed_video_addr *addr);
499 static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
504 for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
505 base = 256 * i; /* AST HW requires this header spacing */
506 memcpy(&table[base], aspeed_video_jpeg_header,
507 sizeof(aspeed_video_jpeg_header));
509 base += ASPEED_VIDEO_JPEG_HEADER_SIZE;
510 memcpy(&table[base], aspeed_video_jpeg_dct[i],
511 sizeof(aspeed_video_jpeg_dct[i]));
513 base += ASPEED_VIDEO_JPEG_DCT_SIZE;
514 memcpy(&table[base], aspeed_video_jpeg_quant,
515 sizeof(aspeed_video_jpeg_quant));
518 table[base + 2] = 0x00220103;
522 // just update jpeg dct table per 420/444
523 static void aspeed_video_update_jpeg_table(u32 *table, bool yuv420)
528 for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
529 base = 256 * i; /* AST HW requires this header spacing */
530 base += ASPEED_VIDEO_JPEG_HEADER_SIZE +
531 ASPEED_VIDEO_JPEG_DCT_SIZE;
533 table[base + 2] = (yuv420) ? 0x00220103 : 0x00110103;
537 static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
540 u32 t = readl(video->base + reg);
545 writel(t, video->base + reg);
546 v4l2_dbg(3, debug, &video->v4l2_dev, "update %03x[%08x -> %08x]\n",
547 reg, before, readl(video->base + reg));
550 static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
552 u32 t = readl(video->base + reg);
554 v4l2_dbg(3, debug, &video->v4l2_dev, "read %03x[%08x]\n", reg, t);
558 static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
560 writel(val, video->base + reg);
561 v4l2_dbg(3, debug, &video->v4l2_dev, "write %03x[%08x]\n", reg,
562 readl(video->base + reg));
565 static void update_perf(struct aspeed_video_perf *p)
567 struct aspeed_video *v = container_of(p, struct aspeed_video,
571 ktime_to_ms(ktime_sub(ktime_get(), p->last_sample));
572 p->totaltime += p->duration;
574 p->duration_max = max(p->duration, p->duration_max);
575 p->duration_min = min(p->duration, p->duration_min);
576 v4l2_dbg(2, debug, &v->v4l2_dev, "time consumed: %d ms\n",
580 static int aspeed_video_start_frame(struct aspeed_video *video)
584 struct aspeed_video_buffer *buf;
585 u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
586 bool bcd_buf_need = (video->format != VIDEO_FMT_STANDARD);
588 if (video->v4l2_input_status) {
589 v4l2_dbg(1, debug, &video->v4l2_dev, "No signal; don't start frame\n");
593 if (!(seq_ctrl & VE_SEQ_CTRL_COMP_BUSY) ||
594 !(seq_ctrl & VE_SEQ_CTRL_CAP_BUSY)) {
595 v4l2_dbg(1, debug, &video->v4l2_dev, "Engine busy; don't start frame\n");
599 if (bcd_buf_need && !video->bcd.size) {
600 if (!aspeed_video_alloc_buf(video, &video->bcd,
602 dev_err(video->dev, "Failed to allocate BCD buffer\n");
603 dev_err(video->dev, "don't start frame\n");
606 aspeed_video_write(video, VE_BCD_ADDR, video->bcd.dma);
607 v4l2_dbg(1, debug, &video->v4l2_dev, "bcd addr(%pad) size(%d)\n",
608 &video->bcd.dma, video->bcd.size);
609 } else if (!bcd_buf_need && video->bcd.size) {
610 aspeed_video_free_buf(video, &video->bcd);
613 spin_lock_irqsave(&video->lock, flags);
614 buf = list_first_entry_or_null(&video->buffers,
615 struct aspeed_video_buffer, link);
617 spin_unlock_irqrestore(&video->lock, flags);
618 v4l2_dbg(1, debug, &video->v4l2_dev, "No buffers; don't start frame\n");
622 set_bit(VIDEO_FRAME_INPRG, &video->flags);
623 addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
624 spin_unlock_irqrestore(&video->lock, flags);
626 aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
627 aspeed_video_write(video, VE_COMP_OFFSET, 0);
628 aspeed_video_write(video, VE_COMP_ADDR, addr);
630 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
631 VE_INTERRUPT_COMP_COMPLETE);
633 video->perf.last_sample = ktime_get();
635 aspeed_video_update(video, VE_SEQ_CTRL, 0,
636 VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
641 static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
643 /* Enable mode detect interrupts */
644 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
645 VE_INTERRUPT_MODE_DETECT);
647 /* Disable mode detect in order to re-trigger */
648 aspeed_video_update(video, VE_SEQ_CTRL,
649 VE_SEQ_CTRL_TRIG_MODE_DET, 0);
651 /* Trigger mode detect */
652 aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET);
655 static void aspeed_video_off(struct aspeed_video *video)
657 if (!test_bit(VIDEO_CLOCKS_ON, &video->flags))
660 /* Disable interrupts */
661 aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
662 aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
664 /* Turn off the relevant clocks */
665 clk_disable(video->eclk);
666 clk_disable(video->vclk);
668 clear_bit(VIDEO_CLOCKS_ON, &video->flags);
671 static void aspeed_video_on(struct aspeed_video *video)
673 if (test_bit(VIDEO_CLOCKS_ON, &video->flags))
676 /* Turn on the relevant clocks */
677 clk_enable(video->vclk);
678 clk_enable(video->eclk);
680 set_bit(VIDEO_CLOCKS_ON, &video->flags);
683 static void aspeed_video_bufs_done(struct aspeed_video *video,
684 enum vb2_buffer_state state)
687 struct aspeed_video_buffer *buf;
689 spin_lock_irqsave(&video->lock, flags);
690 list_for_each_entry(buf, &video->buffers, link)
691 vb2_buffer_done(&buf->vb.vb2_buf, state);
692 INIT_LIST_HEAD(&video->buffers);
693 spin_unlock_irqrestore(&video->lock, flags);
696 static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
698 v4l2_dbg(1, debug, &video->v4l2_dev, "Resolution changed; resetting\n");
700 set_bit(VIDEO_RES_CHANGE, &video->flags);
701 clear_bit(VIDEO_FRAME_INPRG, &video->flags);
703 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
705 aspeed_video_off(video);
706 aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
708 schedule_delayed_work(&video->res_work, delay);
711 static void aspeed_video_swap_src_buf(struct aspeed_video *v)
713 if (v->format == VIDEO_FMT_STANDARD)
716 /* Reset bcd buffer to have a full frame update every 8 frames. */
717 if (IS_ALIGNED(v->sequence, 8))
718 memset((u8 *)v->bcd.virt, 0x00, VE_BCD_BUFF_SIZE);
720 if (v->sequence & 0x01) {
721 aspeed_video_write(v, VE_SRC0_ADDR, v->srcs[1].dma);
722 aspeed_video_write(v, VE_SRC1_ADDR, v->srcs[0].dma);
724 aspeed_video_write(v, VE_SRC0_ADDR, v->srcs[0].dma);
725 aspeed_video_write(v, VE_SRC1_ADDR, v->srcs[1].dma);
729 static irqreturn_t aspeed_video_irq(int irq, void *arg)
731 struct aspeed_video *video = arg;
732 u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
735 * Hardware sometimes asserts interrupts that we haven't actually
736 * enabled; ignore them if so.
738 sts &= aspeed_video_read(video, VE_INTERRUPT_CTRL);
740 v4l2_dbg(2, debug, &video->v4l2_dev, "irq sts=%#x %s%s%s%s\n", sts,
741 sts & VE_INTERRUPT_MODE_DETECT_WD ? ", unlock" : "",
742 sts & VE_INTERRUPT_MODE_DETECT ? ", lock" : "",
743 sts & VE_INTERRUPT_CAPTURE_COMPLETE ? ", capture-done" : "",
744 sts & VE_INTERRUPT_COMP_COMPLETE ? ", comp-done" : "");
747 * Resolution changed or signal was lost; reset the engine and
750 if (sts & VE_INTERRUPT_MODE_DETECT_WD) {
751 aspeed_video_irq_res_change(video, 0);
755 if (sts & VE_INTERRUPT_MODE_DETECT) {
756 if (test_bit(VIDEO_RES_DETECT, &video->flags)) {
757 aspeed_video_update(video, VE_INTERRUPT_CTRL,
758 VE_INTERRUPT_MODE_DETECT, 0);
759 aspeed_video_write(video, VE_INTERRUPT_STATUS,
760 VE_INTERRUPT_MODE_DETECT);
761 sts &= ~VE_INTERRUPT_MODE_DETECT;
762 set_bit(VIDEO_MODE_DETECT_DONE, &video->flags);
763 wake_up_interruptible_all(&video->wait);
766 * Signal acquired while NOT doing resolution
767 * detection; reset the engine and re-initialize
769 aspeed_video_irq_res_change(video,
770 RESOLUTION_CHANGE_DELAY);
775 if (sts & VE_INTERRUPT_COMP_COMPLETE) {
776 struct aspeed_video_buffer *buf;
778 u32 frame_size = aspeed_video_read(video,
779 video->comp_size_read);
781 update_perf(&video->perf);
783 spin_lock(&video->lock);
784 clear_bit(VIDEO_FRAME_INPRG, &video->flags);
785 buf = list_first_entry_or_null(&video->buffers,
786 struct aspeed_video_buffer,
789 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, frame_size);
792 * aspeed_jpeg requires continuous update.
793 * On the contrary, standard jpeg can keep last buffer
794 * to always have the latest result.
796 if (video->format == VIDEO_FMT_STANDARD &&
797 list_is_last(&buf->link, &video->buffers)) {
799 v4l2_dbg(1, debug, &video->v4l2_dev, "skip to keep last frame updated\n");
801 buf->vb.vb2_buf.timestamp = ktime_get_ns();
802 buf->vb.sequence = video->sequence++;
803 buf->vb.field = V4L2_FIELD_NONE;
804 vb2_buffer_done(&buf->vb.vb2_buf,
806 list_del(&buf->link);
807 empty = list_empty(&video->buffers);
810 spin_unlock(&video->lock);
812 aspeed_video_update(video, VE_SEQ_CTRL,
813 VE_SEQ_CTRL_TRIG_CAPTURE |
814 VE_SEQ_CTRL_FORCE_IDLE |
815 VE_SEQ_CTRL_TRIG_COMP, 0);
816 aspeed_video_update(video, VE_INTERRUPT_CTRL,
817 VE_INTERRUPT_COMP_COMPLETE, 0);
818 aspeed_video_write(video, VE_INTERRUPT_STATUS,
819 VE_INTERRUPT_COMP_COMPLETE);
820 sts &= ~VE_INTERRUPT_COMP_COMPLETE;
822 aspeed_video_swap_src_buf(video);
824 if (test_bit(VIDEO_STREAMING, &video->flags) && !empty)
825 aspeed_video_start_frame(video);
828 return sts ? IRQ_NONE : IRQ_HANDLED;
831 static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
834 int hsync_counter = 0;
835 int vsync_counter = 0;
838 for (i = 0; i < NUM_POLARITY_CHECKS; ++i) {
839 sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
840 if (sts & VE_MODE_DETECT_STATUS_VSYNC)
845 if (sts & VE_MODE_DETECT_STATUS_HSYNC)
851 ctrl = aspeed_video_read(video, VE_CTRL);
853 if (hsync_counter < 0) {
854 ctrl |= VE_CTRL_HSYNC_POL;
855 video->detected_timings.polarities &=
856 ~V4L2_DV_HSYNC_POS_POL;
858 ctrl &= ~VE_CTRL_HSYNC_POL;
859 video->detected_timings.polarities |=
860 V4L2_DV_HSYNC_POS_POL;
863 if (vsync_counter < 0) {
864 ctrl |= VE_CTRL_VSYNC_POL;
865 video->detected_timings.polarities &=
866 ~V4L2_DV_VSYNC_POS_POL;
868 ctrl &= ~VE_CTRL_VSYNC_POL;
869 video->detected_timings.polarities |=
870 V4L2_DV_VSYNC_POS_POL;
873 aspeed_video_write(video, VE_CTRL, ctrl);
876 static bool aspeed_video_alloc_buf(struct aspeed_video *video,
877 struct aspeed_video_addr *addr,
880 addr->virt = dma_alloc_coherent(video->dev, size, &addr->dma,
889 static void aspeed_video_free_buf(struct aspeed_video *video,
890 struct aspeed_video_addr *addr)
892 dma_free_coherent(video->dev, addr->size, addr->virt, addr->dma);
899 * Get the minimum HW-supported compression buffer size for the frame size.
900 * Assume worst-case JPEG compression size is 1/8 raw size. This should be
901 * plenty even for maximum quality; any worse and the engine will simply return
904 static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
905 unsigned int frame_size)
908 u32 compression_buffer_size_reg = 0;
910 const unsigned int num_compression_packets = 4;
911 const unsigned int compression_packet_size = 1024;
912 const unsigned int max_compressed_size = frame_size / 2; /* 4bpp / 8 */
914 video->max_compressed_size = UINT_MAX;
916 for (i = 0; i < 6; ++i) {
917 for (j = 0; j < 8; ++j) {
918 size = (num_compression_packets << i) *
919 (compression_packet_size << j);
920 if (size < max_compressed_size)
923 if (size < video->max_compressed_size) {
924 compression_buffer_size_reg = (i << 3) | j;
925 video->max_compressed_size = size;
930 aspeed_video_write(video, VE_STREAM_BUF_SIZE,
931 compression_buffer_size_reg);
933 v4l2_dbg(1, debug, &video->v4l2_dev, "Max compressed size: %#x\n",
934 video->max_compressed_size);
938 * Update v4l2_bt_timings per current status.
939 * frame_top/frame_bottom/frame_left/frame_right need to be ready.
941 * The following registers start counting from sync's rising edge:
942 * 1. VR090: frame edge's left and right
943 * 2. VR094: frame edge's top and bottom
944 * 3. VR09C: counting from sync's rising edge to falling edge
947 * +--+ +-------------------+ +--+
948 * | | | v i d e o | | |
949 * +--+ +-----+ +-----+ +---+
951 * frame_top+--------+
952 * frame_bottom+----------------------------+
954 * +-------------------+
956 * +--+ +-----+ +-----+ +---+
959 * vsync+-------------------------------+
961 * frame_bottom+-------------------------+
963 * [Horizontal timing]
964 * +--+ +-------------------+ +--+
965 * | | | v i d e o | | |
966 * +--+ +-----+ +-----+ +---+
968 * frame_left+--------+
969 * frame_right+----------------------------+
971 * +-------------------+
973 * +--+ +-----+ +-----+ +---+
976 * hsync+-------------------------------+
978 * frame_right+-------------------------+
980 * @v: the struct of aspeed_video
981 * @det: v4l2_bt_timings to be updated.
983 static void aspeed_video_get_timings(struct aspeed_video *v,
984 struct v4l2_bt_timings *det)
986 u32 mds, sync, htotal, vtotal, vsync, hsync;
988 mds = aspeed_video_read(v, VE_MODE_DETECT_STATUS);
989 sync = aspeed_video_read(v, VE_SYNC_STATUS);
990 htotal = aspeed_video_read(v, VE_H_TOTAL_PIXELS);
991 vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
992 vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
993 hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
996 * This is a workaround for polarity detection.
997 * Because ast-soc counts sync from sync's rising edge, the reg value
998 * of sync would be larger than video's active area if negative.
1000 if (vsync > det->height)
1001 det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
1003 det->polarities |= V4L2_DV_VSYNC_POS_POL;
1004 if (hsync > det->width)
1005 det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
1007 det->polarities |= V4L2_DV_HSYNC_POS_POL;
1009 if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
1010 det->vbackporch = v->frame_top - vsync;
1011 det->vfrontporch = vtotal - v->frame_bottom;
1014 det->vbackporch = v->frame_top;
1015 det->vfrontporch = vsync - v->frame_bottom;
1016 det->vsync = vtotal - vsync;
1019 if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
1020 det->hbackporch = v->frame_left - hsync;
1021 det->hfrontporch = htotal - v->frame_right;
1024 det->hbackporch = v->frame_left;
1025 det->hfrontporch = hsync - v->frame_right;
1026 det->hsync = htotal - hsync;
1030 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
1032 static void aspeed_video_get_resolution(struct aspeed_video *video)
1034 bool invalid_resolution = true;
1040 struct v4l2_bt_timings *det = &video->detected_timings;
1042 det->width = MIN_WIDTH;
1043 det->height = MIN_HEIGHT;
1044 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1045 memset(&video->perf, 0, sizeof(video->perf));
1049 set_current_state(TASK_INTERRUPTIBLE);
1050 if (schedule_timeout(INVALID_RESOLUTION_DELAY))
1054 set_bit(VIDEO_RES_DETECT, &video->flags);
1055 aspeed_video_update(video, VE_CTRL,
1056 VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, 0);
1057 aspeed_video_enable_mode_detect(video);
1059 rc = wait_event_interruptible_timeout(video->wait,
1061 MODE_DETECT_TIMEOUT);
1063 v4l2_dbg(1, debug, &video->v4l2_dev, "Timed out; first mode detect\n");
1064 clear_bit(VIDEO_RES_DETECT, &video->flags);
1068 mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
1069 // try detection again if current signal isn't stable
1070 if (!(mds & VE_MODE_DETECT_H_STABLE) ||
1071 !(mds & VE_MODE_DETECT_V_STABLE) ||
1072 (mds & VE_MODE_DETECT_EXTSRC_ADC))
1075 aspeed_video_check_and_set_polarity(video);
1077 aspeed_video_enable_mode_detect(video);
1079 rc = wait_event_interruptible_timeout(video->wait,
1081 MODE_DETECT_TIMEOUT);
1082 clear_bit(VIDEO_RES_DETECT, &video->flags);
1084 v4l2_dbg(1, debug, &video->v4l2_dev, "Timed out; second mode detect\n");
1088 src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
1089 src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
1091 video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
1092 video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
1094 if (video->frame_top > video->frame_bottom)
1097 video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
1098 video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
1100 if (video->frame_left > video->frame_right)
1103 invalid_resolution = false;
1104 } while (invalid_resolution && (tries++ < INVALID_RESOLUTION_RETRIES));
1106 if (invalid_resolution) {
1107 v4l2_dbg(1, debug, &video->v4l2_dev, "Invalid resolution detected\n");
1111 det->height = (video->frame_bottom - video->frame_top) + 1;
1112 det->width = (video->frame_right - video->frame_left) + 1;
1113 video->v4l2_input_status = 0;
1115 aspeed_video_get_timings(video, det);
1118 * Enable mode-detect watchdog, resolution-change watchdog and
1119 * automatic compression after frame capture.
1121 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
1122 VE_INTERRUPT_MODE_DETECT_WD);
1123 aspeed_video_update(video, VE_SEQ_CTRL, 0,
1124 VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
1126 v4l2_dbg(1, debug, &video->v4l2_dev, "Got resolution: %dx%d\n",
1127 det->width, det->height);
1130 static void aspeed_video_set_resolution(struct aspeed_video *video)
1132 struct v4l2_bt_timings *act = &video->active_timings;
1133 unsigned int size = act->width * act->height;
1135 /* Set capture/compression frame sizes */
1136 aspeed_video_calc_compressed_size(video, size);
1138 if (!IS_ALIGNED(act->width, 64)) {
1140 * This is a workaround to fix a AST2500 silicon bug on A1 and
1141 * A2 revisions. Since it doesn't break capturing operation of
1142 * other revisions, use it for all revisions without checking
1143 * the revision ID. It picked new width which is a very next
1144 * 64-pixels aligned value to minimize memory bandwidth
1145 * and to get better access speed from video engine.
1147 u32 width = ALIGN(act->width, 64);
1149 aspeed_video_write(video, VE_CAP_WINDOW, width << 16 | act->height);
1150 size = width * act->height;
1152 aspeed_video_write(video, VE_CAP_WINDOW,
1153 act->width << 16 | act->height);
1155 aspeed_video_write(video, VE_COMP_WINDOW,
1156 act->width << 16 | act->height);
1157 aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4);
1159 /* Don't use direct mode below 1024 x 768 (irqs don't fire) */
1160 if (size < DIRECT_FETCH_THRESHOLD) {
1161 v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Sync Mode\n");
1162 aspeed_video_write(video, VE_TGS_0,
1163 FIELD_PREP(VE_TGS_FIRST,
1164 video->frame_left - 1) |
1165 FIELD_PREP(VE_TGS_LAST,
1166 video->frame_right));
1167 aspeed_video_write(video, VE_TGS_1,
1168 FIELD_PREP(VE_TGS_FIRST, video->frame_top) |
1169 FIELD_PREP(VE_TGS_LAST,
1170 video->frame_bottom + 1));
1171 aspeed_video_update(video, VE_CTRL,
1172 VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH,
1175 v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Direct Mode\n");
1176 aspeed_video_update(video, VE_CTRL,
1177 VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH,
1178 VE_CTRL_DIRECT_FETCH);
1183 if (size != video->srcs[0].size) {
1184 if (video->srcs[0].size)
1185 aspeed_video_free_buf(video, &video->srcs[0]);
1186 if (video->srcs[1].size)
1187 aspeed_video_free_buf(video, &video->srcs[1]);
1189 if (!aspeed_video_alloc_buf(video, &video->srcs[0], size))
1191 if (!aspeed_video_alloc_buf(video, &video->srcs[1], size))
1194 v4l2_dbg(1, debug, &video->v4l2_dev, "src buf0 addr(%pad) size(%d)\n",
1195 &video->srcs[0].dma, video->srcs[0].size);
1196 v4l2_dbg(1, debug, &video->v4l2_dev, "src buf1 addr(%pad) size(%d)\n",
1197 &video->srcs[1].dma, video->srcs[1].size);
1198 aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma);
1199 aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma);
1205 dev_err(video->dev, "Failed to allocate source buffers\n");
1207 if (video->srcs[0].size)
1208 aspeed_video_free_buf(video, &video->srcs[0]);
1211 static void aspeed_video_update_regs(struct aspeed_video *video)
1213 u8 jpeg_hq_quality = clamp((int)video->jpeg_hq_quality - 1, 0,
1214 ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1);
1215 u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
1216 FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10) |
1217 FIELD_PREP(VE_COMP_CTRL_EN_HQ, video->hq_mode) |
1218 FIELD_PREP(VE_COMP_CTRL_HQ_DCT_LUM, jpeg_hq_quality) |
1219 FIELD_PREP(VE_COMP_CTRL_HQ_DCT_CHR, jpeg_hq_quality | 0x10);
1223 v4l2_dbg(1, debug, &video->v4l2_dev, "framerate(%d)\n",
1225 v4l2_dbg(1, debug, &video->v4l2_dev, "jpeg format(%s) subsample(%s)\n",
1226 format_str[video->format],
1227 video->yuv420 ? "420" : "444");
1228 v4l2_dbg(1, debug, &video->v4l2_dev, "compression quality(%d)\n",
1229 video->jpeg_quality);
1230 v4l2_dbg(1, debug, &video->v4l2_dev, "hq_mode(%s) hq_quality(%d)\n",
1231 video->hq_mode ? "on" : "off", video->jpeg_hq_quality);
1233 if (video->format == VIDEO_FMT_ASPEED)
1234 aspeed_video_update(video, VE_BCD_CTRL, 0, VE_BCD_CTRL_EN_BCD);
1236 aspeed_video_update(video, VE_BCD_CTRL, VE_BCD_CTRL_EN_BCD, 0);
1238 if (video->frame_rate)
1239 ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
1241 if (video->format == VIDEO_FMT_STANDARD) {
1242 comp_ctrl &= ~FIELD_PREP(VE_COMP_CTRL_EN_HQ, video->hq_mode);
1243 seq_ctrl |= video->jpeg_mode;
1247 seq_ctrl |= VE_SEQ_CTRL_YUV420;
1249 if (video->jpeg.virt)
1250 aspeed_video_update_jpeg_table(video->jpeg.virt, video->yuv420);
1252 /* Set control registers */
1253 aspeed_video_update(video, VE_SEQ_CTRL,
1254 video->jpeg_mode | VE_SEQ_CTRL_YUV420,
1256 aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC, ctrl);
1257 aspeed_video_update(video, VE_COMP_CTRL,
1258 VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR |
1259 VE_COMP_CTRL_EN_HQ | VE_COMP_CTRL_HQ_DCT_LUM |
1260 VE_COMP_CTRL_HQ_DCT_CHR | VE_COMP_CTRL_VQ_4COLOR |
1261 VE_COMP_CTRL_VQ_DCT_ONLY,
1265 static void aspeed_video_init_regs(struct aspeed_video *video)
1267 u32 ctrl = VE_CTRL_AUTO_OR_CURSOR |
1268 FIELD_PREP(VE_CTRL_CAPTURE_FMT, VIDEO_CAP_FMT_YUV_FULL_SWING);
1270 /* Unlock VE registers */
1271 aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
1273 /* Disable interrupts */
1274 aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
1275 aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
1277 /* Clear the offset */
1278 aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
1279 aspeed_video_write(video, VE_COMP_OFFSET, 0);
1281 aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
1283 /* Set control registers */
1284 aspeed_video_write(video, VE_CTRL, ctrl);
1285 aspeed_video_write(video, VE_COMP_CTRL, VE_COMP_CTRL_RSVD);
1287 /* Don't downscale */
1288 aspeed_video_write(video, VE_SCALING_FACTOR, 0x10001000);
1289 aspeed_video_write(video, VE_SCALING_FILTER0, 0x00200000);
1290 aspeed_video_write(video, VE_SCALING_FILTER1, 0x00200000);
1291 aspeed_video_write(video, VE_SCALING_FILTER2, 0x00200000);
1292 aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
1294 /* Set mode detection defaults */
1295 aspeed_video_write(video, VE_MODE_DETECT,
1296 FIELD_PREP(VE_MODE_DT_HOR_TOLER, 2) |
1297 FIELD_PREP(VE_MODE_DT_VER_TOLER, 2) |
1298 FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) |
1299 FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) |
1300 FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65));
1302 aspeed_video_write(video, VE_BCD_CTRL, 0);
1305 static void aspeed_video_start(struct aspeed_video *video)
1307 aspeed_video_on(video);
1309 aspeed_video_init_regs(video);
1311 /* Resolution set to 640x480 if no signal found */
1312 aspeed_video_get_resolution(video);
1314 /* Set timings since the device is being opened for the first time */
1315 video->active_timings = video->detected_timings;
1316 aspeed_video_set_resolution(video);
1318 video->pix_fmt.width = video->active_timings.width;
1319 video->pix_fmt.height = video->active_timings.height;
1320 video->pix_fmt.sizeimage = video->max_compressed_size;
1323 static void aspeed_video_stop(struct aspeed_video *video)
1325 set_bit(VIDEO_STOPPED, &video->flags);
1326 cancel_delayed_work_sync(&video->res_work);
1328 aspeed_video_off(video);
1330 if (video->srcs[0].size)
1331 aspeed_video_free_buf(video, &video->srcs[0]);
1333 if (video->srcs[1].size)
1334 aspeed_video_free_buf(video, &video->srcs[1]);
1336 if (video->bcd.size)
1337 aspeed_video_free_buf(video, &video->bcd);
1339 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1343 static int aspeed_video_querycap(struct file *file, void *fh,
1344 struct v4l2_capability *cap)
1346 strscpy(cap->driver, DEVICE_NAME, sizeof(cap->driver));
1347 strscpy(cap->card, "Aspeed Video Engine", sizeof(cap->card));
1348 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1354 static int aspeed_video_enum_format(struct file *file, void *fh,
1355 struct v4l2_fmtdesc *f)
1357 struct aspeed_video *video = video_drvdata(file);
1362 f->pixelformat = video->pix_fmt.pixelformat;
1367 static int aspeed_video_get_format(struct file *file, void *fh,
1368 struct v4l2_format *f)
1370 struct aspeed_video *video = video_drvdata(file);
1372 f->fmt.pix = video->pix_fmt;
1377 static int aspeed_video_set_format(struct file *file, void *fh,
1378 struct v4l2_format *f)
1380 struct aspeed_video *video = video_drvdata(file);
1382 if (vb2_is_busy(&video->queue))
1385 switch (f->fmt.pix.pixelformat) {
1386 case V4L2_PIX_FMT_JPEG:
1387 video->format = VIDEO_FMT_STANDARD;
1389 case V4L2_PIX_FMT_AJPG:
1390 video->format = VIDEO_FMT_ASPEED;
1395 video->pix_fmt.pixelformat = f->fmt.pix.pixelformat;
1400 static int aspeed_video_enum_input(struct file *file, void *fh,
1401 struct v4l2_input *inp)
1403 struct aspeed_video *video = video_drvdata(file);
1408 strscpy(inp->name, "Host VGA capture", sizeof(inp->name));
1409 inp->type = V4L2_INPUT_TYPE_CAMERA;
1410 inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
1411 inp->status = video->v4l2_input_status;
1416 static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
1423 static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
1431 static int aspeed_video_get_parm(struct file *file, void *fh,
1432 struct v4l2_streamparm *a)
1434 struct aspeed_video *video = video_drvdata(file);
1436 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1437 a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1438 a->parm.capture.timeperframe.numerator = 1;
1439 if (!video->frame_rate)
1440 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1442 a->parm.capture.timeperframe.denominator = video->frame_rate;
1447 static int aspeed_video_set_parm(struct file *file, void *fh,
1448 struct v4l2_streamparm *a)
1450 unsigned int frame_rate = 0;
1451 struct aspeed_video *video = video_drvdata(file);
1453 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1454 a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1456 if (a->parm.capture.timeperframe.numerator)
1457 frame_rate = a->parm.capture.timeperframe.denominator /
1458 a->parm.capture.timeperframe.numerator;
1460 if (!frame_rate || frame_rate > MAX_FRAME_RATE) {
1462 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1463 a->parm.capture.timeperframe.numerator = 1;
1466 if (video->frame_rate != frame_rate) {
1467 video->frame_rate = frame_rate;
1468 aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC,
1469 FIELD_PREP(VE_CTRL_FRC, frame_rate));
1475 static int aspeed_video_enum_framesizes(struct file *file, void *fh,
1476 struct v4l2_frmsizeenum *fsize)
1478 struct aspeed_video *video = video_drvdata(file);
1483 if (fsize->pixel_format != V4L2_PIX_FMT_JPEG)
1486 fsize->discrete.width = video->pix_fmt.width;
1487 fsize->discrete.height = video->pix_fmt.height;
1488 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1493 static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
1494 struct v4l2_frmivalenum *fival)
1496 struct aspeed_video *video = video_drvdata(file);
1501 if (fival->width != video->detected_timings.width ||
1502 fival->height != video->detected_timings.height)
1505 if (fival->pixel_format != V4L2_PIX_FMT_JPEG)
1508 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1510 fival->stepwise.min.denominator = MAX_FRAME_RATE;
1511 fival->stepwise.min.numerator = 1;
1512 fival->stepwise.max.denominator = 1;
1513 fival->stepwise.max.numerator = 1;
1514 fival->stepwise.step = fival->stepwise.max;
1519 static int aspeed_video_set_dv_timings(struct file *file, void *fh,
1520 struct v4l2_dv_timings *timings)
1522 struct aspeed_video *video = video_drvdata(file);
1524 if (timings->bt.width == video->active_timings.width &&
1525 timings->bt.height == video->active_timings.height)
1528 if (vb2_is_busy(&video->queue))
1531 video->active_timings = timings->bt;
1533 aspeed_video_set_resolution(video);
1535 video->pix_fmt.width = timings->bt.width;
1536 video->pix_fmt.height = timings->bt.height;
1537 video->pix_fmt.sizeimage = video->max_compressed_size;
1539 timings->type = V4L2_DV_BT_656_1120;
1541 v4l2_dbg(1, debug, &video->v4l2_dev, "set new timings(%dx%d)\n",
1542 timings->bt.width, timings->bt.height);
1547 static int aspeed_video_get_dv_timings(struct file *file, void *fh,
1548 struct v4l2_dv_timings *timings)
1550 struct aspeed_video *video = video_drvdata(file);
1552 timings->type = V4L2_DV_BT_656_1120;
1553 timings->bt = video->active_timings;
1558 static int aspeed_video_query_dv_timings(struct file *file, void *fh,
1559 struct v4l2_dv_timings *timings)
1562 struct aspeed_video *video = video_drvdata(file);
1565 * This blocks only if the driver is currently in the process of
1566 * detecting a new resolution; in the event of no signal or timeout
1567 * this function is woken up.
1569 if (file->f_flags & O_NONBLOCK) {
1570 if (test_bit(VIDEO_RES_CHANGE, &video->flags))
1573 rc = wait_event_interruptible(video->wait,
1574 !test_bit(VIDEO_RES_CHANGE,
1580 timings->type = V4L2_DV_BT_656_1120;
1581 timings->bt = video->detected_timings;
1583 return video->v4l2_input_status ? -ENOLINK : 0;
1586 static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
1587 struct v4l2_enum_dv_timings *timings)
1589 return v4l2_enum_dv_timings_cap(timings, &aspeed_video_timings_cap,
1593 static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
1594 struct v4l2_dv_timings_cap *cap)
1596 *cap = aspeed_video_timings_cap;
1601 static int aspeed_video_sub_event(struct v4l2_fh *fh,
1602 const struct v4l2_event_subscription *sub)
1604 switch (sub->type) {
1605 case V4L2_EVENT_SOURCE_CHANGE:
1606 return v4l2_src_change_event_subscribe(fh, sub);
1609 return v4l2_ctrl_subscribe_event(fh, sub);
1612 static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = {
1613 .vidioc_querycap = aspeed_video_querycap,
1615 .vidioc_enum_fmt_vid_cap = aspeed_video_enum_format,
1616 .vidioc_g_fmt_vid_cap = aspeed_video_get_format,
1617 .vidioc_s_fmt_vid_cap = aspeed_video_set_format,
1618 .vidioc_try_fmt_vid_cap = aspeed_video_get_format,
1620 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1621 .vidioc_querybuf = vb2_ioctl_querybuf,
1622 .vidioc_qbuf = vb2_ioctl_qbuf,
1623 .vidioc_expbuf = vb2_ioctl_expbuf,
1624 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1625 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1626 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1627 .vidioc_streamon = vb2_ioctl_streamon,
1628 .vidioc_streamoff = vb2_ioctl_streamoff,
1630 .vidioc_enum_input = aspeed_video_enum_input,
1631 .vidioc_g_input = aspeed_video_get_input,
1632 .vidioc_s_input = aspeed_video_set_input,
1634 .vidioc_g_parm = aspeed_video_get_parm,
1635 .vidioc_s_parm = aspeed_video_set_parm,
1636 .vidioc_enum_framesizes = aspeed_video_enum_framesizes,
1637 .vidioc_enum_frameintervals = aspeed_video_enum_frameintervals,
1639 .vidioc_s_dv_timings = aspeed_video_set_dv_timings,
1640 .vidioc_g_dv_timings = aspeed_video_get_dv_timings,
1641 .vidioc_query_dv_timings = aspeed_video_query_dv_timings,
1642 .vidioc_enum_dv_timings = aspeed_video_enum_dv_timings,
1643 .vidioc_dv_timings_cap = aspeed_video_dv_timings_cap,
1645 .vidioc_subscribe_event = aspeed_video_sub_event,
1646 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1649 static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
1651 struct aspeed_video *video = container_of(ctrl->handler,
1652 struct aspeed_video,
1656 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1657 video->jpeg_quality = ctrl->val;
1658 if (test_bit(VIDEO_STREAMING, &video->flags))
1659 aspeed_video_update_regs(video);
1661 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1662 video->yuv420 = (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420);
1663 if (test_bit(VIDEO_STREAMING, &video->flags))
1664 aspeed_video_update_regs(video);
1666 case V4L2_CID_ASPEED_HQ_MODE:
1667 video->hq_mode = ctrl->val;
1668 if (test_bit(VIDEO_STREAMING, &video->flags))
1669 aspeed_video_update_regs(video);
1671 case V4L2_CID_ASPEED_HQ_JPEG_QUALITY:
1672 video->jpeg_hq_quality = ctrl->val;
1673 if (test_bit(VIDEO_STREAMING, &video->flags))
1674 aspeed_video_update_regs(video);
1683 static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
1684 .s_ctrl = aspeed_video_set_ctrl,
1687 static const struct v4l2_ctrl_config aspeed_ctrl_HQ_mode = {
1688 .ops = &aspeed_video_ctrl_ops,
1689 .id = V4L2_CID_ASPEED_HQ_MODE,
1690 .name = "Aspeed HQ Mode",
1691 .type = V4L2_CTRL_TYPE_BOOLEAN,
1698 static const struct v4l2_ctrl_config aspeed_ctrl_HQ_jpeg_quality = {
1699 .ops = &aspeed_video_ctrl_ops,
1700 .id = V4L2_CID_ASPEED_HQ_JPEG_QUALITY,
1701 .name = "Aspeed HQ Quality",
1702 .type = V4L2_CTRL_TYPE_INTEGER,
1704 .max = ASPEED_VIDEO_JPEG_NUM_QUALITIES,
1709 static void aspeed_video_resolution_work(struct work_struct *work)
1711 struct delayed_work *dwork = to_delayed_work(work);
1712 struct aspeed_video *video = container_of(dwork, struct aspeed_video,
1715 aspeed_video_on(video);
1717 /* Exit early in case no clients remain */
1718 if (test_bit(VIDEO_STOPPED, &video->flags))
1721 aspeed_video_init_regs(video);
1723 aspeed_video_update_regs(video);
1725 aspeed_video_get_resolution(video);
1727 if (video->detected_timings.width != video->active_timings.width ||
1728 video->detected_timings.height != video->active_timings.height) {
1729 static const struct v4l2_event ev = {
1730 .type = V4L2_EVENT_SOURCE_CHANGE,
1731 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1734 v4l2_dbg(1, debug, &video->v4l2_dev, "fire source change event\n");
1735 v4l2_event_queue(&video->vdev, &ev);
1736 } else if (test_bit(VIDEO_STREAMING, &video->flags)) {
1737 /* No resolution change so just restart streaming */
1738 aspeed_video_start_frame(video);
1742 clear_bit(VIDEO_RES_CHANGE, &video->flags);
1743 wake_up_interruptible_all(&video->wait);
1746 static int aspeed_video_open(struct file *file)
1749 struct aspeed_video *video = video_drvdata(file);
1751 mutex_lock(&video->video_lock);
1753 rc = v4l2_fh_open(file);
1755 mutex_unlock(&video->video_lock);
1759 if (v4l2_fh_is_singular_file(file))
1760 aspeed_video_start(video);
1762 mutex_unlock(&video->video_lock);
1767 static int aspeed_video_release(struct file *file)
1770 struct aspeed_video *video = video_drvdata(file);
1772 mutex_lock(&video->video_lock);
1774 if (v4l2_fh_is_singular_file(file))
1775 aspeed_video_stop(video);
1777 rc = _vb2_fop_release(file, NULL);
1779 mutex_unlock(&video->video_lock);
1784 static const struct v4l2_file_operations aspeed_video_v4l2_fops = {
1785 .owner = THIS_MODULE,
1786 .read = vb2_fop_read,
1787 .poll = vb2_fop_poll,
1788 .unlocked_ioctl = video_ioctl2,
1789 .mmap = vb2_fop_mmap,
1790 .open = aspeed_video_open,
1791 .release = aspeed_video_release,
1794 static int aspeed_video_queue_setup(struct vb2_queue *q,
1795 unsigned int *num_buffers,
1796 unsigned int *num_planes,
1797 unsigned int sizes[],
1798 struct device *alloc_devs[])
1800 struct aspeed_video *video = vb2_get_drv_priv(q);
1803 if (sizes[0] < video->max_compressed_size)
1810 sizes[0] = video->max_compressed_size;
1815 static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
1817 struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1819 if (vb2_plane_size(vb, 0) < video->max_compressed_size)
1825 static int aspeed_video_start_streaming(struct vb2_queue *q,
1829 struct aspeed_video *video = vb2_get_drv_priv(q);
1831 video->sequence = 0;
1832 video->perf.duration_max = 0;
1833 video->perf.duration_min = 0xffffffff;
1835 aspeed_video_update_regs(video);
1837 rc = aspeed_video_start_frame(video);
1839 aspeed_video_bufs_done(video, VB2_BUF_STATE_QUEUED);
1843 set_bit(VIDEO_STREAMING, &video->flags);
1847 static void aspeed_video_stop_streaming(struct vb2_queue *q)
1850 struct aspeed_video *video = vb2_get_drv_priv(q);
1852 clear_bit(VIDEO_STREAMING, &video->flags);
1854 rc = wait_event_timeout(video->wait,
1855 !test_bit(VIDEO_FRAME_INPRG, &video->flags),
1858 v4l2_dbg(1, debug, &video->v4l2_dev, "Timed out when stopping streaming\n");
1861 * Need to force stop any DMA and try and get HW into a good
1862 * state for future calls to start streaming again.
1864 aspeed_video_off(video);
1865 aspeed_video_on(video);
1867 aspeed_video_init_regs(video);
1869 aspeed_video_get_resolution(video);
1872 aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
1875 static void aspeed_video_buf_queue(struct vb2_buffer *vb)
1878 struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1879 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1880 struct aspeed_video_buffer *avb = to_aspeed_video_buffer(vbuf);
1881 unsigned long flags;
1883 spin_lock_irqsave(&video->lock, flags);
1884 empty = list_empty(&video->buffers);
1885 list_add_tail(&avb->link, &video->buffers);
1886 spin_unlock_irqrestore(&video->lock, flags);
1888 if (test_bit(VIDEO_STREAMING, &video->flags) &&
1889 !test_bit(VIDEO_FRAME_INPRG, &video->flags) && empty)
1890 aspeed_video_start_frame(video);
1893 static const struct vb2_ops aspeed_video_vb2_ops = {
1894 .queue_setup = aspeed_video_queue_setup,
1895 .wait_prepare = vb2_ops_wait_prepare,
1896 .wait_finish = vb2_ops_wait_finish,
1897 .buf_prepare = aspeed_video_buf_prepare,
1898 .start_streaming = aspeed_video_start_streaming,
1899 .stop_streaming = aspeed_video_stop_streaming,
1900 .buf_queue = aspeed_video_buf_queue,
1903 #ifdef CONFIG_DEBUG_FS
1904 static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
1906 struct aspeed_video *v = s->private;
1911 seq_puts(s, "Capture:\n");
1912 val08 = aspeed_video_read(v, VE_CTRL);
1913 if (FIELD_GET(VE_CTRL_DIRECT_FETCH, val08)) {
1914 seq_printf(s, " %-20s:\tDirect fetch\n", "Mode");
1915 seq_printf(s, " %-20s:\t%s\n", "VGA bpp mode",
1916 FIELD_GET(VE_CTRL_INT_DE, val08) ? "16" : "32");
1918 seq_printf(s, " %-20s:\tSync\n", "Mode");
1919 seq_printf(s, " %-20s:\t%s\n", "Video source",
1920 FIELD_GET(VE_CTRL_SOURCE, val08) ?
1921 "external" : "internal");
1922 seq_printf(s, " %-20s:\t%s\n", "DE source",
1923 FIELD_GET(VE_CTRL_INT_DE, val08) ?
1924 "internal" : "external");
1925 seq_printf(s, " %-20s:\t%s\n", "Cursor overlay",
1926 FIELD_GET(VE_CTRL_AUTO_OR_CURSOR, val08) ?
1927 "Without" : "With");
1930 seq_printf(s, " %-20s:\t%s\n", "Signal",
1931 v->v4l2_input_status ? "Unlock" : "Lock");
1932 seq_printf(s, " %-20s:\t%d\n", "Width", v->pix_fmt.width);
1933 seq_printf(s, " %-20s:\t%d\n", "Height", v->pix_fmt.height);
1934 seq_printf(s, " %-20s:\t%d\n", "FRC", v->frame_rate);
1938 seq_puts(s, "Compression:\n");
1939 seq_printf(s, " %-20s:\t%s\n", "Format", format_str[v->format]);
1940 seq_printf(s, " %-20s:\t%s\n", "Subsampling",
1941 v->yuv420 ? "420" : "444");
1942 seq_printf(s, " %-20s:\t%d\n", "Quality", v->jpeg_quality);
1943 if (v->format == VIDEO_FMT_ASPEED) {
1944 seq_printf(s, " %-20s:\t%s\n", "HQ Mode",
1945 v->hq_mode ? "on" : "off");
1946 seq_printf(s, " %-20s:\t%d\n", "HQ Quality",
1947 v->hq_mode ? v->jpeg_hq_quality : 0);
1952 seq_puts(s, "Performance:\n");
1953 seq_printf(s, " %-20s:\t%d\n", "Frame#", v->sequence);
1954 seq_printf(s, " %-20s:\n", "Frame Duration(ms)");
1955 seq_printf(s, " %-18s:\t%d\n", "Now", v->perf.duration);
1956 seq_printf(s, " %-18s:\t%d\n", "Min", v->perf.duration_min);
1957 seq_printf(s, " %-18s:\t%d\n", "Max", v->perf.duration_max);
1958 seq_printf(s, " %-20s:\t%d\n", "FPS",
1959 (v->perf.totaltime && v->sequence) ?
1960 1000 / (v->perf.totaltime / v->sequence) : 0);
1964 DEFINE_SHOW_ATTRIBUTE(aspeed_video_debugfs);
1966 static struct dentry *debugfs_entry;
1968 static void aspeed_video_debugfs_remove(struct aspeed_video *video)
1970 debugfs_remove_recursive(debugfs_entry);
1971 debugfs_entry = NULL;
1974 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1976 debugfs_entry = debugfs_create_file(DEVICE_NAME, 0444, NULL,
1978 &aspeed_video_debugfs_fops);
1980 aspeed_video_debugfs_remove(video);
1982 return !debugfs_entry ? -EIO : 0;
1985 static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
1986 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1990 #endif /* CONFIG_DEBUG_FS */
1992 static int aspeed_video_setup_video(struct aspeed_video *video)
1994 const u64 mask = ~(BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_444) |
1995 BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_420));
1996 struct v4l2_device *v4l2_dev = &video->v4l2_dev;
1997 struct vb2_queue *vbq = &video->queue;
1998 struct video_device *vdev = &video->vdev;
1999 struct v4l2_ctrl_handler *hdl = &video->ctrl_handler;
2002 video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG;
2003 video->pix_fmt.field = V4L2_FIELD_NONE;
2004 video->pix_fmt.colorspace = V4L2_COLORSPACE_SRGB;
2005 video->pix_fmt.quantization = V4L2_QUANTIZATION_FULL_RANGE;
2006 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
2008 rc = v4l2_device_register(video->dev, v4l2_dev);
2010 dev_err(video->dev, "Failed to register v4l2 device\n");
2014 v4l2_ctrl_handler_init(hdl, 4);
2015 v4l2_ctrl_new_std(hdl, &aspeed_video_ctrl_ops,
2016 V4L2_CID_JPEG_COMPRESSION_QUALITY, 0,
2017 ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1, 1, 0);
2018 v4l2_ctrl_new_std_menu(hdl, &aspeed_video_ctrl_ops,
2019 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
2020 V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask,
2021 V4L2_JPEG_CHROMA_SUBSAMPLING_444);
2022 v4l2_ctrl_new_custom(hdl, &aspeed_ctrl_HQ_mode, NULL);
2023 v4l2_ctrl_new_custom(hdl, &aspeed_ctrl_HQ_jpeg_quality, NULL);
2027 v4l2_ctrl_handler_free(&video->ctrl_handler);
2028 v4l2_device_unregister(v4l2_dev);
2030 dev_err(video->dev, "Failed to init controls: %d\n", rc);
2034 v4l2_dev->ctrl_handler = hdl;
2036 vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2037 vbq->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
2038 vbq->dev = v4l2_dev->dev;
2039 vbq->lock = &video->video_lock;
2040 vbq->ops = &aspeed_video_vb2_ops;
2041 vbq->mem_ops = &vb2_dma_contig_memops;
2042 vbq->drv_priv = video;
2043 vbq->buf_struct_size = sizeof(struct aspeed_video_buffer);
2044 vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
2045 vbq->min_buffers_needed = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
2047 rc = vb2_queue_init(vbq);
2049 v4l2_ctrl_handler_free(&video->ctrl_handler);
2050 v4l2_device_unregister(v4l2_dev);
2052 dev_err(video->dev, "Failed to init vb2 queue\n");
2057 vdev->fops = &aspeed_video_v4l2_fops;
2058 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
2060 vdev->v4l2_dev = v4l2_dev;
2061 strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));
2062 vdev->vfl_type = VFL_TYPE_VIDEO;
2063 vdev->vfl_dir = VFL_DIR_RX;
2064 vdev->release = video_device_release_empty;
2065 vdev->ioctl_ops = &aspeed_video_ioctl_ops;
2066 vdev->lock = &video->video_lock;
2068 video_set_drvdata(vdev, video);
2069 rc = video_register_device(vdev, VFL_TYPE_VIDEO, 0);
2071 v4l2_ctrl_handler_free(&video->ctrl_handler);
2072 v4l2_device_unregister(v4l2_dev);
2074 dev_err(video->dev, "Failed to register video device\n");
2081 static int aspeed_video_init(struct aspeed_video *video)
2085 struct device *dev = video->dev;
2087 irq = irq_of_parse_and_map(dev->of_node, 0);
2089 dev_err(dev, "Unable to find IRQ\n");
2093 rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
2094 IRQF_ONESHOT, DEVICE_NAME, video);
2096 dev_err(dev, "Unable to request IRQ %d\n", irq);
2099 dev_info(video->dev, "irq %d\n", irq);
2101 video->eclk = devm_clk_get(dev, "eclk");
2102 if (IS_ERR(video->eclk)) {
2103 dev_err(dev, "Unable to get ECLK\n");
2104 return PTR_ERR(video->eclk);
2107 rc = clk_prepare(video->eclk);
2111 video->vclk = devm_clk_get(dev, "vclk");
2112 if (IS_ERR(video->vclk)) {
2113 dev_err(dev, "Unable to get VCLK\n");
2114 rc = PTR_ERR(video->vclk);
2115 goto err_unprepare_eclk;
2118 rc = clk_prepare(video->vclk);
2120 goto err_unprepare_eclk;
2122 of_reserved_mem_device_init(dev);
2124 rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
2126 dev_err(dev, "Failed to set DMA mask\n");
2127 goto err_release_reserved_mem;
2130 if (!aspeed_video_alloc_buf(video, &video->jpeg,
2131 VE_JPEG_HEADER_SIZE)) {
2132 dev_err(dev, "Failed to allocate DMA for JPEG header\n");
2134 goto err_release_reserved_mem;
2136 dev_info(video->dev, "alloc mem size(%d) at %pad for jpeg header\n",
2137 VE_JPEG_HEADER_SIZE, &video->jpeg.dma);
2139 aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
2143 err_release_reserved_mem:
2144 of_reserved_mem_device_release(dev);
2145 clk_unprepare(video->vclk);
2147 clk_unprepare(video->eclk);
2152 static const struct of_device_id aspeed_video_of_match[] = {
2153 { .compatible = "aspeed,ast2400-video-engine", .data = &ast2400_config },
2154 { .compatible = "aspeed,ast2500-video-engine", .data = &ast2500_config },
2155 { .compatible = "aspeed,ast2600-video-engine", .data = &ast2600_config },
2158 MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
2160 static int aspeed_video_probe(struct platform_device *pdev)
2162 const struct aspeed_video_config *config;
2163 struct aspeed_video *video;
2166 video = devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
2170 video->base = devm_platform_ioremap_resource(pdev, 0);
2171 if (IS_ERR(video->base))
2172 return PTR_ERR(video->base);
2174 config = of_device_get_match_data(&pdev->dev);
2178 video->jpeg_mode = config->jpeg_mode;
2179 video->comp_size_read = config->comp_size_read;
2181 video->frame_rate = 30;
2182 video->jpeg_hq_quality = 1;
2183 video->dev = &pdev->dev;
2184 spin_lock_init(&video->lock);
2185 mutex_init(&video->video_lock);
2186 init_waitqueue_head(&video->wait);
2187 INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
2188 INIT_LIST_HEAD(&video->buffers);
2190 rc = aspeed_video_init(video);
2194 rc = aspeed_video_setup_video(video);
2196 aspeed_video_free_buf(video, &video->jpeg);
2197 clk_unprepare(video->vclk);
2198 clk_unprepare(video->eclk);
2202 rc = aspeed_video_debugfs_create(video);
2204 dev_err(video->dev, "debugfs create failed\n");
2209 static void aspeed_video_remove(struct platform_device *pdev)
2211 struct device *dev = &pdev->dev;
2212 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
2213 struct aspeed_video *video = to_aspeed_video(v4l2_dev);
2215 aspeed_video_off(video);
2217 aspeed_video_debugfs_remove(video);
2219 clk_unprepare(video->vclk);
2220 clk_unprepare(video->eclk);
2222 vb2_video_unregister_device(&video->vdev);
2224 v4l2_ctrl_handler_free(&video->ctrl_handler);
2226 v4l2_device_unregister(v4l2_dev);
2228 aspeed_video_free_buf(video, &video->jpeg);
2230 of_reserved_mem_device_release(dev);
2233 static struct platform_driver aspeed_video_driver = {
2235 .name = DEVICE_NAME,
2236 .of_match_table = aspeed_video_of_match,
2238 .probe = aspeed_video_probe,
2239 .remove_new = aspeed_video_remove,
2242 module_platform_driver(aspeed_video_driver);
2244 module_param(debug, int, 0644);
2245 MODULE_PARM_DESC(debug, "Debug level (0=off,1=info,2=debug,3=reg ops)");
2247 MODULE_DESCRIPTION("ASPEED Video Engine Driver");
2248 MODULE_AUTHOR("Eddie James");
2249 MODULE_LICENSE("GPL v2");