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