1// SPDX-License-Identifier: GPL-2.0-or-later
2// Copyright 2020 IBM Corp.
3// Copyright (c) 2019-2020 Intel Corporation
4
5#include <linux/atomic.h>
6#include <linux/bitfield.h>
7#include <linux/clk.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>
15#include <linux/of.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>
35#include <uapi/linux/aspeed-video.h>
36
37#define ASPEED_VIDEO_V4L2_MIN_BUF_REQ 3
38
39#define DEVICE_NAME "aspeed-video"
40
41#define ASPEED_VIDEO_JPEG_NUM_QUALITIES 12
42#define ASPEED_VIDEO_JPEG_HEADER_SIZE 10
43#define ASPEED_VIDEO_JPEG_QUANT_SIZE 116
44#define ASPEED_VIDEO_JPEG_DCT_SIZE 34
45
46#define MAX_FRAME_RATE 60
47#define MAX_HEIGHT 1200
48#define MAX_WIDTH 1920
49#define MIN_HEIGHT 480
50#define MIN_WIDTH 640
51
52#define NUM_POLARITY_CHECKS 10
53#define INVALID_RESOLUTION_RETRIES 2
54#define INVALID_RESOLUTION_DELAY msecs_to_jiffies(250)
55#define RESOLUTION_CHANGE_DELAY msecs_to_jiffies(500)
56#define MODE_DETECT_TIMEOUT msecs_to_jiffies(500)
57#define STOP_TIMEOUT msecs_to_jiffies(1000)
58#define DIRECT_FETCH_THRESHOLD 0x0c0000 /* 1024 * 768 */
59
60#define VE_MAX_SRC_BUFFER_SIZE 0x8ca000 /* 1920 * 1200, 32bpp */
61#define VE_JPEG_HEADER_SIZE 0x006000 /* 512 * 12 * 4 */
62#define VE_BCD_BUFF_SIZE 0x9000 /* (1920/8) * (1200/8) */
63
64#define VE_PROTECTION_KEY 0x000
65#define VE_PROTECTION_KEY_UNLOCK 0x1a038aa8
66
67#define VE_SEQ_CTRL 0x004
68#define VE_SEQ_CTRL_TRIG_MODE_DET BIT(0)
69#define VE_SEQ_CTRL_TRIG_CAPTURE BIT(1)
70#define VE_SEQ_CTRL_FORCE_IDLE BIT(2)
71#define VE_SEQ_CTRL_MULT_FRAME BIT(3)
72#define VE_SEQ_CTRL_TRIG_COMP BIT(4)
73#define VE_SEQ_CTRL_AUTO_COMP BIT(5)
74#define VE_SEQ_CTRL_EN_WATCHDOG BIT(7)
75#define VE_SEQ_CTRL_YUV420 BIT(10)
76#define VE_SEQ_CTRL_COMP_FMT GENMASK(11, 10)
77#define VE_SEQ_CTRL_HALT BIT(12)
78#define VE_SEQ_CTRL_EN_WATCHDOG_COMP BIT(14)
79#define VE_SEQ_CTRL_TRIG_JPG BIT(15)
80#define VE_SEQ_CTRL_CAP_BUSY BIT(16)
81#define VE_SEQ_CTRL_COMP_BUSY BIT(18)
82
83#define AST2500_VE_SEQ_CTRL_JPEG_MODE BIT(13)
84#define AST2400_VE_SEQ_CTRL_JPEG_MODE BIT(8)
85
86#define VE_CTRL 0x008
87#define VE_CTRL_HSYNC_POL BIT(0)
88#define VE_CTRL_VSYNC_POL BIT(1)
89#define VE_CTRL_SOURCE BIT(2)
90#define VE_CTRL_INT_DE BIT(4)
91#define VE_CTRL_DIRECT_FETCH BIT(5)
92#define VE_CTRL_CAPTURE_FMT GENMASK(7, 6)
93#define VE_CTRL_AUTO_OR_CURSOR BIT(8)
94#define VE_CTRL_CLK_INVERSE BIT(11)
95#define VE_CTRL_CLK_DELAY GENMASK(11, 9)
96#define VE_CTRL_INTERLACE BIT(14)
97#define VE_CTRL_HSYNC_POL_CTRL BIT(15)
98#define VE_CTRL_FRC GENMASK(23, 16)
99
100#define VE_TGS_0 0x00c
101#define VE_TGS_1 0x010
102#define VE_TGS_FIRST GENMASK(28, 16)
103#define VE_TGS_LAST GENMASK(12, 0)
104
105#define VE_SCALING_FACTOR 0x014
106#define VE_SCALING_FILTER0 0x018
107#define VE_SCALING_FILTER1 0x01c
108#define VE_SCALING_FILTER2 0x020
109#define VE_SCALING_FILTER3 0x024
110
111#define VE_BCD_CTRL 0x02C
112#define VE_BCD_CTRL_EN_BCD BIT(0)
113#define VE_BCD_CTRL_EN_ABCD BIT(1)
114#define VE_BCD_CTRL_EN_CB BIT(2)
115#define VE_BCD_CTRL_THR GENMASK(23, 16)
116#define VE_BCD_CTRL_ABCD_THR GENMASK(31, 24)
117
118#define VE_CAP_WINDOW 0x030
119#define VE_COMP_WINDOW 0x034
120#define VE_COMP_PROC_OFFSET 0x038
121#define VE_COMP_OFFSET 0x03c
122#define VE_JPEG_ADDR 0x040
123#define VE_SRC0_ADDR 0x044
124#define VE_SRC_SCANLINE_OFFSET 0x048
125#define VE_SRC1_ADDR 0x04c
126#define VE_BCD_ADDR 0x050
127#define VE_COMP_ADDR 0x054
128
129#define VE_STREAM_BUF_SIZE 0x058
130#define VE_STREAM_BUF_SIZE_N_PACKETS GENMASK(5, 3)
131#define VE_STREAM_BUF_SIZE_P_SIZE GENMASK(2, 0)
132
133#define VE_COMP_CTRL 0x060
134#define VE_COMP_CTRL_VQ_DCT_ONLY BIT(0)
135#define VE_COMP_CTRL_VQ_4COLOR BIT(1)
136#define VE_COMP_CTRL_QUANTIZE BIT(2)
137#define VE_COMP_CTRL_EN_BQ BIT(4)
138#define VE_COMP_CTRL_EN_CRYPTO BIT(5)
139#define VE_COMP_CTRL_DCT_CHR GENMASK(10, 6)
140#define VE_COMP_CTRL_DCT_LUM GENMASK(15, 11)
141#define VE_COMP_CTRL_EN_HQ BIT(16)
142#define VE_COMP_CTRL_RSVD BIT(19)
143#define VE_COMP_CTRL_ENCODE GENMASK(21, 20)
144#define VE_COMP_CTRL_HQ_DCT_CHR GENMASK(26, 22)
145#define VE_COMP_CTRL_HQ_DCT_LUM GENMASK(31, 27)
146
147#define VE_CB_ADDR 0x06C
148
149#define AST2400_VE_COMP_SIZE_READ_BACK 0x078
150#define AST2600_VE_COMP_SIZE_READ_BACK 0x084
151
152#define VE_SRC_LR_EDGE_DET 0x090
153#define VE_SRC_LR_EDGE_DET_LEFT GENMASK(11, 0)
154#define VE_SRC_LR_EDGE_DET_NO_V BIT(12)
155#define VE_SRC_LR_EDGE_DET_NO_H BIT(13)
156#define VE_SRC_LR_EDGE_DET_NO_DISP BIT(14)
157#define VE_SRC_LR_EDGE_DET_NO_CLK BIT(15)
158#define VE_SRC_LR_EDGE_DET_RT GENMASK(27, 16)
159#define VE_SRC_LR_EDGE_DET_INTERLACE BIT(31)
160
161#define VE_SRC_TB_EDGE_DET 0x094
162#define VE_SRC_TB_EDGE_DET_TOP GENMASK(12, 0)
163#define VE_SRC_TB_EDGE_DET_BOT GENMASK(28, 16)
164
165#define VE_MODE_DETECT_STATUS 0x098
166#define VE_MODE_DETECT_H_PERIOD GENMASK(11, 0)
167#define VE_MODE_DETECT_EXTSRC_ADC BIT(12)
168#define VE_MODE_DETECT_H_STABLE BIT(13)
169#define VE_MODE_DETECT_V_STABLE BIT(14)
170#define VE_MODE_DETECT_V_LINES GENMASK(27, 16)
171#define VE_MODE_DETECT_STATUS_VSYNC BIT(28)
172#define VE_MODE_DETECT_STATUS_HSYNC BIT(29)
173#define VE_MODE_DETECT_VSYNC_RDY BIT(30)
174#define VE_MODE_DETECT_HSYNC_RDY BIT(31)
175
176#define VE_SYNC_STATUS 0x09c
177#define VE_SYNC_STATUS_HSYNC GENMASK(11, 0)
178#define VE_SYNC_STATUS_VSYNC GENMASK(27, 16)
179
180#define VE_H_TOTAL_PIXELS 0x0A0
181
182#define VE_INTERRUPT_CTRL 0x304
183#define VE_INTERRUPT_STATUS 0x308
184#define VE_INTERRUPT_MODE_DETECT_WD BIT(0)
185#define VE_INTERRUPT_CAPTURE_COMPLETE BIT(1)
186#define VE_INTERRUPT_COMP_READY BIT(2)
187#define VE_INTERRUPT_COMP_COMPLETE BIT(3)
188#define VE_INTERRUPT_MODE_DETECT BIT(4)
189#define VE_INTERRUPT_FRAME_COMPLETE BIT(5)
190#define VE_INTERRUPT_DECODE_ERR BIT(6)
191#define VE_INTERRUPT_HALT_READY BIT(8)
192#define VE_INTERRUPT_HANG_WD BIT(9)
193#define VE_INTERRUPT_STREAM_DESC BIT(10)
194#define VE_INTERRUPT_VSYNC_DESC BIT(11)
195
196#define VE_MODE_DETECT 0x30c
197#define VE_MODE_DT_HOR_TOLER GENMASK(31, 28)
198#define VE_MODE_DT_VER_TOLER GENMASK(27, 24)
199#define VE_MODE_DT_HOR_STABLE GENMASK(23, 20)
200#define VE_MODE_DT_VER_STABLE GENMASK(19, 16)
201#define VE_MODE_DT_EDG_THROD GENMASK(15, 8)
202
203#define VE_MEM_RESTRICT_START 0x310
204#define VE_MEM_RESTRICT_END 0x314
205
206/*
207 * VIDEO_MODE_DETECT_DONE: a flag raised if signal lock
208 * VIDEO_RES_CHANGE: a flag raised if res_change work on-going
209 * VIDEO_RES_DETECT: a flag raised if res. detection on-going
210 * VIDEO_STREAMING: a flag raised if user requires stream-on
211 * VIDEO_FRAME_INPRG: a flag raised if hw working on a frame
212 * VIDEO_STOPPED: a flag raised if device release
213 * VIDEO_CLOCKS_ON: a flag raised if clk is on
214 */
215enum {
216 VIDEO_MODE_DETECT_DONE,
217 VIDEO_RES_CHANGE,
218 VIDEO_RES_DETECT,
219 VIDEO_STREAMING,
220 VIDEO_FRAME_INPRG,
221 VIDEO_STOPPED,
222 VIDEO_CLOCKS_ON,
223};
224
225enum aspeed_video_format {
226 VIDEO_FMT_STANDARD = 0,
227 VIDEO_FMT_ASPEED,
228 VIDEO_FMT_MAX = VIDEO_FMT_ASPEED
229};
230
231// for VE_CTRL_CAPTURE_FMT
232enum aspeed_video_capture_format {
233 VIDEO_CAP_FMT_YUV_STUDIO_SWING = 0,
234 VIDEO_CAP_FMT_YUV_FULL_SWING,
235 VIDEO_CAP_FMT_RGB,
236 VIDEO_CAP_FMT_GRAY,
237 VIDEO_CAP_FMT_MAX
238};
239
240struct aspeed_video_addr {
241 unsigned int size;
242 dma_addr_t dma;
243 void *virt;
244};
245
246struct aspeed_video_buffer {
247 struct vb2_v4l2_buffer vb;
248 struct list_head link;
249};
250
251struct aspeed_video_perf {
252 ktime_t last_sample;
253 u32 totaltime;
254 u32 duration;
255 u32 duration_min;
256 u32 duration_max;
257};
258
259#define to_aspeed_video_buffer(x) \
260 container_of((x), struct aspeed_video_buffer, vb)
261
262/*
263 * struct aspeed_video - driver data
264 *
265 * res_work: holds the delayed_work for res-detection if unlock
266 * buffers: holds the list of buffer queued from user
267 * flags: holds the state of video
268 * sequence: holds the last number of frame completed
269 * max_compressed_size: holds max compressed stream's size
270 * srcs: holds the buffer information for srcs
271 * jpeg: holds the buffer information for jpeg header
272 * bcd: holds the buffer information for bcd work
273 * yuv420: a flag raised if JPEG subsampling is 420
274 * format: holds the video format
275 * hq_mode: a flag raised if HQ is enabled. Only for VIDEO_FMT_ASPEED
276 * frame_rate: holds the frame_rate
277 * jpeg_quality: holds jpeq's quality (0~11)
278 * jpeg_hq_quality: holds hq's quality (1~12) only if hq_mode enabled
279 * frame_bottom: end position of video data in vertical direction
280 * frame_left: start position of video data in horizontal direction
281 * frame_right: end position of video data in horizontal direction
282 * frame_top: start position of video data in vertical direction
283 * perf: holds the statistics primary for debugfs
284 */
285struct aspeed_video {
286 void __iomem *base;
287 struct clk *eclk;
288 struct clk *vclk;
289
290 struct device *dev;
291 struct v4l2_ctrl_handler ctrl_handler;
292 struct v4l2_device v4l2_dev;
293 struct v4l2_pix_format pix_fmt;
294 struct v4l2_bt_timings active_timings;
295 struct v4l2_bt_timings detected_timings;
296 u32 v4l2_input_status;
297 struct vb2_queue queue;
298 struct video_device vdev;
299 struct mutex video_lock; /* v4l2 and videobuf2 lock */
300
301 u32 jpeg_mode;
302 u32 comp_size_read;
303
304 wait_queue_head_t wait;
305 spinlock_t lock; /* buffer list lock */
306 struct delayed_work res_work;
307 struct list_head buffers;
308 unsigned long flags;
309 unsigned int sequence;
310
311 unsigned int max_compressed_size;
312 struct aspeed_video_addr srcs[2];
313 struct aspeed_video_addr jpeg;
314 struct aspeed_video_addr bcd;
315
316 bool yuv420;
317 enum aspeed_video_format format;
318 bool hq_mode;
319 unsigned int frame_rate;
320 unsigned int jpeg_quality;
321 unsigned int jpeg_hq_quality;
322
323 unsigned int frame_bottom;
324 unsigned int frame_left;
325 unsigned int frame_right;
326 unsigned int frame_top;
327
328 struct aspeed_video_perf perf;
329};
330
331#define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
332
333struct aspeed_video_config {
334 u32 jpeg_mode;
335 u32 comp_size_read;
336};
337
338static const struct aspeed_video_config ast2400_config = {
339 .jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
340 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
341};
342
343static const struct aspeed_video_config ast2500_config = {
344 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
345 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
346};
347
348static const struct aspeed_video_config ast2600_config = {
349 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
350 .comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
351};
352
353static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
354 0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
355 0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
356};
357
358static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] = {
359 0x081100c0, 0x00000000, 0x00110103, 0x03011102, 0xc4ff0111, 0x00001f00,
360 0x01010501, 0x01010101, 0x00000000, 0x00000000, 0x04030201, 0x08070605,
361 0xff0b0a09, 0x10b500c4, 0x03010200, 0x03040203, 0x04040505, 0x7d010000,
362 0x00030201, 0x12051104, 0x06413121, 0x07615113, 0x32147122, 0x08a19181,
363 0xc1b14223, 0xf0d15215, 0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
364 0x35342a29, 0x39383736, 0x4544433a, 0x49484746, 0x5554534a, 0x59585756,
365 0x6564635a, 0x69686766, 0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
366 0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4, 0xb2aaa9a8, 0xb6b5b4b3,
367 0xbab9b8b7, 0xc5c4c3c2, 0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
368 0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5, 0xc4fffaf9, 0x00011f00,
369 0x01010103, 0x01010101, 0x00000101, 0x00000000, 0x04030201, 0x08070605,
370 0xff0b0a09, 0x11b500c4, 0x02010200, 0x04030404, 0x04040507, 0x77020100,
371 0x03020100, 0x21050411, 0x41120631, 0x71610751, 0x81322213, 0x91421408,
372 0x09c1b1a1, 0xf0523323, 0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
373 0x2a292827, 0x38373635, 0x44433a39, 0x48474645, 0x54534a49, 0x58575655,
374 0x64635a59, 0x68676665, 0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
375 0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2, 0xa9a8a7a6, 0xb4b3b2aa,
376 0xb8b7b6b5, 0xc3c2bab9, 0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
377 0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5, 0xdafffaf9, 0x01030c00,
378 0x03110200, 0x003f0011
379};
380
381static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
382 [ASPEED_VIDEO_JPEG_DCT_SIZE] = {
383 { 0x0d140043, 0x0c0f110f, 0x11101114, 0x17141516, 0x1e20321e,
384 0x3d1e1b1b, 0x32242e2b, 0x4b4c3f48, 0x44463f47, 0x61735a50,
385 0x566c5550, 0x88644644, 0x7a766c65, 0x4d808280, 0x8c978d60,
386 0x7e73967d, 0xdbff7b80, 0x1f014300, 0x272d2121, 0x3030582d,
387 0x697bb958, 0xb8b9b97b, 0xb9b8a6a6, 0xb9b9b9b9, 0xb9b9b9b9,
388 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9,
389 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xffb9b9b9 },
390 { 0x0c110043, 0x0a0d0f0d, 0x0f0e0f11, 0x14111213, 0x1a1c2b1a,
391 0x351a1818, 0x2b1f2826, 0x4142373f, 0x3c3d373e, 0x55644e46,
392 0x4b5f4a46, 0x77573d3c, 0x6b675f58, 0x43707170, 0x7a847b54,
393 0x6e64836d, 0xdbff6c70, 0x1b014300, 0x22271d1d, 0x2a2a4c27,
394 0x5b6ba04c, 0xa0a0a06b, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
395 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
396 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xffa0a0a0 },
397 { 0x090e0043, 0x090a0c0a, 0x0c0b0c0e, 0x110e0f10, 0x15172415,
398 0x2c151313, 0x241a211f, 0x36372e34, 0x31322e33, 0x4653413a,
399 0x3e4e3d3a, 0x62483231, 0x58564e49, 0x385d5e5d, 0x656d6645,
400 0x5b536c5a, 0xdbff595d, 0x16014300, 0x1c201818, 0x22223f20,
401 0x4b58853f, 0x85858558, 0x85858585, 0x85858585, 0x85858585,
402 0x85858585, 0x85858585, 0x85858585, 0x85858585, 0x85858585,
403 0x85858585, 0x85858585, 0x85858585, 0xff858585 },
404 { 0x070b0043, 0x07080a08, 0x0a090a0b, 0x0d0b0c0c, 0x11121c11,
405 0x23110f0f, 0x1c141a19, 0x2b2b2429, 0x27282428, 0x3842332e,
406 0x313e302e, 0x4e392827, 0x46443e3a, 0x2c4a4a4a, 0x50565137,
407 0x48425647, 0xdbff474a, 0x12014300, 0x161a1313, 0x1c1c331a,
408 0x3d486c33, 0x6c6c6c48, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
409 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
410 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0xff6c6c6c },
411 { 0x06090043, 0x05060706, 0x07070709, 0x0a09090a, 0x0d0e160d,
412 0x1b0d0c0c, 0x16101413, 0x21221c20, 0x1e1f1c20, 0x2b332824,
413 0x26302624, 0x3d2d1f1e, 0x3735302d, 0x22393a39, 0x3f443f2b,
414 0x38334338, 0xdbff3739, 0x0d014300, 0x11130e0e, 0x15152613,
415 0x2d355026, 0x50505035, 0x50505050, 0x50505050, 0x50505050,
416 0x50505050, 0x50505050, 0x50505050, 0x50505050, 0x50505050,
417 0x50505050, 0x50505050, 0x50505050, 0xff505050 },
418 { 0x04060043, 0x03040504, 0x05040506, 0x07060606, 0x09090f09,
419 0x12090808, 0x0f0a0d0d, 0x16161315, 0x14151315, 0x1d221b18,
420 0x19201918, 0x281e1514, 0x2423201e, 0x17262726, 0x2a2d2a1c,
421 0x25222d25, 0xdbff2526, 0x09014300, 0x0b0d0a0a, 0x0e0e1a0d,
422 0x1f25371a, 0x37373725, 0x37373737, 0x37373737, 0x37373737,
423 0x37373737, 0x37373737, 0x37373737, 0x37373737, 0x37373737,
424 0x37373737, 0x37373737, 0x37373737, 0xff373737 },
425 { 0x02030043, 0x01020202, 0x02020203, 0x03030303, 0x04040704,
426 0x09040404, 0x07050606, 0x0b0b090a, 0x0a0a090a, 0x0e110d0c,
427 0x0c100c0c, 0x140f0a0a, 0x1211100f, 0x0b131313, 0x1516150e,
428 0x12111612, 0xdbff1213, 0x04014300, 0x05060505, 0x07070d06,
429 0x0f121b0d, 0x1b1b1b12, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
430 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
431 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0xff1b1b1b },
432 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
433 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
434 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
435 0x0c0b0f0c, 0xdbff0c0c, 0x03014300, 0x03040303, 0x04040804,
436 0x0a0c1208, 0x1212120c, 0x12121212, 0x12121212, 0x12121212,
437 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
438 0x12121212, 0x12121212, 0x12121212, 0xff121212 },
439 { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
440 0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
441 0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
442 0x0c0b0f0c, 0xdbff0c0c, 0x02014300, 0x03030202, 0x04040703,
443 0x080a0f07, 0x0f0f0f0a, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
444 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
445 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xff0f0f0f },
446 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x02020302,
447 0x04020202, 0x03020303, 0x05050405, 0x05050405, 0x07080606,
448 0x06080606, 0x0a070505, 0x09080807, 0x05090909, 0x0a0b0a07,
449 0x09080b09, 0xdbff0909, 0x02014300, 0x02030202, 0x03030503,
450 0x07080c05, 0x0c0c0c08, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
451 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
452 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xff0c0c0c },
453 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010201,
454 0x03010101, 0x02010202, 0x03030303, 0x03030303, 0x04050404,
455 0x04050404, 0x06050303, 0x06050505, 0x03060606, 0x07070704,
456 0x06050706, 0xdbff0606, 0x01014300, 0x01020101, 0x02020402,
457 0x05060904, 0x09090906, 0x09090909, 0x09090909, 0x09090909,
458 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
459 0x09090909, 0x09090909, 0x09090909, 0xff090909 },
460 { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
461 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202,
462 0x02020202, 0x03020101, 0x03020202, 0x01030303, 0x03030302,
463 0x03020303, 0xdbff0403, 0x01014300, 0x01010101, 0x01010201,
464 0x03040602, 0x06060604, 0x06060606, 0x06060606, 0x06060606,
465 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
466 0x06060606, 0x06060606, 0x06060606, 0xff060606 }
467};
468
469static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
470 .type = V4L2_DV_BT_656_1120,
471 .bt = {
472 .min_width = MIN_WIDTH,
473 .max_width = MAX_WIDTH,
474 .min_height = MIN_HEIGHT,
475 .max_height = MAX_HEIGHT,
476 .min_pixelclock = 6574080, /* 640 x 480 x 24Hz */
477 .max_pixelclock = 138240000, /* 1920 x 1200 x 60Hz */
478 .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
479 V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
480 .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
481 V4L2_DV_BT_CAP_REDUCED_BLANKING |
482 V4L2_DV_BT_CAP_CUSTOM,
483 },
484};
485
486static const char * const format_str[] = {"Standard JPEG",
487 "Aspeed JPEG"};
488
489static unsigned int debug;
490
491static bool aspeed_video_alloc_buf(struct aspeed_video *video,
492 struct aspeed_video_addr *addr,
493 unsigned int size);
494
495static void aspeed_video_free_buf(struct aspeed_video *video,
496 struct aspeed_video_addr *addr);
497
498static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
499{
500 int i;
501 unsigned int base;
502
503 for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
504 base = 256 * i; /* AST HW requires this header spacing */
505 memcpy(&table[base], aspeed_video_jpeg_header,
506 sizeof(aspeed_video_jpeg_header));
507
508 base += ASPEED_VIDEO_JPEG_HEADER_SIZE;
509 memcpy(&table[base], aspeed_video_jpeg_dct[i],
510 sizeof(aspeed_video_jpeg_dct[i]));
511
512 base += ASPEED_VIDEO_JPEG_DCT_SIZE;
513 memcpy(&table[base], aspeed_video_jpeg_quant,
514 sizeof(aspeed_video_jpeg_quant));
515
516 if (yuv420)
517 table[base + 2] = 0x00220103;
518 }
519}
520
521// just update jpeg dct table per 420/444
522static void aspeed_video_update_jpeg_table(u32 *table, bool yuv420)
523{
524 int i;
525 unsigned int base;
526
527 for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
528 base = 256 * i; /* AST HW requires this header spacing */
529 base += ASPEED_VIDEO_JPEG_HEADER_SIZE +
530 ASPEED_VIDEO_JPEG_DCT_SIZE;
531
532 table[base + 2] = (yuv420) ? 0x00220103 : 0x00110103;
533 }
534}
535
536static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
537 u32 bits)
538{
539 u32 t = readl(addr: video->base + reg);
540 u32 before = t;
541
542 t &= ~clear;
543 t |= bits;
544 writel(val: t, addr: video->base + reg);
545 v4l2_dbg(3, debug, &video->v4l2_dev, "update %03x[%08x -> %08x]\n",
546 reg, before, readl(video->base + reg));
547}
548
549static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
550{
551 u32 t = readl(addr: video->base + reg);
552
553 v4l2_dbg(3, debug, &video->v4l2_dev, "read %03x[%08x]\n", reg, t);
554 return t;
555}
556
557static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
558{
559 writel(val, addr: video->base + reg);
560 v4l2_dbg(3, debug, &video->v4l2_dev, "write %03x[%08x]\n", reg,
561 readl(video->base + reg));
562}
563
564static void update_perf(struct aspeed_video_perf *p)
565{
566 struct aspeed_video *v = container_of(p, struct aspeed_video,
567 perf);
568
569 p->duration =
570 ktime_to_ms(ktime_sub(ktime_get(), p->last_sample));
571 p->totaltime += p->duration;
572
573 p->duration_max = max(p->duration, p->duration_max);
574 p->duration_min = min(p->duration, p->duration_min);
575 v4l2_dbg(2, debug, &v->v4l2_dev, "time consumed: %d ms\n",
576 p->duration);
577}
578
579static int aspeed_video_start_frame(struct aspeed_video *video)
580{
581 dma_addr_t addr;
582 unsigned long flags;
583 struct aspeed_video_buffer *buf;
584 u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
585 bool bcd_buf_need = (video->format != VIDEO_FMT_STANDARD);
586
587 if (video->v4l2_input_status) {
588 v4l2_dbg(1, debug, &video->v4l2_dev, "No signal; don't start frame\n");
589 return 0;
590 }
591
592 if (!(seq_ctrl & VE_SEQ_CTRL_COMP_BUSY) ||
593 !(seq_ctrl & VE_SEQ_CTRL_CAP_BUSY)) {
594 v4l2_dbg(1, debug, &video->v4l2_dev, "Engine busy; don't start frame\n");
595 return -EBUSY;
596 }
597
598 if (bcd_buf_need && !video->bcd.size) {
599 if (!aspeed_video_alloc_buf(video, addr: &video->bcd,
600 VE_BCD_BUFF_SIZE)) {
601 dev_err(video->dev, "Failed to allocate BCD buffer\n");
602 dev_err(video->dev, "don't start frame\n");
603 return -ENOMEM;
604 }
605 aspeed_video_write(video, VE_BCD_ADDR, val: video->bcd.dma);
606 v4l2_dbg(1, debug, &video->v4l2_dev, "bcd addr(%pad) size(%d)\n",
607 &video->bcd.dma, video->bcd.size);
608 } else if (!bcd_buf_need && video->bcd.size) {
609 aspeed_video_free_buf(video, addr: &video->bcd);
610 }
611
612 spin_lock_irqsave(&video->lock, flags);
613 buf = list_first_entry_or_null(&video->buffers,
614 struct aspeed_video_buffer, link);
615 if (!buf) {
616 spin_unlock_irqrestore(lock: &video->lock, flags);
617 v4l2_dbg(1, debug, &video->v4l2_dev, "No buffers; don't start frame\n");
618 return -EPROTO;
619 }
620
621 set_bit(nr: VIDEO_FRAME_INPRG, addr: &video->flags);
622 addr = vb2_dma_contig_plane_dma_addr(vb: &buf->vb.vb2_buf, plane_no: 0);
623 spin_unlock_irqrestore(lock: &video->lock, flags);
624
625 aspeed_video_write(video, VE_COMP_PROC_OFFSET, val: 0);
626 aspeed_video_write(video, VE_COMP_OFFSET, val: 0);
627 aspeed_video_write(video, VE_COMP_ADDR, val: addr);
628
629 aspeed_video_update(video, VE_INTERRUPT_CTRL, clear: 0,
630 VE_INTERRUPT_COMP_COMPLETE);
631
632 video->perf.last_sample = ktime_get();
633
634 aspeed_video_update(video, VE_SEQ_CTRL, clear: 0,
635 VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
636
637 return 0;
638}
639
640static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
641{
642 /* Enable mode detect interrupts */
643 aspeed_video_update(video, VE_INTERRUPT_CTRL, clear: 0,
644 VE_INTERRUPT_MODE_DETECT);
645
646 /* Disable mode detect in order to re-trigger */
647 aspeed_video_update(video, VE_SEQ_CTRL,
648 VE_SEQ_CTRL_TRIG_MODE_DET, bits: 0);
649
650 /* Trigger mode detect */
651 aspeed_video_update(video, VE_SEQ_CTRL, clear: 0, VE_SEQ_CTRL_TRIG_MODE_DET);
652}
653
654static void aspeed_video_off(struct aspeed_video *video)
655{
656 if (!test_bit(VIDEO_CLOCKS_ON, &video->flags))
657 return;
658
659 /* Disable interrupts */
660 aspeed_video_write(video, VE_INTERRUPT_CTRL, val: 0);
661 aspeed_video_write(video, VE_INTERRUPT_STATUS, val: 0xffffffff);
662
663 /* Turn off the relevant clocks */
664 clk_disable(clk: video->eclk);
665 clk_disable(clk: video->vclk);
666
667 clear_bit(nr: VIDEO_CLOCKS_ON, addr: &video->flags);
668}
669
670static void aspeed_video_on(struct aspeed_video *video)
671{
672 if (test_bit(VIDEO_CLOCKS_ON, &video->flags))
673 return;
674
675 /* Turn on the relevant clocks */
676 clk_enable(clk: video->vclk);
677 clk_enable(clk: video->eclk);
678
679 set_bit(nr: VIDEO_CLOCKS_ON, addr: &video->flags);
680}
681
682static void aspeed_video_bufs_done(struct aspeed_video *video,
683 enum vb2_buffer_state state)
684{
685 unsigned long flags;
686 struct aspeed_video_buffer *buf;
687
688 spin_lock_irqsave(&video->lock, flags);
689 list_for_each_entry(buf, &video->buffers, link)
690 vb2_buffer_done(vb: &buf->vb.vb2_buf, state);
691 INIT_LIST_HEAD(list: &video->buffers);
692 spin_unlock_irqrestore(lock: &video->lock, flags);
693}
694
695static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
696{
697 v4l2_dbg(1, debug, &video->v4l2_dev, "Resolution changed; resetting\n");
698
699 set_bit(nr: VIDEO_RES_CHANGE, addr: &video->flags);
700 clear_bit(nr: VIDEO_FRAME_INPRG, addr: &video->flags);
701
702 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
703
704 aspeed_video_off(video);
705 aspeed_video_bufs_done(video, state: VB2_BUF_STATE_ERROR);
706
707 schedule_delayed_work(dwork: &video->res_work, delay);
708}
709
710static void aspeed_video_swap_src_buf(struct aspeed_video *v)
711{
712 if (v->format == VIDEO_FMT_STANDARD)
713 return;
714
715 /* Reset bcd buffer to have a full frame update every 8 frames. */
716 if (IS_ALIGNED(v->sequence, 8))
717 memset((u8 *)v->bcd.virt, 0x00, VE_BCD_BUFF_SIZE);
718
719 if (v->sequence & 0x01) {
720 aspeed_video_write(video: v, VE_SRC0_ADDR, val: v->srcs[1].dma);
721 aspeed_video_write(video: v, VE_SRC1_ADDR, val: v->srcs[0].dma);
722 } else {
723 aspeed_video_write(video: v, VE_SRC0_ADDR, val: v->srcs[0].dma);
724 aspeed_video_write(video: v, VE_SRC1_ADDR, val: v->srcs[1].dma);
725 }
726}
727
728static irqreturn_t aspeed_video_irq(int irq, void *arg)
729{
730 struct aspeed_video *video = arg;
731 u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
732
733 /*
734 * Hardware sometimes asserts interrupts that we haven't actually
735 * enabled; ignore them if so.
736 */
737 sts &= aspeed_video_read(video, VE_INTERRUPT_CTRL);
738
739 v4l2_dbg(2, debug, &video->v4l2_dev, "irq sts=%#x %s%s%s%s\n", sts,
740 sts & VE_INTERRUPT_MODE_DETECT_WD ? ", unlock" : "",
741 sts & VE_INTERRUPT_MODE_DETECT ? ", lock" : "",
742 sts & VE_INTERRUPT_CAPTURE_COMPLETE ? ", capture-done" : "",
743 sts & VE_INTERRUPT_COMP_COMPLETE ? ", comp-done" : "");
744
745 /*
746 * Resolution changed or signal was lost; reset the engine and
747 * re-initialize
748 */
749 if (sts & VE_INTERRUPT_MODE_DETECT_WD) {
750 aspeed_video_irq_res_change(video, delay: 0);
751 return IRQ_HANDLED;
752 }
753
754 if (sts & VE_INTERRUPT_MODE_DETECT) {
755 if (test_bit(VIDEO_RES_DETECT, &video->flags)) {
756 aspeed_video_update(video, VE_INTERRUPT_CTRL,
757 VE_INTERRUPT_MODE_DETECT, bits: 0);
758 aspeed_video_write(video, VE_INTERRUPT_STATUS,
759 VE_INTERRUPT_MODE_DETECT);
760 sts &= ~VE_INTERRUPT_MODE_DETECT;
761 set_bit(nr: VIDEO_MODE_DETECT_DONE, addr: &video->flags);
762 wake_up_interruptible_all(&video->wait);
763 } else {
764 /*
765 * Signal acquired while NOT doing resolution
766 * detection; reset the engine and re-initialize
767 */
768 aspeed_video_irq_res_change(video,
769 RESOLUTION_CHANGE_DELAY);
770 return IRQ_HANDLED;
771 }
772 }
773
774 if (sts & VE_INTERRUPT_COMP_COMPLETE) {
775 struct aspeed_video_buffer *buf;
776 bool empty = true;
777 u32 frame_size = aspeed_video_read(video,
778 reg: video->comp_size_read);
779
780 update_perf(p: &video->perf);
781
782 spin_lock(lock: &video->lock);
783 clear_bit(nr: VIDEO_FRAME_INPRG, addr: &video->flags);
784 buf = list_first_entry_or_null(&video->buffers,
785 struct aspeed_video_buffer,
786 link);
787 if (buf) {
788 vb2_set_plane_payload(vb: &buf->vb.vb2_buf, plane_no: 0, size: frame_size);
789
790 /*
791 * aspeed_jpeg requires continuous update.
792 * On the contrary, standard jpeg can keep last buffer
793 * to always have the latest result.
794 */
795 if (video->format == VIDEO_FMT_STANDARD &&
796 list_is_last(list: &buf->link, head: &video->buffers)) {
797 empty = false;
798 v4l2_dbg(1, debug, &video->v4l2_dev, "skip to keep last frame updated\n");
799 } else {
800 buf->vb.vb2_buf.timestamp = ktime_get_ns();
801 buf->vb.sequence = video->sequence++;
802 buf->vb.field = V4L2_FIELD_NONE;
803 vb2_buffer_done(vb: &buf->vb.vb2_buf,
804 state: VB2_BUF_STATE_DONE);
805 list_del(entry: &buf->link);
806 empty = list_empty(head: &video->buffers);
807 }
808 }
809 spin_unlock(lock: &video->lock);
810
811 aspeed_video_update(video, VE_SEQ_CTRL,
812 VE_SEQ_CTRL_TRIG_CAPTURE |
813 VE_SEQ_CTRL_FORCE_IDLE |
814 VE_SEQ_CTRL_TRIG_COMP, bits: 0);
815 aspeed_video_update(video, VE_INTERRUPT_CTRL,
816 VE_INTERRUPT_COMP_COMPLETE, bits: 0);
817 aspeed_video_write(video, VE_INTERRUPT_STATUS,
818 VE_INTERRUPT_COMP_COMPLETE);
819 sts &= ~VE_INTERRUPT_COMP_COMPLETE;
820
821 aspeed_video_swap_src_buf(v: video);
822
823 if (test_bit(VIDEO_STREAMING, &video->flags) && !empty)
824 aspeed_video_start_frame(video);
825 }
826
827 return sts ? IRQ_NONE : IRQ_HANDLED;
828}
829
830static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
831{
832 int i;
833 int hsync_counter = 0;
834 int vsync_counter = 0;
835 u32 sts, ctrl;
836
837 for (i = 0; i < NUM_POLARITY_CHECKS; ++i) {
838 sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
839 if (sts & VE_MODE_DETECT_STATUS_VSYNC)
840 vsync_counter--;
841 else
842 vsync_counter++;
843
844 if (sts & VE_MODE_DETECT_STATUS_HSYNC)
845 hsync_counter--;
846 else
847 hsync_counter++;
848 }
849
850 ctrl = aspeed_video_read(video, VE_CTRL);
851
852 if (hsync_counter < 0) {
853 ctrl |= VE_CTRL_HSYNC_POL;
854 video->detected_timings.polarities &=
855 ~V4L2_DV_HSYNC_POS_POL;
856 } else {
857 ctrl &= ~VE_CTRL_HSYNC_POL;
858 video->detected_timings.polarities |=
859 V4L2_DV_HSYNC_POS_POL;
860 }
861
862 if (vsync_counter < 0) {
863 ctrl |= VE_CTRL_VSYNC_POL;
864 video->detected_timings.polarities &=
865 ~V4L2_DV_VSYNC_POS_POL;
866 } else {
867 ctrl &= ~VE_CTRL_VSYNC_POL;
868 video->detected_timings.polarities |=
869 V4L2_DV_VSYNC_POS_POL;
870 }
871
872 aspeed_video_write(video, VE_CTRL, val: ctrl);
873}
874
875static bool aspeed_video_alloc_buf(struct aspeed_video *video,
876 struct aspeed_video_addr *addr,
877 unsigned int size)
878{
879 addr->virt = dma_alloc_coherent(dev: video->dev, size, dma_handle: &addr->dma,
880 GFP_KERNEL);
881 if (!addr->virt)
882 return false;
883
884 addr->size = size;
885 return true;
886}
887
888static void aspeed_video_free_buf(struct aspeed_video *video,
889 struct aspeed_video_addr *addr)
890{
891 dma_free_coherent(dev: video->dev, size: addr->size, cpu_addr: addr->virt, dma_handle: addr->dma);
892 addr->size = 0;
893 addr->dma = 0ULL;
894 addr->virt = NULL;
895}
896
897/*
898 * Get the minimum HW-supported compression buffer size for the frame size.
899 * Assume worst-case JPEG compression size is 1/8 raw size. This should be
900 * plenty even for maximum quality; any worse and the engine will simply return
901 * incomplete JPEGs.
902 */
903static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
904 unsigned int frame_size)
905{
906 int i, j;
907 u32 compression_buffer_size_reg = 0;
908 unsigned int size;
909 const unsigned int num_compression_packets = 4;
910 const unsigned int compression_packet_size = 1024;
911 const unsigned int max_compressed_size = frame_size / 2; /* 4bpp / 8 */
912
913 video->max_compressed_size = UINT_MAX;
914
915 for (i = 0; i < 6; ++i) {
916 for (j = 0; j < 8; ++j) {
917 size = (num_compression_packets << i) *
918 (compression_packet_size << j);
919 if (size < max_compressed_size)
920 continue;
921
922 if (size < video->max_compressed_size) {
923 compression_buffer_size_reg = (i << 3) | j;
924 video->max_compressed_size = size;
925 }
926 }
927 }
928
929 aspeed_video_write(video, VE_STREAM_BUF_SIZE,
930 val: compression_buffer_size_reg);
931
932 v4l2_dbg(1, debug, &video->v4l2_dev, "Max compressed size: %#x\n",
933 video->max_compressed_size);
934}
935
936/*
937 * Update v4l2_bt_timings per current status.
938 * frame_top/frame_bottom/frame_left/frame_right need to be ready.
939 *
940 * The following registers start counting from sync's rising edge:
941 * 1. VR090: frame edge's left and right
942 * 2. VR094: frame edge's top and bottom
943 * 3. VR09C: counting from sync's rising edge to falling edge
944 *
945 * [Vertical timing]
946 * +--+ +-------------------+ +--+
947 * | | | v i d e o | | |
948 * +--+ +-----+ +-----+ +---+
949 * vsync+--+
950 * frame_top+--------+
951 * frame_bottom+----------------------------+
952 *
953 * +-------------------+
954 * | v i d e o |
955 * +--+ +-----+ +-----+ +---+
956 * | | | |
957 * +--+ +--+
958 * vsync+-------------------------------+
959 * frame_top+-----+
960 * frame_bottom+-------------------------+
961 *
962 * [Horizontal timing]
963 * +--+ +-------------------+ +--+
964 * | | | v i d e o | | |
965 * +--+ +-----+ +-----+ +---+
966 * hsync+--+
967 * frame_left+--------+
968 * frame_right+----------------------------+
969 *
970 * +-------------------+
971 * | v i d e o |
972 * +--+ +-----+ +-----+ +---+
973 * | | | |
974 * +--+ +--+
975 * hsync+-------------------------------+
976 * frame_left+-----+
977 * frame_right+-------------------------+
978 *
979 * @v: the struct of aspeed_video
980 * @det: v4l2_bt_timings to be updated.
981 */
982static void aspeed_video_get_timings(struct aspeed_video *v,
983 struct v4l2_bt_timings *det)
984{
985 u32 mds, sync, htotal, vtotal, vsync, hsync;
986
987 mds = aspeed_video_read(video: v, VE_MODE_DETECT_STATUS);
988 sync = aspeed_video_read(video: v, VE_SYNC_STATUS);
989 htotal = aspeed_video_read(video: v, VE_H_TOTAL_PIXELS);
990 vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
991 vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
992 hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
993
994 /*
995 * This is a workaround for polarity detection.
996 * Because ast-soc counts sync from sync's rising edge, the reg value
997 * of sync would be larger than video's active area if negative.
998 */
999 if (vsync > det->height)
1000 det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
1001 else
1002 det->polarities |= V4L2_DV_VSYNC_POS_POL;
1003 if (hsync > det->width)
1004 det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
1005 else
1006 det->polarities |= V4L2_DV_HSYNC_POS_POL;
1007
1008 if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
1009 det->vbackporch = v->frame_top - vsync;
1010 det->vfrontporch = vtotal - v->frame_bottom;
1011 det->vsync = vsync;
1012 } else {
1013 det->vbackporch = v->frame_top;
1014 det->vfrontporch = vsync - v->frame_bottom;
1015 det->vsync = vtotal - vsync;
1016 }
1017
1018 if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
1019 det->hbackporch = v->frame_left - hsync;
1020 det->hfrontporch = htotal - v->frame_right;
1021 det->hsync = hsync;
1022 } else {
1023 det->hbackporch = v->frame_left;
1024 det->hfrontporch = hsync - v->frame_right;
1025 det->hsync = htotal - hsync;
1026 }
1027}
1028
1029#define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
1030
1031static void aspeed_video_get_resolution(struct aspeed_video *video)
1032{
1033 bool invalid_resolution = true;
1034 int rc;
1035 int tries = 0;
1036 u32 mds;
1037 u32 src_lr_edge;
1038 u32 src_tb_edge;
1039 struct v4l2_bt_timings *det = &video->detected_timings;
1040
1041 det->width = MIN_WIDTH;
1042 det->height = MIN_HEIGHT;
1043 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1044 memset(&video->perf, 0, sizeof(video->perf));
1045
1046 do {
1047 if (tries) {
1048 set_current_state(TASK_INTERRUPTIBLE);
1049 if (schedule_timeout(INVALID_RESOLUTION_DELAY))
1050 return;
1051 }
1052
1053 set_bit(nr: VIDEO_RES_DETECT, addr: &video->flags);
1054 aspeed_video_update(video, VE_CTRL,
1055 VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, bits: 0);
1056 aspeed_video_enable_mode_detect(video);
1057
1058 rc = wait_event_interruptible_timeout(video->wait,
1059 res_check(video),
1060 MODE_DETECT_TIMEOUT);
1061 if (!rc) {
1062 v4l2_dbg(1, debug, &video->v4l2_dev, "Timed out; first mode detect\n");
1063 clear_bit(nr: VIDEO_RES_DETECT, addr: &video->flags);
1064 return;
1065 }
1066
1067 mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
1068 // try detection again if current signal isn't stable
1069 if (!(mds & VE_MODE_DETECT_H_STABLE) ||
1070 !(mds & VE_MODE_DETECT_V_STABLE) ||
1071 (mds & VE_MODE_DETECT_EXTSRC_ADC))
1072 continue;
1073
1074 aspeed_video_check_and_set_polarity(video);
1075
1076 aspeed_video_enable_mode_detect(video);
1077
1078 rc = wait_event_interruptible_timeout(video->wait,
1079 res_check(video),
1080 MODE_DETECT_TIMEOUT);
1081 clear_bit(nr: VIDEO_RES_DETECT, addr: &video->flags);
1082 if (!rc) {
1083 v4l2_dbg(1, debug, &video->v4l2_dev, "Timed out; second mode detect\n");
1084 return;
1085 }
1086
1087 src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
1088 src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
1089
1090 video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
1091 video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
1092
1093 if (video->frame_top > video->frame_bottom)
1094 continue;
1095
1096 video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
1097 video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
1098
1099 if (video->frame_left > video->frame_right)
1100 continue;
1101
1102 invalid_resolution = false;
1103 } while (invalid_resolution && (tries++ < INVALID_RESOLUTION_RETRIES));
1104
1105 if (invalid_resolution) {
1106 v4l2_dbg(1, debug, &video->v4l2_dev, "Invalid resolution detected\n");
1107 return;
1108 }
1109
1110 det->height = (video->frame_bottom - video->frame_top) + 1;
1111 det->width = (video->frame_right - video->frame_left) + 1;
1112 video->v4l2_input_status = 0;
1113
1114 aspeed_video_get_timings(v: video, det);
1115
1116 /*
1117 * Enable mode-detect watchdog, resolution-change watchdog and
1118 * automatic compression after frame capture.
1119 */
1120 aspeed_video_update(video, VE_INTERRUPT_CTRL, clear: 0,
1121 VE_INTERRUPT_MODE_DETECT_WD);
1122 aspeed_video_update(video, VE_SEQ_CTRL, clear: 0,
1123 VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
1124
1125 v4l2_dbg(1, debug, &video->v4l2_dev, "Got resolution: %dx%d\n",
1126 det->width, det->height);
1127}
1128
1129static void aspeed_video_set_resolution(struct aspeed_video *video)
1130{
1131 struct v4l2_bt_timings *act = &video->active_timings;
1132 unsigned int size = act->width * ALIGN(act->height, 8);
1133
1134 /* Set capture/compression frame sizes */
1135 aspeed_video_calc_compressed_size(video, frame_size: size);
1136
1137 if (!IS_ALIGNED(act->width, 64)) {
1138 /*
1139 * This is a workaround to fix a AST2500 silicon bug on A1 and
1140 * A2 revisions. Since it doesn't break capturing operation of
1141 * other revisions, use it for all revisions without checking
1142 * the revision ID. It picked new width which is a very next
1143 * 64-pixels aligned value to minimize memory bandwidth
1144 * and to get better access speed from video engine.
1145 */
1146 u32 width = ALIGN(act->width, 64);
1147
1148 aspeed_video_write(video, VE_CAP_WINDOW, val: width << 16 | act->height);
1149 size = width * ALIGN(act->height, 8);
1150 } else {
1151 aspeed_video_write(video, VE_CAP_WINDOW,
1152 val: act->width << 16 | act->height);
1153 }
1154 aspeed_video_write(video, VE_COMP_WINDOW,
1155 val: act->width << 16 | act->height);
1156 aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, val: act->width * 4);
1157
1158 /* Don't use direct mode below 1024 x 768 (irqs don't fire) */
1159 if (size < DIRECT_FETCH_THRESHOLD) {
1160 v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Sync Mode\n");
1161 aspeed_video_write(video, VE_TGS_0,
1162 FIELD_PREP(VE_TGS_FIRST,
1163 video->frame_left - 1) |
1164 FIELD_PREP(VE_TGS_LAST,
1165 video->frame_right));
1166 aspeed_video_write(video, VE_TGS_1,
1167 FIELD_PREP(VE_TGS_FIRST, video->frame_top) |
1168 FIELD_PREP(VE_TGS_LAST,
1169 video->frame_bottom + 1));
1170 aspeed_video_update(video, VE_CTRL,
1171 VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH,
1172 VE_CTRL_INT_DE);
1173 } else {
1174 v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Direct Mode\n");
1175 aspeed_video_update(video, VE_CTRL,
1176 VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH,
1177 VE_CTRL_DIRECT_FETCH);
1178 }
1179
1180 size *= 4;
1181
1182 if (size != video->srcs[0].size) {
1183 if (video->srcs[0].size)
1184 aspeed_video_free_buf(video, addr: &video->srcs[0]);
1185 if (video->srcs[1].size)
1186 aspeed_video_free_buf(video, addr: &video->srcs[1]);
1187
1188 if (!aspeed_video_alloc_buf(video, addr: &video->srcs[0], size))
1189 goto err_mem;
1190 if (!aspeed_video_alloc_buf(video, addr: &video->srcs[1], size))
1191 goto err_mem;
1192
1193 v4l2_dbg(1, debug, &video->v4l2_dev, "src buf0 addr(%pad) size(%d)\n",
1194 &video->srcs[0].dma, video->srcs[0].size);
1195 v4l2_dbg(1, debug, &video->v4l2_dev, "src buf1 addr(%pad) size(%d)\n",
1196 &video->srcs[1].dma, video->srcs[1].size);
1197 aspeed_video_write(video, VE_SRC0_ADDR, val: video->srcs[0].dma);
1198 aspeed_video_write(video, VE_SRC1_ADDR, val: video->srcs[1].dma);
1199 }
1200
1201 return;
1202
1203err_mem:
1204 dev_err(video->dev, "Failed to allocate source buffers\n");
1205
1206 if (video->srcs[0].size)
1207 aspeed_video_free_buf(video, addr: &video->srcs[0]);
1208}
1209
1210static void aspeed_video_update_regs(struct aspeed_video *video)
1211{
1212 u8 jpeg_hq_quality = clamp((int)video->jpeg_hq_quality - 1, 0,
1213 ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1);
1214 u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
1215 FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10) |
1216 FIELD_PREP(VE_COMP_CTRL_EN_HQ, video->hq_mode) |
1217 FIELD_PREP(VE_COMP_CTRL_HQ_DCT_LUM, jpeg_hq_quality) |
1218 FIELD_PREP(VE_COMP_CTRL_HQ_DCT_CHR, jpeg_hq_quality | 0x10);
1219 u32 ctrl = 0;
1220 u32 seq_ctrl = 0;
1221
1222 v4l2_dbg(1, debug, &video->v4l2_dev, "framerate(%d)\n",
1223 video->frame_rate);
1224 v4l2_dbg(1, debug, &video->v4l2_dev, "jpeg format(%s) subsample(%s)\n",
1225 format_str[video->format],
1226 video->yuv420 ? "420" : "444");
1227 v4l2_dbg(1, debug, &video->v4l2_dev, "compression quality(%d)\n",
1228 video->jpeg_quality);
1229 v4l2_dbg(1, debug, &video->v4l2_dev, "hq_mode(%s) hq_quality(%d)\n",
1230 video->hq_mode ? "on" : "off", video->jpeg_hq_quality);
1231
1232 if (video->format == VIDEO_FMT_ASPEED)
1233 aspeed_video_update(video, VE_BCD_CTRL, clear: 0, VE_BCD_CTRL_EN_BCD);
1234 else
1235 aspeed_video_update(video, VE_BCD_CTRL, VE_BCD_CTRL_EN_BCD, bits: 0);
1236
1237 if (video->frame_rate)
1238 ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
1239
1240 if (video->format == VIDEO_FMT_STANDARD) {
1241 comp_ctrl &= ~FIELD_PREP(VE_COMP_CTRL_EN_HQ, video->hq_mode);
1242 seq_ctrl |= video->jpeg_mode;
1243 }
1244
1245 if (video->yuv420)
1246 seq_ctrl |= VE_SEQ_CTRL_YUV420;
1247
1248 if (video->jpeg.virt)
1249 aspeed_video_update_jpeg_table(table: video->jpeg.virt, yuv420: video->yuv420);
1250
1251 /* Set control registers */
1252 aspeed_video_update(video, VE_SEQ_CTRL,
1253 clear: video->jpeg_mode | VE_SEQ_CTRL_YUV420,
1254 bits: seq_ctrl);
1255 aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC, bits: ctrl);
1256 aspeed_video_update(video, VE_COMP_CTRL,
1257 VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR |
1258 VE_COMP_CTRL_EN_HQ | VE_COMP_CTRL_HQ_DCT_LUM |
1259 VE_COMP_CTRL_HQ_DCT_CHR | VE_COMP_CTRL_VQ_4COLOR |
1260 VE_COMP_CTRL_VQ_DCT_ONLY,
1261 bits: comp_ctrl);
1262}
1263
1264static void aspeed_video_init_regs(struct aspeed_video *video)
1265{
1266 u32 ctrl = VE_CTRL_AUTO_OR_CURSOR |
1267 FIELD_PREP(VE_CTRL_CAPTURE_FMT, VIDEO_CAP_FMT_YUV_FULL_SWING);
1268
1269 /* Unlock VE registers */
1270 aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
1271
1272 /* Disable interrupts */
1273 aspeed_video_write(video, VE_INTERRUPT_CTRL, val: 0);
1274 aspeed_video_write(video, VE_INTERRUPT_STATUS, val: 0xffffffff);
1275
1276 /* Clear the offset */
1277 aspeed_video_write(video, VE_COMP_PROC_OFFSET, val: 0);
1278 aspeed_video_write(video, VE_COMP_OFFSET, val: 0);
1279
1280 aspeed_video_write(video, VE_JPEG_ADDR, val: video->jpeg.dma);
1281
1282 /* Set control registers */
1283 aspeed_video_write(video, VE_CTRL, val: ctrl);
1284 aspeed_video_write(video, VE_COMP_CTRL, VE_COMP_CTRL_RSVD);
1285
1286 /* Don't downscale */
1287 aspeed_video_write(video, VE_SCALING_FACTOR, val: 0x10001000);
1288 aspeed_video_write(video, VE_SCALING_FILTER0, val: 0x00200000);
1289 aspeed_video_write(video, VE_SCALING_FILTER1, val: 0x00200000);
1290 aspeed_video_write(video, VE_SCALING_FILTER2, val: 0x00200000);
1291 aspeed_video_write(video, VE_SCALING_FILTER3, val: 0x00200000);
1292
1293 /* Set mode detection defaults */
1294 aspeed_video_write(video, VE_MODE_DETECT,
1295 FIELD_PREP(VE_MODE_DT_HOR_TOLER, 2) |
1296 FIELD_PREP(VE_MODE_DT_VER_TOLER, 2) |
1297 FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) |
1298 FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) |
1299 FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65));
1300
1301 aspeed_video_write(video, VE_BCD_CTRL, val: 0);
1302}
1303
1304static void aspeed_video_start(struct aspeed_video *video)
1305{
1306 aspeed_video_on(video);
1307
1308 aspeed_video_init_regs(video);
1309
1310 /* Resolution set to 640x480 if no signal found */
1311 aspeed_video_get_resolution(video);
1312
1313 /* Set timings since the device is being opened for the first time */
1314 video->active_timings = video->detected_timings;
1315 aspeed_video_set_resolution(video);
1316
1317 video->pix_fmt.width = video->active_timings.width;
1318 video->pix_fmt.height = video->active_timings.height;
1319 video->pix_fmt.sizeimage = video->max_compressed_size;
1320}
1321
1322static void aspeed_video_stop(struct aspeed_video *video)
1323{
1324 set_bit(nr: VIDEO_STOPPED, addr: &video->flags);
1325 cancel_delayed_work_sync(dwork: &video->res_work);
1326
1327 aspeed_video_off(video);
1328
1329 if (video->srcs[0].size)
1330 aspeed_video_free_buf(video, addr: &video->srcs[0]);
1331
1332 if (video->srcs[1].size)
1333 aspeed_video_free_buf(video, addr: &video->srcs[1]);
1334
1335 if (video->bcd.size)
1336 aspeed_video_free_buf(video, addr: &video->bcd);
1337
1338 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1339 video->flags = 0;
1340}
1341
1342static int aspeed_video_querycap(struct file *file, void *fh,
1343 struct v4l2_capability *cap)
1344{
1345 strscpy(cap->driver, DEVICE_NAME, sizeof(cap->driver));
1346 strscpy(cap->card, "Aspeed Video Engine", sizeof(cap->card));
1347 snprintf(buf: cap->bus_info, size: sizeof(cap->bus_info), fmt: "platform:%s",
1348 DEVICE_NAME);
1349
1350 return 0;
1351}
1352
1353static int aspeed_video_enum_format(struct file *file, void *fh,
1354 struct v4l2_fmtdesc *f)
1355{
1356 struct aspeed_video *video = video_drvdata(file);
1357
1358 if (f->index)
1359 return -EINVAL;
1360
1361 f->pixelformat = video->pix_fmt.pixelformat;
1362
1363 return 0;
1364}
1365
1366static int aspeed_video_get_format(struct file *file, void *fh,
1367 struct v4l2_format *f)
1368{
1369 struct aspeed_video *video = video_drvdata(file);
1370
1371 f->fmt.pix = video->pix_fmt;
1372
1373 return 0;
1374}
1375
1376static int aspeed_video_set_format(struct file *file, void *fh,
1377 struct v4l2_format *f)
1378{
1379 struct aspeed_video *video = video_drvdata(file);
1380
1381 if (vb2_is_busy(q: &video->queue))
1382 return -EBUSY;
1383
1384 switch (f->fmt.pix.pixelformat) {
1385 case V4L2_PIX_FMT_JPEG:
1386 video->format = VIDEO_FMT_STANDARD;
1387 break;
1388 case V4L2_PIX_FMT_AJPG:
1389 video->format = VIDEO_FMT_ASPEED;
1390 break;
1391 default:
1392 return -EINVAL;
1393 }
1394 video->pix_fmt.pixelformat = f->fmt.pix.pixelformat;
1395
1396 return 0;
1397}
1398
1399static int aspeed_video_enum_input(struct file *file, void *fh,
1400 struct v4l2_input *inp)
1401{
1402 struct aspeed_video *video = video_drvdata(file);
1403
1404 if (inp->index)
1405 return -EINVAL;
1406
1407 strscpy(inp->name, "Host VGA capture", sizeof(inp->name));
1408 inp->type = V4L2_INPUT_TYPE_CAMERA;
1409 inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
1410 inp->status = video->v4l2_input_status;
1411
1412 return 0;
1413}
1414
1415static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
1416{
1417 *i = 0;
1418
1419 return 0;
1420}
1421
1422static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
1423{
1424 if (i)
1425 return -EINVAL;
1426
1427 return 0;
1428}
1429
1430static int aspeed_video_get_parm(struct file *file, void *fh,
1431 struct v4l2_streamparm *a)
1432{
1433 struct aspeed_video *video = video_drvdata(file);
1434
1435 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1436 a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1437 a->parm.capture.timeperframe.numerator = 1;
1438 if (!video->frame_rate)
1439 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1440 else
1441 a->parm.capture.timeperframe.denominator = video->frame_rate;
1442
1443 return 0;
1444}
1445
1446static int aspeed_video_set_parm(struct file *file, void *fh,
1447 struct v4l2_streamparm *a)
1448{
1449 unsigned int frame_rate = 0;
1450 struct aspeed_video *video = video_drvdata(file);
1451
1452 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1453 a->parm.capture.readbuffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
1454
1455 if (a->parm.capture.timeperframe.numerator)
1456 frame_rate = a->parm.capture.timeperframe.denominator /
1457 a->parm.capture.timeperframe.numerator;
1458
1459 if (!frame_rate || frame_rate > MAX_FRAME_RATE) {
1460 frame_rate = 0;
1461 a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1462 a->parm.capture.timeperframe.numerator = 1;
1463 }
1464
1465 if (video->frame_rate != frame_rate) {
1466 video->frame_rate = frame_rate;
1467 aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC,
1468 FIELD_PREP(VE_CTRL_FRC, frame_rate));
1469 }
1470
1471 return 0;
1472}
1473
1474static int aspeed_video_enum_framesizes(struct file *file, void *fh,
1475 struct v4l2_frmsizeenum *fsize)
1476{
1477 struct aspeed_video *video = video_drvdata(file);
1478
1479 if (fsize->index)
1480 return -EINVAL;
1481
1482 if (fsize->pixel_format != V4L2_PIX_FMT_JPEG)
1483 return -EINVAL;
1484
1485 fsize->discrete.width = video->pix_fmt.width;
1486 fsize->discrete.height = video->pix_fmt.height;
1487 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1488
1489 return 0;
1490}
1491
1492static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
1493 struct v4l2_frmivalenum *fival)
1494{
1495 struct aspeed_video *video = video_drvdata(file);
1496
1497 if (fival->index)
1498 return -EINVAL;
1499
1500 if (fival->width != video->detected_timings.width ||
1501 fival->height != video->detected_timings.height)
1502 return -EINVAL;
1503
1504 if (fival->pixel_format != V4L2_PIX_FMT_JPEG)
1505 return -EINVAL;
1506
1507 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1508
1509 fival->stepwise.min.denominator = MAX_FRAME_RATE;
1510 fival->stepwise.min.numerator = 1;
1511 fival->stepwise.max.denominator = 1;
1512 fival->stepwise.max.numerator = 1;
1513 fival->stepwise.step = fival->stepwise.max;
1514
1515 return 0;
1516}
1517
1518static int aspeed_video_set_dv_timings(struct file *file, void *fh,
1519 struct v4l2_dv_timings *timings)
1520{
1521 struct aspeed_video *video = video_drvdata(file);
1522
1523 if (timings->bt.width == video->active_timings.width &&
1524 timings->bt.height == video->active_timings.height)
1525 return 0;
1526
1527 if (vb2_is_busy(q: &video->queue))
1528 return -EBUSY;
1529
1530 video->active_timings = timings->bt;
1531
1532 aspeed_video_set_resolution(video);
1533
1534 video->pix_fmt.width = timings->bt.width;
1535 video->pix_fmt.height = timings->bt.height;
1536 video->pix_fmt.sizeimage = video->max_compressed_size;
1537
1538 timings->type = V4L2_DV_BT_656_1120;
1539
1540 v4l2_dbg(1, debug, &video->v4l2_dev, "set new timings(%dx%d)\n",
1541 timings->bt.width, timings->bt.height);
1542
1543 return 0;
1544}
1545
1546static int aspeed_video_get_dv_timings(struct file *file, void *fh,
1547 struct v4l2_dv_timings *timings)
1548{
1549 struct aspeed_video *video = video_drvdata(file);
1550
1551 timings->type = V4L2_DV_BT_656_1120;
1552 timings->bt = video->active_timings;
1553
1554 return 0;
1555}
1556
1557static int aspeed_video_query_dv_timings(struct file *file, void *fh,
1558 struct v4l2_dv_timings *timings)
1559{
1560 int rc;
1561 struct aspeed_video *video = video_drvdata(file);
1562
1563 /*
1564 * This blocks only if the driver is currently in the process of
1565 * detecting a new resolution; in the event of no signal or timeout
1566 * this function is woken up.
1567 */
1568 if (file->f_flags & O_NONBLOCK) {
1569 if (test_bit(VIDEO_RES_CHANGE, &video->flags))
1570 return -EAGAIN;
1571 } else {
1572 rc = wait_event_interruptible(video->wait,
1573 !test_bit(VIDEO_RES_CHANGE,
1574 &video->flags));
1575 if (rc)
1576 return -EINTR;
1577 }
1578
1579 timings->type = V4L2_DV_BT_656_1120;
1580 timings->bt = video->detected_timings;
1581
1582 return video->v4l2_input_status ? -ENOLINK : 0;
1583}
1584
1585static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
1586 struct v4l2_enum_dv_timings *timings)
1587{
1588 return v4l2_enum_dv_timings_cap(t: timings, cap: &aspeed_video_timings_cap,
1589 NULL, NULL);
1590}
1591
1592static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
1593 struct v4l2_dv_timings_cap *cap)
1594{
1595 *cap = aspeed_video_timings_cap;
1596
1597 return 0;
1598}
1599
1600static int aspeed_video_sub_event(struct v4l2_fh *fh,
1601 const struct v4l2_event_subscription *sub)
1602{
1603 switch (sub->type) {
1604 case V4L2_EVENT_SOURCE_CHANGE:
1605 return v4l2_src_change_event_subscribe(fh, sub);
1606 }
1607
1608 return v4l2_ctrl_subscribe_event(fh, sub);
1609}
1610
1611static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = {
1612 .vidioc_querycap = aspeed_video_querycap,
1613
1614 .vidioc_enum_fmt_vid_cap = aspeed_video_enum_format,
1615 .vidioc_g_fmt_vid_cap = aspeed_video_get_format,
1616 .vidioc_s_fmt_vid_cap = aspeed_video_set_format,
1617 .vidioc_try_fmt_vid_cap = aspeed_video_get_format,
1618
1619 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1620 .vidioc_querybuf = vb2_ioctl_querybuf,
1621 .vidioc_qbuf = vb2_ioctl_qbuf,
1622 .vidioc_expbuf = vb2_ioctl_expbuf,
1623 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1624 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1625 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1626 .vidioc_streamon = vb2_ioctl_streamon,
1627 .vidioc_streamoff = vb2_ioctl_streamoff,
1628
1629 .vidioc_enum_input = aspeed_video_enum_input,
1630 .vidioc_g_input = aspeed_video_get_input,
1631 .vidioc_s_input = aspeed_video_set_input,
1632
1633 .vidioc_g_parm = aspeed_video_get_parm,
1634 .vidioc_s_parm = aspeed_video_set_parm,
1635 .vidioc_enum_framesizes = aspeed_video_enum_framesizes,
1636 .vidioc_enum_frameintervals = aspeed_video_enum_frameintervals,
1637
1638 .vidioc_s_dv_timings = aspeed_video_set_dv_timings,
1639 .vidioc_g_dv_timings = aspeed_video_get_dv_timings,
1640 .vidioc_query_dv_timings = aspeed_video_query_dv_timings,
1641 .vidioc_enum_dv_timings = aspeed_video_enum_dv_timings,
1642 .vidioc_dv_timings_cap = aspeed_video_dv_timings_cap,
1643
1644 .vidioc_subscribe_event = aspeed_video_sub_event,
1645 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1646};
1647
1648static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
1649{
1650 struct aspeed_video *video = container_of(ctrl->handler,
1651 struct aspeed_video,
1652 ctrl_handler);
1653
1654 switch (ctrl->id) {
1655 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1656 video->jpeg_quality = ctrl->val;
1657 if (test_bit(VIDEO_STREAMING, &video->flags))
1658 aspeed_video_update_regs(video);
1659 break;
1660 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1661 video->yuv420 = (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420);
1662 if (test_bit(VIDEO_STREAMING, &video->flags))
1663 aspeed_video_update_regs(video);
1664 break;
1665 case V4L2_CID_ASPEED_HQ_MODE:
1666 video->hq_mode = ctrl->val;
1667 if (test_bit(VIDEO_STREAMING, &video->flags))
1668 aspeed_video_update_regs(video);
1669 break;
1670 case V4L2_CID_ASPEED_HQ_JPEG_QUALITY:
1671 video->jpeg_hq_quality = ctrl->val;
1672 if (test_bit(VIDEO_STREAMING, &video->flags))
1673 aspeed_video_update_regs(video);
1674 break;
1675 default:
1676 return -EINVAL;
1677 }
1678
1679 return 0;
1680}
1681
1682static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
1683 .s_ctrl = aspeed_video_set_ctrl,
1684};
1685
1686static const struct v4l2_ctrl_config aspeed_ctrl_HQ_mode = {
1687 .ops = &aspeed_video_ctrl_ops,
1688 .id = V4L2_CID_ASPEED_HQ_MODE,
1689 .name = "Aspeed HQ Mode",
1690 .type = V4L2_CTRL_TYPE_BOOLEAN,
1691 .min = false,
1692 .max = true,
1693 .step = 1,
1694 .def = false,
1695};
1696
1697static const struct v4l2_ctrl_config aspeed_ctrl_HQ_jpeg_quality = {
1698 .ops = &aspeed_video_ctrl_ops,
1699 .id = V4L2_CID_ASPEED_HQ_JPEG_QUALITY,
1700 .name = "Aspeed HQ Quality",
1701 .type = V4L2_CTRL_TYPE_INTEGER,
1702 .min = 1,
1703 .max = ASPEED_VIDEO_JPEG_NUM_QUALITIES,
1704 .step = 1,
1705 .def = 1,
1706};
1707
1708static void aspeed_video_resolution_work(struct work_struct *work)
1709{
1710 struct delayed_work *dwork = to_delayed_work(work);
1711 struct aspeed_video *video = container_of(dwork, struct aspeed_video,
1712 res_work);
1713
1714 aspeed_video_on(video);
1715
1716 /* Exit early in case no clients remain */
1717 if (test_bit(VIDEO_STOPPED, &video->flags))
1718 goto done;
1719
1720 aspeed_video_init_regs(video);
1721
1722 aspeed_video_update_regs(video);
1723
1724 aspeed_video_get_resolution(video);
1725
1726 if (video->detected_timings.width != video->active_timings.width ||
1727 video->detected_timings.height != video->active_timings.height) {
1728 static const struct v4l2_event ev = {
1729 .type = V4L2_EVENT_SOURCE_CHANGE,
1730 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1731 };
1732
1733 v4l2_dbg(1, debug, &video->v4l2_dev, "fire source change event\n");
1734 v4l2_event_queue(vdev: &video->vdev, ev: &ev);
1735 } else if (test_bit(VIDEO_STREAMING, &video->flags)) {
1736 /* No resolution change so just restart streaming */
1737 aspeed_video_start_frame(video);
1738 }
1739
1740done:
1741 clear_bit(nr: VIDEO_RES_CHANGE, addr: &video->flags);
1742 wake_up_interruptible_all(&video->wait);
1743}
1744
1745static int aspeed_video_open(struct file *file)
1746{
1747 int rc;
1748 struct aspeed_video *video = video_drvdata(file);
1749
1750 mutex_lock(&video->video_lock);
1751
1752 rc = v4l2_fh_open(filp: file);
1753 if (rc) {
1754 mutex_unlock(lock: &video->video_lock);
1755 return rc;
1756 }
1757
1758 if (v4l2_fh_is_singular_file(filp: file))
1759 aspeed_video_start(video);
1760
1761 mutex_unlock(lock: &video->video_lock);
1762
1763 return 0;
1764}
1765
1766static int aspeed_video_release(struct file *file)
1767{
1768 int rc;
1769 struct aspeed_video *video = video_drvdata(file);
1770
1771 mutex_lock(&video->video_lock);
1772
1773 if (v4l2_fh_is_singular_file(filp: file))
1774 aspeed_video_stop(video);
1775
1776 rc = _vb2_fop_release(file, NULL);
1777
1778 mutex_unlock(lock: &video->video_lock);
1779
1780 return rc;
1781}
1782
1783static const struct v4l2_file_operations aspeed_video_v4l2_fops = {
1784 .owner = THIS_MODULE,
1785 .read = vb2_fop_read,
1786 .poll = vb2_fop_poll,
1787 .unlocked_ioctl = video_ioctl2,
1788 .mmap = vb2_fop_mmap,
1789 .open = aspeed_video_open,
1790 .release = aspeed_video_release,
1791};
1792
1793static int aspeed_video_queue_setup(struct vb2_queue *q,
1794 unsigned int *num_buffers,
1795 unsigned int *num_planes,
1796 unsigned int sizes[],
1797 struct device *alloc_devs[])
1798{
1799 struct aspeed_video *video = vb2_get_drv_priv(q);
1800
1801 if (*num_planes) {
1802 if (sizes[0] < video->max_compressed_size)
1803 return -EINVAL;
1804
1805 return 0;
1806 }
1807
1808 *num_planes = 1;
1809 sizes[0] = video->max_compressed_size;
1810
1811 return 0;
1812}
1813
1814static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
1815{
1816 struct aspeed_video *video = vb2_get_drv_priv(q: vb->vb2_queue);
1817
1818 if (vb2_plane_size(vb, plane_no: 0) < video->max_compressed_size)
1819 return -EINVAL;
1820
1821 return 0;
1822}
1823
1824static int aspeed_video_start_streaming(struct vb2_queue *q,
1825 unsigned int count)
1826{
1827 int rc;
1828 struct aspeed_video *video = vb2_get_drv_priv(q);
1829
1830 video->sequence = 0;
1831 video->perf.duration_max = 0;
1832 video->perf.duration_min = 0xffffffff;
1833
1834 aspeed_video_update_regs(video);
1835
1836 rc = aspeed_video_start_frame(video);
1837 if (rc) {
1838 aspeed_video_bufs_done(video, state: VB2_BUF_STATE_QUEUED);
1839 return rc;
1840 }
1841
1842 set_bit(nr: VIDEO_STREAMING, addr: &video->flags);
1843 return 0;
1844}
1845
1846static void aspeed_video_stop_streaming(struct vb2_queue *q)
1847{
1848 int rc;
1849 struct aspeed_video *video = vb2_get_drv_priv(q);
1850
1851 clear_bit(nr: VIDEO_STREAMING, addr: &video->flags);
1852
1853 rc = wait_event_timeout(video->wait,
1854 !test_bit(VIDEO_FRAME_INPRG, &video->flags),
1855 STOP_TIMEOUT);
1856 if (!rc) {
1857 v4l2_dbg(1, debug, &video->v4l2_dev, "Timed out when stopping streaming\n");
1858
1859 /*
1860 * Need to force stop any DMA and try and get HW into a good
1861 * state for future calls to start streaming again.
1862 */
1863 aspeed_video_off(video);
1864 aspeed_video_on(video);
1865
1866 aspeed_video_init_regs(video);
1867
1868 aspeed_video_get_resolution(video);
1869 }
1870
1871 aspeed_video_bufs_done(video, state: VB2_BUF_STATE_ERROR);
1872}
1873
1874static void aspeed_video_buf_queue(struct vb2_buffer *vb)
1875{
1876 bool empty;
1877 struct aspeed_video *video = vb2_get_drv_priv(q: vb->vb2_queue);
1878 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1879 struct aspeed_video_buffer *avb = to_aspeed_video_buffer(vbuf);
1880 unsigned long flags;
1881
1882 spin_lock_irqsave(&video->lock, flags);
1883 empty = list_empty(head: &video->buffers);
1884 list_add_tail(new: &avb->link, head: &video->buffers);
1885 spin_unlock_irqrestore(lock: &video->lock, flags);
1886
1887 if (test_bit(VIDEO_STREAMING, &video->flags) &&
1888 !test_bit(VIDEO_FRAME_INPRG, &video->flags) && empty)
1889 aspeed_video_start_frame(video);
1890}
1891
1892static const struct vb2_ops aspeed_video_vb2_ops = {
1893 .queue_setup = aspeed_video_queue_setup,
1894 .wait_prepare = vb2_ops_wait_prepare,
1895 .wait_finish = vb2_ops_wait_finish,
1896 .buf_prepare = aspeed_video_buf_prepare,
1897 .start_streaming = aspeed_video_start_streaming,
1898 .stop_streaming = aspeed_video_stop_streaming,
1899 .buf_queue = aspeed_video_buf_queue,
1900};
1901
1902#ifdef CONFIG_DEBUG_FS
1903static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
1904{
1905 struct aspeed_video *v = s->private;
1906 u32 val08;
1907
1908 seq_puts(m: s, s: "\n");
1909
1910 seq_puts(m: s, s: "Capture:\n");
1911 val08 = aspeed_video_read(video: v, VE_CTRL);
1912 if (FIELD_GET(VE_CTRL_DIRECT_FETCH, val08)) {
1913 seq_printf(m: s, fmt: " %-20s:\tDirect fetch\n", "Mode");
1914 seq_printf(m: s, fmt: " %-20s:\t%s\n", "VGA bpp mode",
1915 FIELD_GET(VE_CTRL_INT_DE, val08) ? "16" : "32");
1916 } else {
1917 seq_printf(m: s, fmt: " %-20s:\tSync\n", "Mode");
1918 seq_printf(m: s, fmt: " %-20s:\t%s\n", "Video source",
1919 FIELD_GET(VE_CTRL_SOURCE, val08) ?
1920 "external" : "internal");
1921 seq_printf(m: s, fmt: " %-20s:\t%s\n", "DE source",
1922 FIELD_GET(VE_CTRL_INT_DE, val08) ?
1923 "internal" : "external");
1924 seq_printf(m: s, fmt: " %-20s:\t%s\n", "Cursor overlay",
1925 FIELD_GET(VE_CTRL_AUTO_OR_CURSOR, val08) ?
1926 "Without" : "With");
1927 }
1928
1929 seq_printf(m: s, fmt: " %-20s:\t%s\n", "Signal",
1930 v->v4l2_input_status ? "Unlock" : "Lock");
1931 seq_printf(m: s, fmt: " %-20s:\t%d\n", "Width", v->pix_fmt.width);
1932 seq_printf(m: s, fmt: " %-20s:\t%d\n", "Height", v->pix_fmt.height);
1933 seq_printf(m: s, fmt: " %-20s:\t%d\n", "FRC", v->frame_rate);
1934
1935 seq_puts(m: s, s: "\n");
1936
1937 seq_puts(m: s, s: "Compression:\n");
1938 seq_printf(m: s, fmt: " %-20s:\t%s\n", "Format", format_str[v->format]);
1939 seq_printf(m: s, fmt: " %-20s:\t%s\n", "Subsampling",
1940 v->yuv420 ? "420" : "444");
1941 seq_printf(m: s, fmt: " %-20s:\t%d\n", "Quality", v->jpeg_quality);
1942 if (v->format == VIDEO_FMT_ASPEED) {
1943 seq_printf(m: s, fmt: " %-20s:\t%s\n", "HQ Mode",
1944 v->hq_mode ? "on" : "off");
1945 seq_printf(m: s, fmt: " %-20s:\t%d\n", "HQ Quality",
1946 v->hq_mode ? v->jpeg_hq_quality : 0);
1947 }
1948
1949 seq_puts(m: s, s: "\n");
1950
1951 seq_puts(m: s, s: "Performance:\n");
1952 seq_printf(m: s, fmt: " %-20s:\t%d\n", "Frame#", v->sequence);
1953 seq_printf(m: s, fmt: " %-20s:\n", "Frame Duration(ms)");
1954 seq_printf(m: s, fmt: " %-18s:\t%d\n", "Now", v->perf.duration);
1955 seq_printf(m: s, fmt: " %-18s:\t%d\n", "Min", v->perf.duration_min);
1956 seq_printf(m: s, fmt: " %-18s:\t%d\n", "Max", v->perf.duration_max);
1957 seq_printf(m: s, fmt: " %-20s:\t%d\n", "FPS",
1958 (v->perf.totaltime && v->sequence) ?
1959 1000 / (v->perf.totaltime / v->sequence) : 0);
1960
1961 return 0;
1962}
1963DEFINE_SHOW_ATTRIBUTE(aspeed_video_debugfs);
1964
1965static struct dentry *debugfs_entry;
1966
1967static void aspeed_video_debugfs_remove(struct aspeed_video *video)
1968{
1969 debugfs_remove_recursive(dentry: debugfs_entry);
1970 debugfs_entry = NULL;
1971}
1972
1973static void aspeed_video_debugfs_create(struct aspeed_video *video)
1974{
1975 debugfs_entry = debugfs_create_file(DEVICE_NAME, mode: 0444, NULL,
1976 data: video,
1977 fops: &aspeed_video_debugfs_fops);
1978}
1979#else
1980static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
1981static void aspeed_video_debugfs_create(struct aspeed_video *video) { }
1982#endif /* CONFIG_DEBUG_FS */
1983
1984static int aspeed_video_setup_video(struct aspeed_video *video)
1985{
1986 const u64 mask = ~(BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_444) |
1987 BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_420));
1988 struct v4l2_device *v4l2_dev = &video->v4l2_dev;
1989 struct vb2_queue *vbq = &video->queue;
1990 struct video_device *vdev = &video->vdev;
1991 struct v4l2_ctrl_handler *hdl = &video->ctrl_handler;
1992 int rc;
1993
1994 video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG;
1995 video->pix_fmt.field = V4L2_FIELD_NONE;
1996 video->pix_fmt.colorspace = V4L2_COLORSPACE_SRGB;
1997 video->pix_fmt.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1998 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1999
2000 rc = v4l2_device_register(dev: video->dev, v4l2_dev);
2001 if (rc) {
2002 dev_err(video->dev, "Failed to register v4l2 device\n");
2003 return rc;
2004 }
2005
2006 v4l2_ctrl_handler_init(hdl, 4);
2007 v4l2_ctrl_new_std(hdl, ops: &aspeed_video_ctrl_ops,
2008 V4L2_CID_JPEG_COMPRESSION_QUALITY, min: 0,
2009 ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1, step: 1, def: 0);
2010 v4l2_ctrl_new_std_menu(hdl, ops: &aspeed_video_ctrl_ops,
2011 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
2012 max: V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask,
2013 def: V4L2_JPEG_CHROMA_SUBSAMPLING_444);
2014 v4l2_ctrl_new_custom(hdl, cfg: &aspeed_ctrl_HQ_mode, NULL);
2015 v4l2_ctrl_new_custom(hdl, cfg: &aspeed_ctrl_HQ_jpeg_quality, NULL);
2016
2017 rc = hdl->error;
2018 if (rc) {
2019 v4l2_ctrl_handler_free(hdl: &video->ctrl_handler);
2020 v4l2_device_unregister(v4l2_dev);
2021
2022 dev_err(video->dev, "Failed to init controls: %d\n", rc);
2023 return rc;
2024 }
2025
2026 v4l2_dev->ctrl_handler = hdl;
2027
2028 vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2029 vbq->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
2030 vbq->dev = v4l2_dev->dev;
2031 vbq->lock = &video->video_lock;
2032 vbq->ops = &aspeed_video_vb2_ops;
2033 vbq->mem_ops = &vb2_dma_contig_memops;
2034 vbq->drv_priv = video;
2035 vbq->buf_struct_size = sizeof(struct aspeed_video_buffer);
2036 vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
2037 vbq->min_queued_buffers = ASPEED_VIDEO_V4L2_MIN_BUF_REQ;
2038
2039 rc = vb2_queue_init(q: vbq);
2040 if (rc) {
2041 v4l2_ctrl_handler_free(hdl: &video->ctrl_handler);
2042 v4l2_device_unregister(v4l2_dev);
2043
2044 dev_err(video->dev, "Failed to init vb2 queue\n");
2045 return rc;
2046 }
2047
2048 vdev->queue = vbq;
2049 vdev->fops = &aspeed_video_v4l2_fops;
2050 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
2051 V4L2_CAP_STREAMING;
2052 vdev->v4l2_dev = v4l2_dev;
2053 strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));
2054 vdev->vfl_type = VFL_TYPE_VIDEO;
2055 vdev->vfl_dir = VFL_DIR_RX;
2056 vdev->release = video_device_release_empty;
2057 vdev->ioctl_ops = &aspeed_video_ioctl_ops;
2058 vdev->lock = &video->video_lock;
2059
2060 video_set_drvdata(vdev, data: video);
2061 rc = video_register_device(vdev, type: VFL_TYPE_VIDEO, nr: 0);
2062 if (rc) {
2063 v4l2_ctrl_handler_free(hdl: &video->ctrl_handler);
2064 v4l2_device_unregister(v4l2_dev);
2065
2066 dev_err(video->dev, "Failed to register video device\n");
2067 return rc;
2068 }
2069
2070 return 0;
2071}
2072
2073static int aspeed_video_init(struct aspeed_video *video)
2074{
2075 int irq;
2076 int rc;
2077 struct device *dev = video->dev;
2078
2079 irq = irq_of_parse_and_map(node: dev->of_node, index: 0);
2080 if (!irq) {
2081 dev_err(dev, "Unable to find IRQ\n");
2082 return -ENODEV;
2083 }
2084
2085 rc = devm_request_threaded_irq(dev, irq, NULL, thread_fn: aspeed_video_irq,
2086 IRQF_ONESHOT, DEVICE_NAME, dev_id: video);
2087 if (rc < 0) {
2088 dev_err(dev, "Unable to request IRQ %d\n", irq);
2089 return rc;
2090 }
2091 dev_info(video->dev, "irq %d\n", irq);
2092
2093 video->eclk = devm_clk_get(dev, id: "eclk");
2094 if (IS_ERR(ptr: video->eclk)) {
2095 dev_err(dev, "Unable to get ECLK\n");
2096 return PTR_ERR(ptr: video->eclk);
2097 }
2098
2099 rc = clk_prepare(clk: video->eclk);
2100 if (rc)
2101 return rc;
2102
2103 video->vclk = devm_clk_get(dev, id: "vclk");
2104 if (IS_ERR(ptr: video->vclk)) {
2105 dev_err(dev, "Unable to get VCLK\n");
2106 rc = PTR_ERR(ptr: video->vclk);
2107 goto err_unprepare_eclk;
2108 }
2109
2110 rc = clk_prepare(clk: video->vclk);
2111 if (rc)
2112 goto err_unprepare_eclk;
2113
2114 of_reserved_mem_device_init(dev);
2115
2116 rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
2117 if (rc) {
2118 dev_err(dev, "Failed to set DMA mask\n");
2119 goto err_release_reserved_mem;
2120 }
2121
2122 if (!aspeed_video_alloc_buf(video, addr: &video->jpeg,
2123 VE_JPEG_HEADER_SIZE)) {
2124 dev_err(dev, "Failed to allocate DMA for JPEG header\n");
2125 rc = -ENOMEM;
2126 goto err_release_reserved_mem;
2127 }
2128 dev_info(video->dev, "alloc mem size(%d) at %pad for jpeg header\n",
2129 VE_JPEG_HEADER_SIZE, &video->jpeg.dma);
2130
2131 aspeed_video_init_jpeg_table(table: video->jpeg.virt, yuv420: video->yuv420);
2132
2133 return 0;
2134
2135err_release_reserved_mem:
2136 of_reserved_mem_device_release(dev);
2137 clk_unprepare(clk: video->vclk);
2138err_unprepare_eclk:
2139 clk_unprepare(clk: video->eclk);
2140
2141 return rc;
2142}
2143
2144static const struct of_device_id aspeed_video_of_match[] = {
2145 { .compatible = "aspeed,ast2400-video-engine", .data = &ast2400_config },
2146 { .compatible = "aspeed,ast2500-video-engine", .data = &ast2500_config },
2147 { .compatible = "aspeed,ast2600-video-engine", .data = &ast2600_config },
2148 {}
2149};
2150MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
2151
2152static int aspeed_video_probe(struct platform_device *pdev)
2153{
2154 const struct aspeed_video_config *config;
2155 struct aspeed_video *video;
2156 int rc;
2157
2158 video = devm_kzalloc(dev: &pdev->dev, size: sizeof(*video), GFP_KERNEL);
2159 if (!video)
2160 return -ENOMEM;
2161
2162 video->base = devm_platform_ioremap_resource(pdev, index: 0);
2163 if (IS_ERR(ptr: video->base))
2164 return PTR_ERR(ptr: video->base);
2165
2166 config = of_device_get_match_data(dev: &pdev->dev);
2167 if (!config)
2168 return -ENODEV;
2169
2170 video->jpeg_mode = config->jpeg_mode;
2171 video->comp_size_read = config->comp_size_read;
2172
2173 video->frame_rate = 30;
2174 video->jpeg_hq_quality = 1;
2175 video->dev = &pdev->dev;
2176 spin_lock_init(&video->lock);
2177 mutex_init(&video->video_lock);
2178 init_waitqueue_head(&video->wait);
2179 INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
2180 INIT_LIST_HEAD(list: &video->buffers);
2181
2182 rc = aspeed_video_init(video);
2183 if (rc)
2184 return rc;
2185
2186 rc = aspeed_video_setup_video(video);
2187 if (rc) {
2188 aspeed_video_free_buf(video, addr: &video->jpeg);
2189 clk_unprepare(clk: video->vclk);
2190 clk_unprepare(clk: video->eclk);
2191 return rc;
2192 }
2193
2194 aspeed_video_debugfs_create(video);
2195
2196 return 0;
2197}
2198
2199static void aspeed_video_remove(struct platform_device *pdev)
2200{
2201 struct device *dev = &pdev->dev;
2202 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
2203 struct aspeed_video *video = to_aspeed_video(v4l2_dev);
2204
2205 aspeed_video_off(video);
2206
2207 aspeed_video_debugfs_remove(video);
2208
2209 clk_unprepare(clk: video->vclk);
2210 clk_unprepare(clk: video->eclk);
2211
2212 vb2_video_unregister_device(vdev: &video->vdev);
2213
2214 v4l2_ctrl_handler_free(hdl: &video->ctrl_handler);
2215
2216 v4l2_device_unregister(v4l2_dev);
2217
2218 aspeed_video_free_buf(video, addr: &video->jpeg);
2219
2220 of_reserved_mem_device_release(dev);
2221}
2222
2223static struct platform_driver aspeed_video_driver = {
2224 .driver = {
2225 .name = DEVICE_NAME,
2226 .of_match_table = aspeed_video_of_match,
2227 },
2228 .probe = aspeed_video_probe,
2229 .remove_new = aspeed_video_remove,
2230};
2231
2232module_platform_driver(aspeed_video_driver);
2233
2234module_param(debug, int, 0644);
2235MODULE_PARM_DESC(debug, "Debug level (0=off,1=info,2=debug,3=reg ops)");
2236
2237MODULE_DESCRIPTION("ASPEED Video Engine Driver");
2238MODULE_AUTHOR("Eddie James");
2239MODULE_LICENSE("GPL v2");
2240

source code of linux/drivers/media/platform/aspeed/aspeed-video.c