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_irq.h>
17 #include <linux/of_reserved_mem.h>
18 #include <linux/platform_device.h>
19 #include <linux/sched.h>
20 #include <linux/spinlock.h>
21 #include <linux/string.h>
22 #include <linux/v4l2-controls.h>
23 #include <linux/videodev2.h>
24 #include <linux/wait.h>
25 #include <linux/workqueue.h>
26 #include <linux/debugfs.h>
27 #include <linux/ktime.h>
28 #include <media/v4l2-ctrls.h>
29 #include <media/v4l2-dev.h>
30 #include <media/v4l2-device.h>
31 #include <media/v4l2-dv-timings.h>
32 #include <media/v4l2-event.h>
33 #include <media/v4l2-ioctl.h>
34 #include <media/videobuf2-dma-contig.h>
36 #define DEVICE_NAME "aspeed-video"
38 #define ASPEED_VIDEO_JPEG_NUM_QUALITIES 12
39 #define ASPEED_VIDEO_JPEG_HEADER_SIZE 10
40 #define ASPEED_VIDEO_JPEG_QUANT_SIZE 116
41 #define ASPEED_VIDEO_JPEG_DCT_SIZE 34
43 #define MAX_FRAME_RATE 60
44 #define MAX_HEIGHT 1200
45 #define MAX_WIDTH 1920
46 #define MIN_HEIGHT 480
49 #define NUM_POLARITY_CHECKS 10
50 #define INVALID_RESOLUTION_RETRIES 2
51 #define INVALID_RESOLUTION_DELAY msecs_to_jiffies(250)
52 #define RESOLUTION_CHANGE_DELAY msecs_to_jiffies(500)
53 #define MODE_DETECT_TIMEOUT msecs_to_jiffies(500)
54 #define STOP_TIMEOUT msecs_to_jiffies(1000)
55 #define DIRECT_FETCH_THRESHOLD 0x0c0000 /* 1024 * 768 */
57 #define VE_MAX_SRC_BUFFER_SIZE 0x8ca000 /* 1920 * 1200, 32bpp */
58 #define VE_JPEG_HEADER_SIZE 0x006000 /* 512 * 12 * 4 */
60 #define VE_PROTECTION_KEY 0x000
61 #define VE_PROTECTION_KEY_UNLOCK 0x1a038aa8
63 #define VE_SEQ_CTRL 0x004
64 #define VE_SEQ_CTRL_TRIG_MODE_DET BIT(0)
65 #define VE_SEQ_CTRL_TRIG_CAPTURE BIT(1)
66 #define VE_SEQ_CTRL_FORCE_IDLE BIT(2)
67 #define VE_SEQ_CTRL_MULT_FRAME BIT(3)
68 #define VE_SEQ_CTRL_TRIG_COMP BIT(4)
69 #define VE_SEQ_CTRL_AUTO_COMP BIT(5)
70 #define VE_SEQ_CTRL_EN_WATCHDOG BIT(7)
71 #define VE_SEQ_CTRL_YUV420 BIT(10)
72 #define VE_SEQ_CTRL_COMP_FMT GENMASK(11, 10)
73 #define VE_SEQ_CTRL_HALT BIT(12)
74 #define VE_SEQ_CTRL_EN_WATCHDOG_COMP BIT(14)
75 #define VE_SEQ_CTRL_TRIG_JPG BIT(15)
76 #define VE_SEQ_CTRL_CAP_BUSY BIT(16)
77 #define VE_SEQ_CTRL_COMP_BUSY BIT(18)
79 #define AST2500_VE_SEQ_CTRL_JPEG_MODE BIT(13)
80 #define AST2400_VE_SEQ_CTRL_JPEG_MODE BIT(8)
83 #define VE_CTRL_HSYNC_POL BIT(0)
84 #define VE_CTRL_VSYNC_POL BIT(1)
85 #define VE_CTRL_SOURCE BIT(2)
86 #define VE_CTRL_INT_DE BIT(4)
87 #define VE_CTRL_DIRECT_FETCH BIT(5)
88 #define VE_CTRL_YUV BIT(6)
89 #define VE_CTRL_RGB BIT(7)
90 #define VE_CTRL_CAPTURE_FMT GENMASK(7, 6)
91 #define VE_CTRL_AUTO_OR_CURSOR BIT(8)
92 #define VE_CTRL_CLK_INVERSE BIT(11)
93 #define VE_CTRL_CLK_DELAY GENMASK(11, 9)
94 #define VE_CTRL_INTERLACE BIT(14)
95 #define VE_CTRL_HSYNC_POL_CTRL BIT(15)
96 #define VE_CTRL_FRC GENMASK(23, 16)
98 #define VE_TGS_0 0x00c
99 #define VE_TGS_1 0x010
100 #define VE_TGS_FIRST GENMASK(28, 16)
101 #define VE_TGS_LAST GENMASK(12, 0)
103 #define VE_SCALING_FACTOR 0x014
104 #define VE_SCALING_FILTER0 0x018
105 #define VE_SCALING_FILTER1 0x01c
106 #define VE_SCALING_FILTER2 0x020
107 #define VE_SCALING_FILTER3 0x024
109 #define VE_CAP_WINDOW 0x030
110 #define VE_COMP_WINDOW 0x034
111 #define VE_COMP_PROC_OFFSET 0x038
112 #define VE_COMP_OFFSET 0x03c
113 #define VE_JPEG_ADDR 0x040
114 #define VE_SRC0_ADDR 0x044
115 #define VE_SRC_SCANLINE_OFFSET 0x048
116 #define VE_SRC1_ADDR 0x04c
117 #define VE_COMP_ADDR 0x054
119 #define VE_STREAM_BUF_SIZE 0x058
120 #define VE_STREAM_BUF_SIZE_N_PACKETS GENMASK(5, 3)
121 #define VE_STREAM_BUF_SIZE_P_SIZE GENMASK(2, 0)
123 #define VE_COMP_CTRL 0x060
124 #define VE_COMP_CTRL_VQ_DCT_ONLY BIT(0)
125 #define VE_COMP_CTRL_VQ_4COLOR BIT(1)
126 #define VE_COMP_CTRL_QUANTIZE BIT(2)
127 #define VE_COMP_CTRL_EN_BQ BIT(4)
128 #define VE_COMP_CTRL_EN_CRYPTO BIT(5)
129 #define VE_COMP_CTRL_DCT_CHR GENMASK(10, 6)
130 #define VE_COMP_CTRL_DCT_LUM GENMASK(15, 11)
131 #define VE_COMP_CTRL_EN_HQ BIT(16)
132 #define VE_COMP_CTRL_RSVD BIT(19)
133 #define VE_COMP_CTRL_ENCODE GENMASK(21, 20)
134 #define VE_COMP_CTRL_HQ_DCT_CHR GENMASK(26, 22)
135 #define VE_COMP_CTRL_HQ_DCT_LUM GENMASK(31, 27)
137 #define AST2400_VE_COMP_SIZE_READ_BACK 0x078
138 #define AST2600_VE_COMP_SIZE_READ_BACK 0x084
140 #define VE_SRC_LR_EDGE_DET 0x090
141 #define VE_SRC_LR_EDGE_DET_LEFT GENMASK(11, 0)
142 #define VE_SRC_LR_EDGE_DET_NO_V BIT(12)
143 #define VE_SRC_LR_EDGE_DET_NO_H BIT(13)
144 #define VE_SRC_LR_EDGE_DET_NO_DISP BIT(14)
145 #define VE_SRC_LR_EDGE_DET_NO_CLK BIT(15)
146 #define VE_SRC_LR_EDGE_DET_RT_SHF 16
147 #define VE_SRC_LR_EDGE_DET_RT GENMASK(27, VE_SRC_LR_EDGE_DET_RT_SHF)
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_SHF 16
153 #define VE_SRC_TB_EDGE_DET_BOT GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF)
155 #define VE_MODE_DETECT_STATUS 0x098
156 #define VE_MODE_DETECT_H_PIXELS GENMASK(11, 0)
157 #define VE_MODE_DETECT_V_LINES_SHF 16
158 #define VE_MODE_DETECT_V_LINES GENMASK(27, VE_MODE_DETECT_V_LINES_SHF)
159 #define VE_MODE_DETECT_STATUS_VSYNC BIT(28)
160 #define VE_MODE_DETECT_STATUS_HSYNC BIT(29)
162 #define VE_SYNC_STATUS 0x09c
163 #define VE_SYNC_STATUS_HSYNC GENMASK(11, 0)
164 #define VE_SYNC_STATUS_VSYNC_SHF 16
165 #define VE_SYNC_STATUS_VSYNC GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
167 #define VE_INTERRUPT_CTRL 0x304
168 #define VE_INTERRUPT_STATUS 0x308
169 #define VE_INTERRUPT_MODE_DETECT_WD BIT(0)
170 #define VE_INTERRUPT_CAPTURE_COMPLETE BIT(1)
171 #define VE_INTERRUPT_COMP_READY BIT(2)
172 #define VE_INTERRUPT_COMP_COMPLETE BIT(3)
173 #define VE_INTERRUPT_MODE_DETECT BIT(4)
174 #define VE_INTERRUPT_FRAME_COMPLETE BIT(5)
175 #define VE_INTERRUPT_DECODE_ERR BIT(6)
176 #define VE_INTERRUPT_HALT_READY BIT(8)
177 #define VE_INTERRUPT_HANG_WD BIT(9)
178 #define VE_INTERRUPT_STREAM_DESC BIT(10)
179 #define VE_INTERRUPT_VSYNC_DESC BIT(11)
181 #define VE_MODE_DETECT 0x30c
182 #define VE_MEM_RESTRICT_START 0x310
183 #define VE_MEM_RESTRICT_END 0x314
186 VIDEO_MODE_DETECT_DONE,
195 struct aspeed_video_addr {
201 struct aspeed_video_buffer {
202 struct vb2_v4l2_buffer vb;
203 struct list_head link;
206 struct aspeed_video_perf {
214 #define to_aspeed_video_buffer(x) \
215 container_of((x), struct aspeed_video_buffer, vb)
217 struct aspeed_video {
223 struct v4l2_ctrl_handler ctrl_handler;
224 struct v4l2_device v4l2_dev;
225 struct v4l2_pix_format pix_fmt;
226 struct v4l2_bt_timings active_timings;
227 struct v4l2_bt_timings detected_timings;
228 u32 v4l2_input_status;
229 struct vb2_queue queue;
230 struct video_device vdev;
231 struct mutex video_lock; /* v4l2 and videobuf2 lock */
236 wait_queue_head_t wait;
237 spinlock_t lock; /* buffer list lock */
238 struct delayed_work res_work;
239 struct list_head buffers;
241 unsigned int sequence;
243 unsigned int max_compressed_size;
244 struct aspeed_video_addr srcs[2];
245 struct aspeed_video_addr jpeg;
248 unsigned int frame_rate;
249 unsigned int jpeg_quality;
251 unsigned int frame_bottom;
252 unsigned int frame_left;
253 unsigned int frame_right;
254 unsigned int frame_top;
256 struct aspeed_video_perf perf;
259 #define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
261 struct aspeed_video_config {
266 static const struct aspeed_video_config ast2400_config = {
267 .jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
268 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
271 static const struct aspeed_video_config ast2500_config = {
272 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
273 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
276 static const struct aspeed_video_config ast2600_config = {
277 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
278 .comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
281 static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
282 0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
283 0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
286 static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] = {
287 0x081100c0, 0x00000000, 0x00110103, 0x03011102, 0xc4ff0111, 0x00001f00,
288 0x01010501, 0x01010101, 0x00000000, 0x00000000, 0x04030201, 0x08070605,
289 0xff0b0a09, 0x10b500c4, 0x03010200, 0x03040203, 0x04040505, 0x7d010000,
290 0x00030201, 0x12051104, 0x06413121, 0x07615113, 0x32147122, 0x08a19181,
291 0xc1b14223, 0xf0d15215, 0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
292 0x35342a29, 0x39383736, 0x4544433a, 0x49484746, 0x5554534a, 0x59585756,
293 0x6564635a, 0x69686766, 0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
294 0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4, 0xb2aaa9a8, 0xb6b5b4b3,
295 0xbab9b8b7, 0xc5c4c3c2, 0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
296 0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5, 0xc4fffaf9, 0x00011f00,
297 0x01010103, 0x01010101, 0x00000101, 0x00000000, 0x04030201, 0x08070605,
298 0xff0b0a09, 0x11b500c4, 0x02010200, 0x04030404, 0x04040507, 0x77020100,
299 0x03020100, 0x21050411, 0x41120631, 0x71610751, 0x81322213, 0x91421408,
300 0x09c1b1a1, 0xf0523323, 0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
301 0x2a292827, 0x38373635, 0x44433a39, 0x48474645, 0x54534a49, 0x58575655,
302 0x64635a59, 0x68676665, 0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
303 0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2, 0xa9a8a7a6, 0xb4b3b2aa,
304 0xb8b7b6b5, 0xc3c2bab9, 0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
305 0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5, 0xdafffaf9, 0x01030c00,
306 0x03110200, 0x003f0011
309 static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
310 [ASPEED_VIDEO_JPEG_DCT_SIZE] = {
311 { 0x0d140043, 0x0c0f110f, 0x11101114, 0x17141516, 0x1e20321e,
312 0x3d1e1b1b, 0x32242e2b, 0x4b4c3f48, 0x44463f47, 0x61735a50,
313 0x566c5550, 0x88644644, 0x7a766c65, 0x4d808280, 0x8c978d60,
314 0x7e73967d, 0xdbff7b80, 0x1f014300, 0x272d2121, 0x3030582d,
315 0x697bb958, 0xb8b9b97b, 0xb9b8a6a6, 0xb9b9b9b9, 0xb9b9b9b9,
316 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9,
317 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xffb9b9b9 },
318 { 0x0c110043, 0x0a0d0f0d, 0x0f0e0f11, 0x14111213, 0x1a1c2b1a,
319 0x351a1818, 0x2b1f2826, 0x4142373f, 0x3c3d373e, 0x55644e46,
320 0x4b5f4a46, 0x77573d3c, 0x6b675f58, 0x43707170, 0x7a847b54,
321 0x6e64836d, 0xdbff6c70, 0x1b014300, 0x22271d1d, 0x2a2a4c27,
322 0x5b6ba04c, 0xa0a0a06b, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
323 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
324 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xffa0a0a0 },
325 { 0x090e0043, 0x090a0c0a, 0x0c0b0c0e, 0x110e0f10, 0x15172415,
326 0x2c151313, 0x241a211f, 0x36372e34, 0x31322e33, 0x4653413a,
327 0x3e4e3d3a, 0x62483231, 0x58564e49, 0x385d5e5d, 0x656d6645,
328 0x5b536c5a, 0xdbff595d, 0x16014300, 0x1c201818, 0x22223f20,
329 0x4b58853f, 0x85858558, 0x85858585, 0x85858585, 0x85858585,
330 0x85858585, 0x85858585, 0x85858585, 0x85858585, 0x85858585,
331 0x85858585, 0x85858585, 0x85858585, 0xff858585 },
332 { 0x070b0043, 0x07080a08, 0x0a090a0b, 0x0d0b0c0c, 0x11121c11,
333 0x23110f0f, 0x1c141a19, 0x2b2b2429, 0x27282428, 0x3842332e,
334 0x313e302e, 0x4e392827, 0x46443e3a, 0x2c4a4a4a, 0x50565137,
335 0x48425647, 0xdbff474a, 0x12014300, 0x161a1313, 0x1c1c331a,
336 0x3d486c33, 0x6c6c6c48, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
337 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
338 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0xff6c6c6c },
339 { 0x06090043, 0x05060706, 0x07070709, 0x0a09090a, 0x0d0e160d,
340 0x1b0d0c0c, 0x16101413, 0x21221c20, 0x1e1f1c20, 0x2b332824,
341 0x26302624, 0x3d2d1f1e, 0x3735302d, 0x22393a39, 0x3f443f2b,
342 0x38334338, 0xdbff3739, 0x0d014300, 0x11130e0e, 0x15152613,
343 0x2d355026, 0x50505035, 0x50505050, 0x50505050, 0x50505050,
344 0x50505050, 0x50505050, 0x50505050, 0x50505050, 0x50505050,
345 0x50505050, 0x50505050, 0x50505050, 0xff505050 },
346 { 0x04060043, 0x03040504, 0x05040506, 0x07060606, 0x09090f09,
347 0x12090808, 0x0f0a0d0d, 0x16161315, 0x14151315, 0x1d221b18,
348 0x19201918, 0x281e1514, 0x2423201e, 0x17262726, 0x2a2d2a1c,
349 0x25222d25, 0xdbff2526, 0x09014300, 0x0b0d0a0a, 0x0e0e1a0d,
350 0x1f25371a, 0x37373725, 0x37373737, 0x37373737, 0x37373737,
351 0x37373737, 0x37373737, 0x37373737, 0x37373737, 0x37373737,
352 0x37373737, 0x37373737, 0x37373737, 0xff373737 },
353 { 0x02030043, 0x01020202, 0x02020203, 0x03030303, 0x04040704,
354 0x09040404, 0x07050606, 0x0b0b090a, 0x0a0a090a, 0x0e110d0c,
355 0x0c100c0c, 0x140f0a0a, 0x1211100f, 0x0b131313, 0x1516150e,
356 0x12111612, 0xdbff1213, 0x04014300, 0x05060505, 0x07070d06,
357 0x0f121b0d, 0x1b1b1b12, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
358 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
359 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0xff1b1b1b },
360 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
361 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
362 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
363 0x0c0b0f0c, 0xdbff0c0c, 0x03014300, 0x03040303, 0x04040804,
364 0x0a0c1208, 0x1212120c, 0x12121212, 0x12121212, 0x12121212,
365 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
366 0x12121212, 0x12121212, 0x12121212, 0xff121212 },
367 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
368 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
369 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
370 0x0c0b0f0c, 0xdbff0c0c, 0x02014300, 0x03030202, 0x04040703,
371 0x080a0f07, 0x0f0f0f0a, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
372 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
373 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xff0f0f0f },
374 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x02020302,
375 0x04020202, 0x03020303, 0x05050405, 0x05050405, 0x07080606,
376 0x06080606, 0x0a070505, 0x09080807, 0x05090909, 0x0a0b0a07,
377 0x09080b09, 0xdbff0909, 0x02014300, 0x02030202, 0x03030503,
378 0x07080c05, 0x0c0c0c08, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
379 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
380 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xff0c0c0c },
381 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010201,
382 0x03010101, 0x02010202, 0x03030303, 0x03030303, 0x04050404,
383 0x04050404, 0x06050303, 0x06050505, 0x03060606, 0x07070704,
384 0x06050706, 0xdbff0606, 0x01014300, 0x01020101, 0x02020402,
385 0x05060904, 0x09090906, 0x09090909, 0x09090909, 0x09090909,
386 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
387 0x09090909, 0x09090909, 0x09090909, 0xff090909 },
388 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
389 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202,
390 0x02020202, 0x03020101, 0x03020202, 0x01030303, 0x03030302,
391 0x03020303, 0xdbff0403, 0x01014300, 0x01010101, 0x01010201,
392 0x03040602, 0x06060604, 0x06060606, 0x06060606, 0x06060606,
393 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
394 0x06060606, 0x06060606, 0x06060606, 0xff060606 }
397 static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
398 .type = V4L2_DV_BT_656_1120,
400 .min_width = MIN_WIDTH,
401 .max_width = MAX_WIDTH,
402 .min_height = MIN_HEIGHT,
403 .max_height = MAX_HEIGHT,
404 .min_pixelclock = 6574080, /* 640 x 480 x 24Hz */
405 .max_pixelclock = 138240000, /* 1920 x 1200 x 60Hz */
406 .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
407 V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
408 .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
409 V4L2_DV_BT_CAP_REDUCED_BLANKING |
410 V4L2_DV_BT_CAP_CUSTOM,
414 static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
419 for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
420 base = 256 * i; /* AST HW requires this header spacing */
421 memcpy(&table[base], aspeed_video_jpeg_header,
422 sizeof(aspeed_video_jpeg_header));
424 base += ASPEED_VIDEO_JPEG_HEADER_SIZE;
425 memcpy(&table[base], aspeed_video_jpeg_dct[i],
426 sizeof(aspeed_video_jpeg_dct[i]));
428 base += ASPEED_VIDEO_JPEG_DCT_SIZE;
429 memcpy(&table[base], aspeed_video_jpeg_quant,
430 sizeof(aspeed_video_jpeg_quant));
433 table[base + 2] = 0x00220103;
437 // just update jpeg dct table per 420/444
438 static void aspeed_video_update_jpeg_table(u32 *table, bool yuv420)
443 for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
444 base = 256 * i; /* AST HW requires this header spacing */
445 base += ASPEED_VIDEO_JPEG_HEADER_SIZE +
446 ASPEED_VIDEO_JPEG_DCT_SIZE;
448 table[base + 2] = (yuv420) ? 0x00220103 : 0x00110103;
452 static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
455 u32 t = readl(video->base + reg);
460 writel(t, video->base + reg);
461 dev_dbg(video->dev, "update %03x[%08x -> %08x]\n", reg, before,
462 readl(video->base + reg));
465 static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
467 u32 t = readl(video->base + reg);
469 dev_dbg(video->dev, "read %03x[%08x]\n", reg, t);
473 static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
475 writel(val, video->base + reg);
476 dev_dbg(video->dev, "write %03x[%08x]\n", reg,
477 readl(video->base + reg));
480 static void update_perf(struct aspeed_video_perf *p)
483 ktime_to_ms(ktime_sub(ktime_get(), p->last_sample));
484 p->totaltime += p->duration;
486 p->duration_max = max(p->duration, p->duration_max);
487 p->duration_min = min(p->duration, p->duration_min);
490 static int aspeed_video_start_frame(struct aspeed_video *video)
494 struct aspeed_video_buffer *buf;
495 u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
497 if (video->v4l2_input_status) {
498 dev_dbg(video->dev, "No signal; don't start frame\n");
502 if (!(seq_ctrl & VE_SEQ_CTRL_COMP_BUSY) ||
503 !(seq_ctrl & VE_SEQ_CTRL_CAP_BUSY)) {
504 dev_dbg(video->dev, "Engine busy; don't start frame\n");
508 spin_lock_irqsave(&video->lock, flags);
509 buf = list_first_entry_or_null(&video->buffers,
510 struct aspeed_video_buffer, link);
512 spin_unlock_irqrestore(&video->lock, flags);
513 dev_dbg(video->dev, "No buffers; don't start frame\n");
517 set_bit(VIDEO_FRAME_INPRG, &video->flags);
518 addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
519 spin_unlock_irqrestore(&video->lock, flags);
521 aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
522 aspeed_video_write(video, VE_COMP_OFFSET, 0);
523 aspeed_video_write(video, VE_COMP_ADDR, addr);
525 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
526 VE_INTERRUPT_COMP_COMPLETE);
528 video->perf.last_sample = ktime_get();
530 aspeed_video_update(video, VE_SEQ_CTRL, 0,
531 VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
536 static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
538 /* Enable mode detect interrupts */
539 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
540 VE_INTERRUPT_MODE_DETECT);
542 /* Disable mode detect in order to re-trigger */
543 aspeed_video_update(video, VE_SEQ_CTRL,
544 VE_SEQ_CTRL_TRIG_MODE_DET, 0);
546 /* Trigger mode detect */
547 aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET);
550 static void aspeed_video_off(struct aspeed_video *video)
552 if (!test_bit(VIDEO_CLOCKS_ON, &video->flags))
555 /* Disable interrupts */
556 aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
557 aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
559 /* Turn off the relevant clocks */
560 clk_disable(video->eclk);
561 clk_disable(video->vclk);
563 clear_bit(VIDEO_CLOCKS_ON, &video->flags);
566 static void aspeed_video_on(struct aspeed_video *video)
568 if (test_bit(VIDEO_CLOCKS_ON, &video->flags))
571 /* Turn on the relevant clocks */
572 clk_enable(video->vclk);
573 clk_enable(video->eclk);
575 set_bit(VIDEO_CLOCKS_ON, &video->flags);
578 static void aspeed_video_bufs_done(struct aspeed_video *video,
579 enum vb2_buffer_state state)
582 struct aspeed_video_buffer *buf;
584 spin_lock_irqsave(&video->lock, flags);
585 list_for_each_entry(buf, &video->buffers, link)
586 vb2_buffer_done(&buf->vb.vb2_buf, state);
587 INIT_LIST_HEAD(&video->buffers);
588 spin_unlock_irqrestore(&video->lock, flags);
591 static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
593 dev_dbg(video->dev, "Resolution changed; resetting\n");
595 set_bit(VIDEO_RES_CHANGE, &video->flags);
596 clear_bit(VIDEO_FRAME_INPRG, &video->flags);
598 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
600 aspeed_video_off(video);
601 aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
603 schedule_delayed_work(&video->res_work, delay);
606 static irqreturn_t aspeed_video_irq(int irq, void *arg)
608 struct aspeed_video *video = arg;
609 u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
612 * Hardware sometimes asserts interrupts that we haven't actually
613 * enabled; ignore them if so.
615 sts &= aspeed_video_read(video, VE_INTERRUPT_CTRL);
618 * Resolution changed or signal was lost; reset the engine and
621 if (sts & VE_INTERRUPT_MODE_DETECT_WD) {
622 aspeed_video_irq_res_change(video, 0);
626 if (sts & VE_INTERRUPT_MODE_DETECT) {
627 if (test_bit(VIDEO_RES_DETECT, &video->flags)) {
628 aspeed_video_update(video, VE_INTERRUPT_CTRL,
629 VE_INTERRUPT_MODE_DETECT, 0);
630 aspeed_video_write(video, VE_INTERRUPT_STATUS,
631 VE_INTERRUPT_MODE_DETECT);
632 sts &= ~VE_INTERRUPT_MODE_DETECT;
633 set_bit(VIDEO_MODE_DETECT_DONE, &video->flags);
634 wake_up_interruptible_all(&video->wait);
637 * Signal acquired while NOT doing resolution
638 * detection; reset the engine and re-initialize
640 aspeed_video_irq_res_change(video,
641 RESOLUTION_CHANGE_DELAY);
646 if (sts & VE_INTERRUPT_COMP_COMPLETE) {
647 struct aspeed_video_buffer *buf;
648 u32 frame_size = aspeed_video_read(video,
649 video->comp_size_read);
651 update_perf(&video->perf);
653 spin_lock(&video->lock);
654 clear_bit(VIDEO_FRAME_INPRG, &video->flags);
655 buf = list_first_entry_or_null(&video->buffers,
656 struct aspeed_video_buffer,
659 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, frame_size);
661 if (!list_is_last(&buf->link, &video->buffers)) {
662 buf->vb.vb2_buf.timestamp = ktime_get_ns();
663 buf->vb.sequence = video->sequence++;
664 buf->vb.field = V4L2_FIELD_NONE;
665 vb2_buffer_done(&buf->vb.vb2_buf,
667 list_del(&buf->link);
670 spin_unlock(&video->lock);
672 aspeed_video_update(video, VE_SEQ_CTRL,
673 VE_SEQ_CTRL_TRIG_CAPTURE |
674 VE_SEQ_CTRL_FORCE_IDLE |
675 VE_SEQ_CTRL_TRIG_COMP, 0);
676 aspeed_video_update(video, VE_INTERRUPT_CTRL,
677 VE_INTERRUPT_COMP_COMPLETE, 0);
678 aspeed_video_write(video, VE_INTERRUPT_STATUS,
679 VE_INTERRUPT_COMP_COMPLETE);
680 sts &= ~VE_INTERRUPT_COMP_COMPLETE;
681 if (test_bit(VIDEO_STREAMING, &video->flags) && buf)
682 aspeed_video_start_frame(video);
685 return sts ? IRQ_NONE : IRQ_HANDLED;
688 static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
691 int hsync_counter = 0;
692 int vsync_counter = 0;
695 for (i = 0; i < NUM_POLARITY_CHECKS; ++i) {
696 sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
697 if (sts & VE_MODE_DETECT_STATUS_VSYNC)
702 if (sts & VE_MODE_DETECT_STATUS_HSYNC)
708 ctrl = aspeed_video_read(video, VE_CTRL);
710 if (hsync_counter < 0) {
711 ctrl |= VE_CTRL_HSYNC_POL;
712 video->detected_timings.polarities &=
713 ~V4L2_DV_HSYNC_POS_POL;
715 ctrl &= ~VE_CTRL_HSYNC_POL;
716 video->detected_timings.polarities |=
717 V4L2_DV_HSYNC_POS_POL;
720 if (vsync_counter < 0) {
721 ctrl |= VE_CTRL_VSYNC_POL;
722 video->detected_timings.polarities &=
723 ~V4L2_DV_VSYNC_POS_POL;
725 ctrl &= ~VE_CTRL_VSYNC_POL;
726 video->detected_timings.polarities |=
727 V4L2_DV_VSYNC_POS_POL;
730 aspeed_video_write(video, VE_CTRL, ctrl);
733 static bool aspeed_video_alloc_buf(struct aspeed_video *video,
734 struct aspeed_video_addr *addr,
737 addr->virt = dma_alloc_coherent(video->dev, size, &addr->dma,
746 static void aspeed_video_free_buf(struct aspeed_video *video,
747 struct aspeed_video_addr *addr)
749 dma_free_coherent(video->dev, addr->size, addr->virt, addr->dma);
756 * Get the minimum HW-supported compression buffer size for the frame size.
757 * Assume worst-case JPEG compression size is 1/8 raw size. This should be
758 * plenty even for maximum quality; any worse and the engine will simply return
761 static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
762 unsigned int frame_size)
765 u32 compression_buffer_size_reg = 0;
767 const unsigned int num_compression_packets = 4;
768 const unsigned int compression_packet_size = 1024;
769 const unsigned int max_compressed_size = frame_size / 2; /* 4bpp / 8 */
771 video->max_compressed_size = UINT_MAX;
773 for (i = 0; i < 6; ++i) {
774 for (j = 0; j < 8; ++j) {
775 size = (num_compression_packets << i) *
776 (compression_packet_size << j);
777 if (size < max_compressed_size)
780 if (size < video->max_compressed_size) {
781 compression_buffer_size_reg = (i << 3) | j;
782 video->max_compressed_size = size;
787 aspeed_video_write(video, VE_STREAM_BUF_SIZE,
788 compression_buffer_size_reg);
790 dev_dbg(video->dev, "Max compressed size: %x\n",
791 video->max_compressed_size);
794 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
796 static void aspeed_video_get_resolution(struct aspeed_video *video)
798 bool invalid_resolution = true;
805 struct v4l2_bt_timings *det = &video->detected_timings;
807 det->width = MIN_WIDTH;
808 det->height = MIN_HEIGHT;
809 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
810 memset(&video->perf, 0, sizeof(video->perf));
814 set_current_state(TASK_INTERRUPTIBLE);
815 if (schedule_timeout(INVALID_RESOLUTION_DELAY))
819 set_bit(VIDEO_RES_DETECT, &video->flags);
820 aspeed_video_update(video, VE_CTRL,
821 VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, 0);
822 aspeed_video_enable_mode_detect(video);
824 rc = wait_event_interruptible_timeout(video->wait,
826 MODE_DETECT_TIMEOUT);
828 dev_dbg(video->dev, "Timed out; first mode detect\n");
829 clear_bit(VIDEO_RES_DETECT, &video->flags);
833 aspeed_video_check_and_set_polarity(video);
835 aspeed_video_enable_mode_detect(video);
837 rc = wait_event_interruptible_timeout(video->wait,
839 MODE_DETECT_TIMEOUT);
840 clear_bit(VIDEO_RES_DETECT, &video->flags);
842 dev_dbg(video->dev, "Timed out; second mode detect\n");
846 src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
847 src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
848 mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
849 sync = aspeed_video_read(video, VE_SYNC_STATUS);
851 video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >>
852 VE_SRC_TB_EDGE_DET_BOT_SHF;
853 video->frame_top = src_tb_edge & VE_SRC_TB_EDGE_DET_TOP;
854 det->vfrontporch = video->frame_top;
855 det->vbackporch = ((mds & VE_MODE_DETECT_V_LINES) >>
856 VE_MODE_DETECT_V_LINES_SHF) - video->frame_bottom;
857 det->vsync = (sync & VE_SYNC_STATUS_VSYNC) >>
858 VE_SYNC_STATUS_VSYNC_SHF;
859 if (video->frame_top > video->frame_bottom)
862 video->frame_right = (src_lr_edge & VE_SRC_LR_EDGE_DET_RT) >>
863 VE_SRC_LR_EDGE_DET_RT_SHF;
864 video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT;
865 det->hfrontporch = video->frame_left;
866 det->hbackporch = (mds & VE_MODE_DETECT_H_PIXELS) -
868 det->hsync = sync & VE_SYNC_STATUS_HSYNC;
869 if (video->frame_left > video->frame_right)
872 invalid_resolution = false;
873 } while (invalid_resolution && (tries++ < INVALID_RESOLUTION_RETRIES));
875 if (invalid_resolution) {
876 dev_dbg(video->dev, "Invalid resolution detected\n");
880 det->height = (video->frame_bottom - video->frame_top) + 1;
881 det->width = (video->frame_right - video->frame_left) + 1;
882 video->v4l2_input_status = 0;
885 * Enable mode-detect watchdog, resolution-change watchdog and
886 * automatic compression after frame capture.
888 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
889 VE_INTERRUPT_MODE_DETECT_WD);
890 aspeed_video_update(video, VE_SEQ_CTRL, 0,
891 VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
893 dev_dbg(video->dev, "Got resolution: %dx%d\n", det->width,
897 static void aspeed_video_set_resolution(struct aspeed_video *video)
899 struct v4l2_bt_timings *act = &video->active_timings;
900 unsigned int size = act->width * act->height;
902 /* Set capture/compression frame sizes */
903 aspeed_video_calc_compressed_size(video, size);
905 if (video->active_timings.width == 1680) {
907 * This is a workaround to fix a silicon bug on A1 and A2
908 * revisions. Since it doesn't break capturing operation of
909 * other revisions, use it for all revisions without checking
910 * the revision ID. It picked 1728 which is a very next
911 * 64-pixels aligned value to 1680 to minimize memory bandwidth
912 * and to get better access speed from video engine.
914 aspeed_video_write(video, VE_CAP_WINDOW,
915 1728 << 16 | act->height);
916 size += (1728 - 1680) * video->active_timings.height;
918 aspeed_video_write(video, VE_CAP_WINDOW,
919 act->width << 16 | act->height);
921 aspeed_video_write(video, VE_COMP_WINDOW,
922 act->width << 16 | act->height);
923 aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4);
925 /* Don't use direct mode below 1024 x 768 (irqs don't fire) */
926 if (size < DIRECT_FETCH_THRESHOLD) {
927 aspeed_video_write(video, VE_TGS_0,
928 FIELD_PREP(VE_TGS_FIRST,
929 video->frame_left - 1) |
930 FIELD_PREP(VE_TGS_LAST,
931 video->frame_right));
932 aspeed_video_write(video, VE_TGS_1,
933 FIELD_PREP(VE_TGS_FIRST, video->frame_top) |
934 FIELD_PREP(VE_TGS_LAST,
935 video->frame_bottom + 1));
936 aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_INT_DE);
938 aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH);
943 if (size != video->srcs[0].size) {
944 if (video->srcs[0].size)
945 aspeed_video_free_buf(video, &video->srcs[0]);
946 if (video->srcs[1].size)
947 aspeed_video_free_buf(video, &video->srcs[1]);
949 if (!aspeed_video_alloc_buf(video, &video->srcs[0], size))
951 if (!aspeed_video_alloc_buf(video, &video->srcs[1], size))
954 aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma);
955 aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma);
961 dev_err(video->dev, "Failed to allocate source buffers\n");
963 if (video->srcs[0].size)
964 aspeed_video_free_buf(video, &video->srcs[0]);
967 static void aspeed_video_init_regs(struct aspeed_video *video)
969 u32 comp_ctrl = VE_COMP_CTRL_RSVD |
970 FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
971 FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
972 u32 ctrl = VE_CTRL_AUTO_OR_CURSOR;
973 u32 seq_ctrl = video->jpeg_mode;
975 if (video->frame_rate)
976 ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
979 seq_ctrl |= VE_SEQ_CTRL_YUV420;
981 /* Unlock VE registers */
982 aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
984 /* Disable interrupts */
985 aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
986 aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
988 /* Clear the offset */
989 aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
990 aspeed_video_write(video, VE_COMP_OFFSET, 0);
992 aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
994 /* Set control registers */
995 aspeed_video_write(video, VE_SEQ_CTRL, seq_ctrl);
996 aspeed_video_write(video, VE_CTRL, ctrl);
997 aspeed_video_write(video, VE_COMP_CTRL, comp_ctrl);
999 /* Don't downscale */
1000 aspeed_video_write(video, VE_SCALING_FACTOR, 0x10001000);
1001 aspeed_video_write(video, VE_SCALING_FILTER0, 0x00200000);
1002 aspeed_video_write(video, VE_SCALING_FILTER1, 0x00200000);
1003 aspeed_video_write(video, VE_SCALING_FILTER2, 0x00200000);
1004 aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
1006 /* Set mode detection defaults */
1007 aspeed_video_write(video, VE_MODE_DETECT, 0x22666500);
1010 static void aspeed_video_start(struct aspeed_video *video)
1012 aspeed_video_on(video);
1014 aspeed_video_init_regs(video);
1016 /* Resolution set to 640x480 if no signal found */
1017 aspeed_video_get_resolution(video);
1019 /* Set timings since the device is being opened for the first time */
1020 video->active_timings = video->detected_timings;
1021 aspeed_video_set_resolution(video);
1023 video->pix_fmt.width = video->active_timings.width;
1024 video->pix_fmt.height = video->active_timings.height;
1025 video->pix_fmt.sizeimage = video->max_compressed_size;
1028 static void aspeed_video_stop(struct aspeed_video *video)
1030 set_bit(VIDEO_STOPPED, &video->flags);
1031 cancel_delayed_work_sync(&video->res_work);
1033 aspeed_video_off(video);
1035 if (video->srcs[0].size)
1036 aspeed_video_free_buf(video, &video->srcs[0]);
1038 if (video->srcs[1].size)
1039 aspeed_video_free_buf(video, &video->srcs[1]);
1041 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1045 static int aspeed_video_querycap(struct file *file, void *fh,
1046 struct v4l2_capability *cap)
1048 strscpy(cap->driver, DEVICE_NAME, sizeof(cap->driver));
1049 strscpy(cap->card, "Aspeed Video Engine", sizeof(cap->card));
1050 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1056 static int aspeed_video_enum_format(struct file *file, void *fh,
1057 struct v4l2_fmtdesc *f)
1062 f->pixelformat = V4L2_PIX_FMT_JPEG;
1067 static int aspeed_video_get_format(struct file *file, void *fh,
1068 struct v4l2_format *f)
1070 struct aspeed_video *video = video_drvdata(file);
1072 f->fmt.pix = video->pix_fmt;
1077 static int aspeed_video_enum_input(struct file *file, void *fh,
1078 struct v4l2_input *inp)
1080 struct aspeed_video *video = video_drvdata(file);
1085 strscpy(inp->name, "Host VGA capture", sizeof(inp->name));
1086 inp->type = V4L2_INPUT_TYPE_CAMERA;
1087 inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
1088 inp->status = video->v4l2_input_status;
1093 static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
1100 static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
1108 static int aspeed_video_get_parm(struct file *file, void *fh,
1109 struct v4l2_streamparm *a)
1111 struct aspeed_video *video = video_drvdata(file);
1113 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1114 a->parm.capture.readbuffers = 3;
1115 a->parm.capture.timeperframe.numerator = 1;
1116 if (!video->frame_rate)
1117 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1119 a->parm.capture.timeperframe.denominator = video->frame_rate;
1124 static int aspeed_video_set_parm(struct file *file, void *fh,
1125 struct v4l2_streamparm *a)
1127 unsigned int frame_rate = 0;
1128 struct aspeed_video *video = video_drvdata(file);
1130 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1131 a->parm.capture.readbuffers = 3;
1133 if (a->parm.capture.timeperframe.numerator)
1134 frame_rate = a->parm.capture.timeperframe.denominator /
1135 a->parm.capture.timeperframe.numerator;
1137 if (!frame_rate || frame_rate > MAX_FRAME_RATE) {
1139 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1140 a->parm.capture.timeperframe.numerator = 1;
1143 if (video->frame_rate != frame_rate) {
1144 video->frame_rate = frame_rate;
1145 aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC,
1146 FIELD_PREP(VE_CTRL_FRC, frame_rate));
1152 static int aspeed_video_enum_framesizes(struct file *file, void *fh,
1153 struct v4l2_frmsizeenum *fsize)
1155 struct aspeed_video *video = video_drvdata(file);
1160 if (fsize->pixel_format != V4L2_PIX_FMT_JPEG)
1163 fsize->discrete.width = video->pix_fmt.width;
1164 fsize->discrete.height = video->pix_fmt.height;
1165 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1170 static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
1171 struct v4l2_frmivalenum *fival)
1173 struct aspeed_video *video = video_drvdata(file);
1178 if (fival->width != video->detected_timings.width ||
1179 fival->height != video->detected_timings.height)
1182 if (fival->pixel_format != V4L2_PIX_FMT_JPEG)
1185 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1187 fival->stepwise.min.denominator = MAX_FRAME_RATE;
1188 fival->stepwise.min.numerator = 1;
1189 fival->stepwise.max.denominator = 1;
1190 fival->stepwise.max.numerator = 1;
1191 fival->stepwise.step = fival->stepwise.max;
1196 static int aspeed_video_set_dv_timings(struct file *file, void *fh,
1197 struct v4l2_dv_timings *timings)
1199 struct aspeed_video *video = video_drvdata(file);
1201 if (timings->bt.width == video->active_timings.width &&
1202 timings->bt.height == video->active_timings.height)
1205 if (vb2_is_busy(&video->queue))
1208 video->active_timings = timings->bt;
1210 aspeed_video_set_resolution(video);
1212 video->pix_fmt.width = timings->bt.width;
1213 video->pix_fmt.height = timings->bt.height;
1214 video->pix_fmt.sizeimage = video->max_compressed_size;
1216 timings->type = V4L2_DV_BT_656_1120;
1221 static int aspeed_video_get_dv_timings(struct file *file, void *fh,
1222 struct v4l2_dv_timings *timings)
1224 struct aspeed_video *video = video_drvdata(file);
1226 timings->type = V4L2_DV_BT_656_1120;
1227 timings->bt = video->active_timings;
1232 static int aspeed_video_query_dv_timings(struct file *file, void *fh,
1233 struct v4l2_dv_timings *timings)
1236 struct aspeed_video *video = video_drvdata(file);
1239 * This blocks only if the driver is currently in the process of
1240 * detecting a new resolution; in the event of no signal or timeout
1241 * this function is woken up.
1243 if (file->f_flags & O_NONBLOCK) {
1244 if (test_bit(VIDEO_RES_CHANGE, &video->flags))
1247 rc = wait_event_interruptible(video->wait,
1248 !test_bit(VIDEO_RES_CHANGE,
1254 timings->type = V4L2_DV_BT_656_1120;
1255 timings->bt = video->detected_timings;
1257 return video->v4l2_input_status ? -ENOLINK : 0;
1260 static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
1261 struct v4l2_enum_dv_timings *timings)
1263 return v4l2_enum_dv_timings_cap(timings, &aspeed_video_timings_cap,
1267 static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
1268 struct v4l2_dv_timings_cap *cap)
1270 *cap = aspeed_video_timings_cap;
1275 static int aspeed_video_sub_event(struct v4l2_fh *fh,
1276 const struct v4l2_event_subscription *sub)
1278 switch (sub->type) {
1279 case V4L2_EVENT_SOURCE_CHANGE:
1280 return v4l2_src_change_event_subscribe(fh, sub);
1283 return v4l2_ctrl_subscribe_event(fh, sub);
1286 static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = {
1287 .vidioc_querycap = aspeed_video_querycap,
1289 .vidioc_enum_fmt_vid_cap = aspeed_video_enum_format,
1290 .vidioc_g_fmt_vid_cap = aspeed_video_get_format,
1291 .vidioc_s_fmt_vid_cap = aspeed_video_get_format,
1292 .vidioc_try_fmt_vid_cap = aspeed_video_get_format,
1294 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1295 .vidioc_querybuf = vb2_ioctl_querybuf,
1296 .vidioc_qbuf = vb2_ioctl_qbuf,
1297 .vidioc_expbuf = vb2_ioctl_expbuf,
1298 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1299 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1300 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1301 .vidioc_streamon = vb2_ioctl_streamon,
1302 .vidioc_streamoff = vb2_ioctl_streamoff,
1304 .vidioc_enum_input = aspeed_video_enum_input,
1305 .vidioc_g_input = aspeed_video_get_input,
1306 .vidioc_s_input = aspeed_video_set_input,
1308 .vidioc_g_parm = aspeed_video_get_parm,
1309 .vidioc_s_parm = aspeed_video_set_parm,
1310 .vidioc_enum_framesizes = aspeed_video_enum_framesizes,
1311 .vidioc_enum_frameintervals = aspeed_video_enum_frameintervals,
1313 .vidioc_s_dv_timings = aspeed_video_set_dv_timings,
1314 .vidioc_g_dv_timings = aspeed_video_get_dv_timings,
1315 .vidioc_query_dv_timings = aspeed_video_query_dv_timings,
1316 .vidioc_enum_dv_timings = aspeed_video_enum_dv_timings,
1317 .vidioc_dv_timings_cap = aspeed_video_dv_timings_cap,
1319 .vidioc_subscribe_event = aspeed_video_sub_event,
1320 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1323 static void aspeed_video_update_jpeg_quality(struct aspeed_video *video)
1325 u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
1326 FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
1328 aspeed_video_update(video, VE_COMP_CTRL,
1329 VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR,
1333 static void aspeed_video_update_subsampling(struct aspeed_video *video)
1335 if (video->jpeg.virt)
1336 aspeed_video_update_jpeg_table(video->jpeg.virt, video->yuv420);
1339 aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420);
1341 aspeed_video_update(video, VE_SEQ_CTRL, VE_SEQ_CTRL_YUV420, 0);
1344 static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
1346 struct aspeed_video *video = container_of(ctrl->handler,
1347 struct aspeed_video,
1351 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1352 video->jpeg_quality = ctrl->val;
1353 aspeed_video_update_jpeg_quality(video);
1355 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1356 if (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
1357 video->yuv420 = true;
1358 aspeed_video_update_subsampling(video);
1360 video->yuv420 = false;
1361 aspeed_video_update_subsampling(video);
1371 static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
1372 .s_ctrl = aspeed_video_set_ctrl,
1375 static void aspeed_video_resolution_work(struct work_struct *work)
1377 struct delayed_work *dwork = to_delayed_work(work);
1378 struct aspeed_video *video = container_of(dwork, struct aspeed_video,
1381 aspeed_video_on(video);
1383 /* Exit early in case no clients remain */
1384 if (test_bit(VIDEO_STOPPED, &video->flags))
1387 aspeed_video_init_regs(video);
1389 aspeed_video_get_resolution(video);
1391 if (video->detected_timings.width != video->active_timings.width ||
1392 video->detected_timings.height != video->active_timings.height) {
1393 static const struct v4l2_event ev = {
1394 .type = V4L2_EVENT_SOURCE_CHANGE,
1395 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1398 v4l2_event_queue(&video->vdev, &ev);
1399 } else if (test_bit(VIDEO_STREAMING, &video->flags)) {
1400 /* No resolution change so just restart streaming */
1401 aspeed_video_start_frame(video);
1405 clear_bit(VIDEO_RES_CHANGE, &video->flags);
1406 wake_up_interruptible_all(&video->wait);
1409 static int aspeed_video_open(struct file *file)
1412 struct aspeed_video *video = video_drvdata(file);
1414 mutex_lock(&video->video_lock);
1416 rc = v4l2_fh_open(file);
1418 mutex_unlock(&video->video_lock);
1422 if (v4l2_fh_is_singular_file(file))
1423 aspeed_video_start(video);
1425 mutex_unlock(&video->video_lock);
1430 static int aspeed_video_release(struct file *file)
1433 struct aspeed_video *video = video_drvdata(file);
1435 mutex_lock(&video->video_lock);
1437 if (v4l2_fh_is_singular_file(file))
1438 aspeed_video_stop(video);
1440 rc = _vb2_fop_release(file, NULL);
1442 mutex_unlock(&video->video_lock);
1447 static const struct v4l2_file_operations aspeed_video_v4l2_fops = {
1448 .owner = THIS_MODULE,
1449 .read = vb2_fop_read,
1450 .poll = vb2_fop_poll,
1451 .unlocked_ioctl = video_ioctl2,
1452 .mmap = vb2_fop_mmap,
1453 .open = aspeed_video_open,
1454 .release = aspeed_video_release,
1457 static int aspeed_video_queue_setup(struct vb2_queue *q,
1458 unsigned int *num_buffers,
1459 unsigned int *num_planes,
1460 unsigned int sizes[],
1461 struct device *alloc_devs[])
1463 struct aspeed_video *video = vb2_get_drv_priv(q);
1466 if (sizes[0] < video->max_compressed_size)
1473 sizes[0] = video->max_compressed_size;
1478 static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
1480 struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1482 if (vb2_plane_size(vb, 0) < video->max_compressed_size)
1488 static int aspeed_video_start_streaming(struct vb2_queue *q,
1492 struct aspeed_video *video = vb2_get_drv_priv(q);
1494 video->sequence = 0;
1495 video->perf.duration_max = 0;
1496 video->perf.duration_min = 0xffffffff;
1498 rc = aspeed_video_start_frame(video);
1500 aspeed_video_bufs_done(video, VB2_BUF_STATE_QUEUED);
1504 set_bit(VIDEO_STREAMING, &video->flags);
1508 static void aspeed_video_stop_streaming(struct vb2_queue *q)
1511 struct aspeed_video *video = vb2_get_drv_priv(q);
1513 clear_bit(VIDEO_STREAMING, &video->flags);
1515 rc = wait_event_timeout(video->wait,
1516 !test_bit(VIDEO_FRAME_INPRG, &video->flags),
1519 dev_dbg(video->dev, "Timed out when stopping streaming\n");
1522 * Need to force stop any DMA and try and get HW into a good
1523 * state for future calls to start streaming again.
1525 aspeed_video_off(video);
1526 aspeed_video_on(video);
1528 aspeed_video_init_regs(video);
1530 aspeed_video_get_resolution(video);
1533 aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
1536 static void aspeed_video_buf_queue(struct vb2_buffer *vb)
1539 struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1540 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1541 struct aspeed_video_buffer *avb = to_aspeed_video_buffer(vbuf);
1542 unsigned long flags;
1544 spin_lock_irqsave(&video->lock, flags);
1545 empty = list_empty(&video->buffers);
1546 list_add_tail(&avb->link, &video->buffers);
1547 spin_unlock_irqrestore(&video->lock, flags);
1549 if (test_bit(VIDEO_STREAMING, &video->flags) &&
1550 !test_bit(VIDEO_FRAME_INPRG, &video->flags) && empty)
1551 aspeed_video_start_frame(video);
1554 static const struct vb2_ops aspeed_video_vb2_ops = {
1555 .queue_setup = aspeed_video_queue_setup,
1556 .wait_prepare = vb2_ops_wait_prepare,
1557 .wait_finish = vb2_ops_wait_finish,
1558 .buf_prepare = aspeed_video_buf_prepare,
1559 .start_streaming = aspeed_video_start_streaming,
1560 .stop_streaming = aspeed_video_stop_streaming,
1561 .buf_queue = aspeed_video_buf_queue,
1564 #ifdef CONFIG_DEBUG_FS
1565 static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
1567 struct aspeed_video *v = s->private;
1571 seq_printf(s, " %-20s:\t%s\n", "Signal",
1572 v->v4l2_input_status ? "Unlock" : "Lock");
1573 seq_printf(s, " %-20s:\t%d\n", "Width", v->pix_fmt.width);
1574 seq_printf(s, " %-20s:\t%d\n", "Height", v->pix_fmt.height);
1575 seq_printf(s, " %-20s:\t%d\n", "FRC", v->frame_rate);
1579 seq_puts(s, "Performance:\n");
1580 seq_printf(s, " %-20s:\t%d\n", "Frame#", v->sequence);
1581 seq_printf(s, " %-20s:\n", "Frame Duration(ms)");
1582 seq_printf(s, " %-18s:\t%d\n", "Now", v->perf.duration);
1583 seq_printf(s, " %-18s:\t%d\n", "Min", v->perf.duration_min);
1584 seq_printf(s, " %-18s:\t%d\n", "Max", v->perf.duration_max);
1585 seq_printf(s, " %-20s:\t%d\n", "FPS", 1000 / (v->perf.totaltime / v->sequence));
1590 static int aspeed_video_proc_open(struct inode *inode, struct file *file)
1592 return single_open(file, aspeed_video_debugfs_show, inode->i_private);
1595 static const struct file_operations aspeed_video_debugfs_ops = {
1596 .owner = THIS_MODULE,
1597 .open = aspeed_video_proc_open,
1599 .llseek = seq_lseek,
1600 .release = single_release,
1603 static struct dentry *debugfs_entry;
1605 static void aspeed_video_debugfs_remove(struct aspeed_video *video)
1607 debugfs_remove_recursive(debugfs_entry);
1608 debugfs_entry = NULL;
1611 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1613 debugfs_entry = debugfs_create_file(DEVICE_NAME, 0444, NULL,
1615 &aspeed_video_debugfs_ops);
1617 aspeed_video_debugfs_remove(video);
1619 return !debugfs_entry ? -EIO : 0;
1622 static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
1623 static int aspeed_video_debugfs_create(struct aspeed_video *video)
1627 #endif /* CONFIG_DEBUG_FS */
1629 static int aspeed_video_setup_video(struct aspeed_video *video)
1631 const u64 mask = ~(BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_444) |
1632 BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_420));
1633 struct v4l2_device *v4l2_dev = &video->v4l2_dev;
1634 struct vb2_queue *vbq = &video->queue;
1635 struct video_device *vdev = &video->vdev;
1638 video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG;
1639 video->pix_fmt.field = V4L2_FIELD_NONE;
1640 video->pix_fmt.colorspace = V4L2_COLORSPACE_SRGB;
1641 video->pix_fmt.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1642 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1644 rc = v4l2_device_register(video->dev, v4l2_dev);
1646 dev_err(video->dev, "Failed to register v4l2 device\n");
1650 v4l2_ctrl_handler_init(&video->ctrl_handler, 2);
1651 v4l2_ctrl_new_std(&video->ctrl_handler, &aspeed_video_ctrl_ops,
1652 V4L2_CID_JPEG_COMPRESSION_QUALITY, 0,
1653 ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1, 1, 0);
1654 v4l2_ctrl_new_std_menu(&video->ctrl_handler, &aspeed_video_ctrl_ops,
1655 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1656 V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask,
1657 V4L2_JPEG_CHROMA_SUBSAMPLING_444);
1659 rc = video->ctrl_handler.error;
1661 v4l2_ctrl_handler_free(&video->ctrl_handler);
1662 v4l2_device_unregister(v4l2_dev);
1664 dev_err(video->dev, "Failed to init controls: %d\n", rc);
1668 v4l2_dev->ctrl_handler = &video->ctrl_handler;
1670 vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1671 vbq->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1672 vbq->dev = v4l2_dev->dev;
1673 vbq->lock = &video->video_lock;
1674 vbq->ops = &aspeed_video_vb2_ops;
1675 vbq->mem_ops = &vb2_dma_contig_memops;
1676 vbq->drv_priv = video;
1677 vbq->buf_struct_size = sizeof(struct aspeed_video_buffer);
1678 vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1679 vbq->min_buffers_needed = 3;
1681 rc = vb2_queue_init(vbq);
1683 v4l2_ctrl_handler_free(&video->ctrl_handler);
1684 v4l2_device_unregister(v4l2_dev);
1686 dev_err(video->dev, "Failed to init vb2 queue\n");
1691 vdev->fops = &aspeed_video_v4l2_fops;
1692 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1694 vdev->v4l2_dev = v4l2_dev;
1695 strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));
1696 vdev->vfl_type = VFL_TYPE_VIDEO;
1697 vdev->vfl_dir = VFL_DIR_RX;
1698 vdev->release = video_device_release_empty;
1699 vdev->ioctl_ops = &aspeed_video_ioctl_ops;
1700 vdev->lock = &video->video_lock;
1702 video_set_drvdata(vdev, video);
1703 rc = video_register_device(vdev, VFL_TYPE_VIDEO, 0);
1705 v4l2_ctrl_handler_free(&video->ctrl_handler);
1706 v4l2_device_unregister(v4l2_dev);
1708 dev_err(video->dev, "Failed to register video device\n");
1715 static int aspeed_video_init(struct aspeed_video *video)
1719 struct device *dev = video->dev;
1721 irq = irq_of_parse_and_map(dev->of_node, 0);
1723 dev_err(dev, "Unable to find IRQ\n");
1727 rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
1728 IRQF_ONESHOT, DEVICE_NAME, video);
1730 dev_err(dev, "Unable to request IRQ %d\n", irq);
1734 video->eclk = devm_clk_get(dev, "eclk");
1735 if (IS_ERR(video->eclk)) {
1736 dev_err(dev, "Unable to get ECLK\n");
1737 return PTR_ERR(video->eclk);
1740 rc = clk_prepare(video->eclk);
1744 video->vclk = devm_clk_get(dev, "vclk");
1745 if (IS_ERR(video->vclk)) {
1746 dev_err(dev, "Unable to get VCLK\n");
1747 rc = PTR_ERR(video->vclk);
1748 goto err_unprepare_eclk;
1751 rc = clk_prepare(video->vclk);
1753 goto err_unprepare_eclk;
1755 of_reserved_mem_device_init(dev);
1757 rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1759 dev_err(dev, "Failed to set DMA mask\n");
1760 goto err_release_reserved_mem;
1763 if (!aspeed_video_alloc_buf(video, &video->jpeg,
1764 VE_JPEG_HEADER_SIZE)) {
1765 dev_err(dev, "Failed to allocate DMA for JPEG header\n");
1767 goto err_release_reserved_mem;
1770 aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
1774 err_release_reserved_mem:
1775 of_reserved_mem_device_release(dev);
1776 clk_unprepare(video->vclk);
1778 clk_unprepare(video->eclk);
1783 static const struct of_device_id aspeed_video_of_match[] = {
1784 { .compatible = "aspeed,ast2400-video-engine", .data = &ast2400_config },
1785 { .compatible = "aspeed,ast2500-video-engine", .data = &ast2500_config },
1786 { .compatible = "aspeed,ast2600-video-engine", .data = &ast2600_config },
1789 MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
1791 static int aspeed_video_probe(struct platform_device *pdev)
1793 const struct aspeed_video_config *config;
1794 const struct of_device_id *match;
1795 struct aspeed_video *video;
1798 video = devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
1802 video->base = devm_platform_ioremap_resource(pdev, 0);
1803 if (IS_ERR(video->base))
1804 return PTR_ERR(video->base);
1806 match = of_match_node(aspeed_video_of_match, pdev->dev.of_node);
1810 config = match->data;
1811 video->jpeg_mode = config->jpeg_mode;
1812 video->comp_size_read = config->comp_size_read;
1814 video->frame_rate = 30;
1815 video->dev = &pdev->dev;
1816 spin_lock_init(&video->lock);
1817 mutex_init(&video->video_lock);
1818 init_waitqueue_head(&video->wait);
1819 INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
1820 INIT_LIST_HEAD(&video->buffers);
1822 rc = aspeed_video_init(video);
1826 rc = aspeed_video_setup_video(video);
1828 clk_unprepare(video->vclk);
1829 clk_unprepare(video->eclk);
1833 rc = aspeed_video_debugfs_create(video);
1835 dev_err(video->dev, "debugfs create failed\n");
1840 static int aspeed_video_remove(struct platform_device *pdev)
1842 struct device *dev = &pdev->dev;
1843 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1844 struct aspeed_video *video = to_aspeed_video(v4l2_dev);
1846 aspeed_video_off(video);
1848 aspeed_video_debugfs_remove(video);
1850 clk_unprepare(video->vclk);
1851 clk_unprepare(video->eclk);
1853 vb2_video_unregister_device(&video->vdev);
1855 v4l2_ctrl_handler_free(&video->ctrl_handler);
1857 v4l2_device_unregister(v4l2_dev);
1859 dma_free_coherent(video->dev, VE_JPEG_HEADER_SIZE, video->jpeg.virt,
1862 of_reserved_mem_device_release(dev);
1867 static struct platform_driver aspeed_video_driver = {
1869 .name = DEVICE_NAME,
1870 .of_match_table = aspeed_video_of_match,
1872 .probe = aspeed_video_probe,
1873 .remove = aspeed_video_remove,
1876 module_platform_driver(aspeed_video_driver);
1878 MODULE_DESCRIPTION("ASPEED Video Engine Driver");
1879 MODULE_AUTHOR("Eddie James");
1880 MODULE_LICENSE("GPL v2");