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