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