1 /*
2 * Renesas R-Car Fine Display Processor
3 *
4 * Video format converter and frame deinterlacer device.
5 *
6 * Author: Kieran Bingham, <kieran@bingham.xyz>
7 * Copyright (c) 2016 Renesas Electronics Corporation.
8 *
9 * This code is developed and inspired from the vim2m, rcar_jpu,
10 * m2m-deinterlace, and vsp1 drivers.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version
16 */
17
18 #include <linux/clk.h>
19 #include <linux/delay.h>
20 #include <linux/dma-mapping.h>
21 #include <linux/fs.h>
22 #include <linux/interrupt.h>
23 #include <linux/module.h>
24 #include <linux/of.h>
25 #include <linux/of_device.h>
26 #include <linux/platform_device.h>
27 #include <linux/pm_runtime.h>
28 #include <linux/sched.h>
29 #include <linux/slab.h>
30 #include <linux/timer.h>
31 #include <media/rcar-fcp.h>
32 #include <media/v4l2-ctrls.h>
33 #include <media/v4l2-device.h>
34 #include <media/v4l2-event.h>
35 #include <media/v4l2-ioctl.h>
36 #include <media/v4l2-mem2mem.h>
37 #include <media/videobuf2-dma-contig.h>
38
39 static unsigned int debug;
40 module_param(debug, uint, 0644);
41 MODULE_PARM_DESC(debug, "activate debug info");
42
43 /* Minimum and maximum frame width/height */
44 #define FDP1_MIN_W 80U
45 #define FDP1_MIN_H 80U
46
47 #define FDP1_MAX_W 3840U
48 #define FDP1_MAX_H 2160U
49
50 #define FDP1_MAX_PLANES 3U
51 #define FDP1_MAX_STRIDE 8190U
52
53 /* Flags that indicate a format can be used for capture/output */
54 #define FDP1_CAPTURE BIT(0)
55 #define FDP1_OUTPUT BIT(1)
56
57 #define DRIVER_NAME "rcar_fdp1"
58
59 /* Number of Job's to have available on the processing queue */
60 #define FDP1_NUMBER_JOBS 8
61
62 #define dprintk(fdp1, fmt, arg...) \
63 v4l2_dbg(1, debug, &fdp1->v4l2_dev, "%s: " fmt, __func__, ## arg)
64
65 /*
66 * FDP1 registers and bits
67 */
68
69 /* FDP1 start register - Imm */
70 #define FD1_CTL_CMD 0x0000
71 #define FD1_CTL_CMD_STRCMD BIT(0)
72
73 /* Sync generator register - Imm */
74 #define FD1_CTL_SGCMD 0x0004
75 #define FD1_CTL_SGCMD_SGEN BIT(0)
76
77 /* Register set end register - Imm */
78 #define FD1_CTL_REGEND 0x0008
79 #define FD1_CTL_REGEND_REGEND BIT(0)
80
81 /* Channel activation register - Vupdt */
82 #define FD1_CTL_CHACT 0x000c
83 #define FD1_CTL_CHACT_SMW BIT(9)
84 #define FD1_CTL_CHACT_WR BIT(8)
85 #define FD1_CTL_CHACT_SMR BIT(3)
86 #define FD1_CTL_CHACT_RD2 BIT(2)
87 #define FD1_CTL_CHACT_RD1 BIT(1)
88 #define FD1_CTL_CHACT_RD0 BIT(0)
89
90 /* Operation Mode Register - Vupdt */
91 #define FD1_CTL_OPMODE 0x0010
92 #define FD1_CTL_OPMODE_PRG BIT(4)
93 #define FD1_CTL_OPMODE_VIMD_INTERRUPT (0 << 0)
94 #define FD1_CTL_OPMODE_VIMD_BESTEFFORT (1 << 0)
95 #define FD1_CTL_OPMODE_VIMD_NOINTERRUPT (2 << 0)
96
97 #define FD1_CTL_VPERIOD 0x0014
98 #define FD1_CTL_CLKCTRL 0x0018
99 #define FD1_CTL_CLKCTRL_CSTP_N BIT(0)
100
101 /* Software reset register */
102 #define FD1_CTL_SRESET 0x001c
103 #define FD1_CTL_SRESET_SRST BIT(0)
104
105 /* Control status register (V-update-status) */
106 #define FD1_CTL_STATUS 0x0024
107 #define FD1_CTL_STATUS_VINT_CNT_MASK GENMASK(31, 16)
108 #define FD1_CTL_STATUS_VINT_CNT_SHIFT 16
109 #define FD1_CTL_STATUS_SGREGSET BIT(10)
110 #define FD1_CTL_STATUS_SGVERR BIT(9)
111 #define FD1_CTL_STATUS_SGFREND BIT(8)
112 #define FD1_CTL_STATUS_BSY BIT(0)
113
114 #define FD1_CTL_VCYCLE_STAT 0x0028
115
116 /* Interrupt enable register */
117 #define FD1_CTL_IRQENB 0x0038
118 /* Interrupt status register */
119 #define FD1_CTL_IRQSTA 0x003c
120 /* Interrupt control register */
121 #define FD1_CTL_IRQFSET 0x0040
122
123 /* Common IRQ Bit settings */
124 #define FD1_CTL_IRQ_VERE BIT(16)
125 #define FD1_CTL_IRQ_VINTE BIT(4)
126 #define FD1_CTL_IRQ_FREE BIT(0)
127 #define FD1_CTL_IRQ_MASK (FD1_CTL_IRQ_VERE | \
128 FD1_CTL_IRQ_VINTE | \
129 FD1_CTL_IRQ_FREE)
130
131 /* RPF */
132 #define FD1_RPF_SIZE 0x0060
133 #define FD1_RPF_SIZE_MASK GENMASK(12, 0)
134 #define FD1_RPF_SIZE_H_SHIFT 16
135 #define FD1_RPF_SIZE_V_SHIFT 0
136
137 #define FD1_RPF_FORMAT 0x0064
138 #define FD1_RPF_FORMAT_CIPM BIT(16)
139 #define FD1_RPF_FORMAT_RSPYCS BIT(13)
140 #define FD1_RPF_FORMAT_RSPUVS BIT(12)
141 #define FD1_RPF_FORMAT_CF BIT(8)
142
143 #define FD1_RPF_PSTRIDE 0x0068
144 #define FD1_RPF_PSTRIDE_Y_SHIFT 16
145 #define FD1_RPF_PSTRIDE_C_SHIFT 0
146
147 /* RPF0 Source Component Y Address register */
148 #define FD1_RPF0_ADDR_Y 0x006c
149
150 /* RPF1 Current Picture Registers */
151 #define FD1_RPF1_ADDR_Y 0x0078
152 #define FD1_RPF1_ADDR_C0 0x007c
153 #define FD1_RPF1_ADDR_C1 0x0080
154
155 /* RPF2 next picture register */
156 #define FD1_RPF2_ADDR_Y 0x0084
157
158 #define FD1_RPF_SMSK_ADDR 0x0090
159 #define FD1_RPF_SWAP 0x0094
160
161 /* WPF */
162 #define FD1_WPF_FORMAT 0x00c0
163 #define FD1_WPF_FORMAT_PDV_SHIFT 24
164 #define FD1_WPF_FORMAT_FCNL BIT(20)
165 #define FD1_WPF_FORMAT_WSPYCS BIT(15)
166 #define FD1_WPF_FORMAT_WSPUVS BIT(14)
167 #define FD1_WPF_FORMAT_WRTM_601_16 (0 << 9)
168 #define FD1_WPF_FORMAT_WRTM_601_0 (1 << 9)
169 #define FD1_WPF_FORMAT_WRTM_709_16 (2 << 9)
170 #define FD1_WPF_FORMAT_CSC BIT(8)
171
172 #define FD1_WPF_RNDCTL 0x00c4
173 #define FD1_WPF_RNDCTL_CBRM BIT(28)
174 #define FD1_WPF_RNDCTL_CLMD_NOCLIP (0 << 12)
175 #define FD1_WPF_RNDCTL_CLMD_CLIP_16_235 (1 << 12)
176 #define FD1_WPF_RNDCTL_CLMD_CLIP_1_254 (2 << 12)
177
178 #define FD1_WPF_PSTRIDE 0x00c8
179 #define FD1_WPF_PSTRIDE_Y_SHIFT 16
180 #define FD1_WPF_PSTRIDE_C_SHIFT 0
181
182 /* WPF Destination picture */
183 #define FD1_WPF_ADDR_Y 0x00cc
184 #define FD1_WPF_ADDR_C0 0x00d0
185 #define FD1_WPF_ADDR_C1 0x00d4
186 #define FD1_WPF_SWAP 0x00d8
187 #define FD1_WPF_SWAP_OSWAP_SHIFT 0
188 #define FD1_WPF_SWAP_SSWAP_SHIFT 4
189
190 /* WPF/RPF Common */
191 #define FD1_RWPF_SWAP_BYTE BIT(0)
192 #define FD1_RWPF_SWAP_WORD BIT(1)
193 #define FD1_RWPF_SWAP_LWRD BIT(2)
194 #define FD1_RWPF_SWAP_LLWD BIT(3)
195
196 /* IPC */
197 #define FD1_IPC_MODE 0x0100
198 #define FD1_IPC_MODE_DLI BIT(8)
199 #define FD1_IPC_MODE_DIM_ADAPT2D3D (0 << 0)
200 #define FD1_IPC_MODE_DIM_FIXED2D (1 << 0)
201 #define FD1_IPC_MODE_DIM_FIXED3D (2 << 0)
202 #define FD1_IPC_MODE_DIM_PREVFIELD (3 << 0)
203 #define FD1_IPC_MODE_DIM_NEXTFIELD (4 << 0)
204
205 #define FD1_IPC_SMSK_THRESH 0x0104
206 #define FD1_IPC_SMSK_THRESH_CONST 0x00010002
207
208 #define FD1_IPC_COMB_DET 0x0108
209 #define FD1_IPC_COMB_DET_CONST 0x00200040
210
211 #define FD1_IPC_MOTDEC 0x010c
212 #define FD1_IPC_MOTDEC_CONST 0x00008020
213
214 /* DLI registers */
215 #define FD1_IPC_DLI_BLEND 0x0120
216 #define FD1_IPC_DLI_BLEND_CONST 0x0080ff02
217
218 #define FD1_IPC_DLI_HGAIN 0x0124
219 #define FD1_IPC_DLI_HGAIN_CONST 0x001000ff
220
221 #define FD1_IPC_DLI_SPRS 0x0128
222 #define FD1_IPC_DLI_SPRS_CONST 0x009004ff
223
224 #define FD1_IPC_DLI_ANGLE 0x012c
225 #define FD1_IPC_DLI_ANGLE_CONST 0x0004080c
226
227 #define FD1_IPC_DLI_ISOPIX0 0x0130
228 #define FD1_IPC_DLI_ISOPIX0_CONST 0xff10ff10
229
230 #define FD1_IPC_DLI_ISOPIX1 0x0134
231 #define FD1_IPC_DLI_ISOPIX1_CONST 0x0000ff10
232
233 /* Sensor registers */
234 #define FD1_IPC_SENSOR_TH0 0x0140
235 #define FD1_IPC_SENSOR_TH0_CONST 0x20208080
236
237 #define FD1_IPC_SENSOR_TH1 0x0144
238 #define FD1_IPC_SENSOR_TH1_CONST 0
239
240 #define FD1_IPC_SENSOR_CTL0 0x0170
241 #define FD1_IPC_SENSOR_CTL0_CONST 0x00002201
242
243 #define FD1_IPC_SENSOR_CTL1 0x0174
244 #define FD1_IPC_SENSOR_CTL1_CONST 0
245
246 #define FD1_IPC_SENSOR_CTL2 0x0178
247 #define FD1_IPC_SENSOR_CTL2_X_SHIFT 16
248 #define FD1_IPC_SENSOR_CTL2_Y_SHIFT 0
249
250 #define FD1_IPC_SENSOR_CTL3 0x017c
251 #define FD1_IPC_SENSOR_CTL3_0_SHIFT 16
252 #define FD1_IPC_SENSOR_CTL3_1_SHIFT 0
253
254 /* Line memory pixel number register */
255 #define FD1_IPC_LMEM 0x01e0
256 #define FD1_IPC_LMEM_LINEAR 1024
257 #define FD1_IPC_LMEM_TILE 960
258
259 /* Internal Data (HW Version) */
260 #define FD1_IP_INTDATA 0x0800
261 #define FD1_IP_H3_ES1 0x02010101
262 #define FD1_IP_M3W 0x02010202
263 #define FD1_IP_H3 0x02010203
264 #define FD1_IP_M3N 0x02010204
265 #define FD1_IP_E3 0x02010205
266
267 /* LUTs */
268 #define FD1_LUT_DIF_ADJ 0x1000
269 #define FD1_LUT_SAD_ADJ 0x1400
270 #define FD1_LUT_BLD_GAIN 0x1800
271 #define FD1_LUT_DIF_GAIN 0x1c00
272 #define FD1_LUT_MDET 0x2000
273
274 /**
275 * struct fdp1_fmt - The FDP1 internal format data
276 * @fourcc: the fourcc code, to match the V4L2 API
277 * @bpp: bits per pixel per plane
278 * @num_planes: number of planes
279 * @hsub: horizontal subsampling factor
280 * @vsub: vertical subsampling factor
281 * @fmt: 7-bit format code for the fdp1 hardware
282 * @swap_yc: the Y and C components are swapped (Y comes before C)
283 * @swap_uv: the U and V components are swapped (V comes before U)
284 * @swap: swap register control
285 * @types: types of queue this format is applicable to
286 */
287 struct fdp1_fmt {
288 u32 fourcc;
289 u8 bpp[3];
290 u8 num_planes;
291 u8 hsub;
292 u8 vsub;
293 u8 fmt;
294 bool swap_yc;
295 bool swap_uv;
296 u8 swap;
297 u8 types;
298 };
299
300 static const struct fdp1_fmt fdp1_formats[] = {
301 /* RGB formats are only supported by the Write Pixel Formatter */
302
303 { V4L2_PIX_FMT_RGB332, { 8, 0, 0 }, 1, 1, 1, 0x00, false, false,
304 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
305 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
306 FDP1_CAPTURE },
307 { V4L2_PIX_FMT_XRGB444, { 16, 0, 0 }, 1, 1, 1, 0x01, false, false,
308 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
309 FD1_RWPF_SWAP_WORD,
310 FDP1_CAPTURE },
311 { V4L2_PIX_FMT_XRGB555, { 16, 0, 0 }, 1, 1, 1, 0x04, false, false,
312 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
313 FD1_RWPF_SWAP_WORD,
314 FDP1_CAPTURE },
315 { V4L2_PIX_FMT_RGB565, { 16, 0, 0 }, 1, 1, 1, 0x06, false, false,
316 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
317 FD1_RWPF_SWAP_WORD,
318 FDP1_CAPTURE },
319 { V4L2_PIX_FMT_ABGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
320 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD,
321 FDP1_CAPTURE },
322 { V4L2_PIX_FMT_XBGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
323 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD,
324 FDP1_CAPTURE },
325 { V4L2_PIX_FMT_ARGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
326 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
327 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
328 FDP1_CAPTURE },
329 { V4L2_PIX_FMT_XRGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
330 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
331 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
332 FDP1_CAPTURE },
333 { V4L2_PIX_FMT_RGB24, { 24, 0, 0 }, 1, 1, 1, 0x15, false, false,
334 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
335 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
336 FDP1_CAPTURE },
337 { V4L2_PIX_FMT_BGR24, { 24, 0, 0 }, 1, 1, 1, 0x18, false, false,
338 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
339 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
340 FDP1_CAPTURE },
341 { V4L2_PIX_FMT_ARGB444, { 16, 0, 0 }, 1, 1, 1, 0x19, false, false,
342 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
343 FD1_RWPF_SWAP_WORD,
344 FDP1_CAPTURE },
345 { V4L2_PIX_FMT_ARGB555, { 16, 0, 0 }, 1, 1, 1, 0x1b, false, false,
346 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
347 FD1_RWPF_SWAP_WORD,
348 FDP1_CAPTURE },
349
350 /* YUV Formats are supported by Read and Write Pixel Formatters */
351
352 { V4L2_PIX_FMT_NV16M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, false,
353 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
354 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
355 FDP1_CAPTURE | FDP1_OUTPUT },
356 { V4L2_PIX_FMT_NV61M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, true,
357 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
358 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
359 FDP1_CAPTURE | FDP1_OUTPUT },
360 { V4L2_PIX_FMT_NV12M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, false,
361 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
362 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
363 FDP1_CAPTURE | FDP1_OUTPUT },
364 { V4L2_PIX_FMT_NV21M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, true,
365 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
366 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
367 FDP1_CAPTURE | FDP1_OUTPUT },
368 { V4L2_PIX_FMT_UYVY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, false,
369 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
370 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
371 FDP1_CAPTURE | FDP1_OUTPUT },
372 { V4L2_PIX_FMT_VYUY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, true,
373 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
374 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
375 FDP1_CAPTURE | FDP1_OUTPUT },
376 { V4L2_PIX_FMT_YUYV, { 16, 0, 0 }, 1, 2, 1, 0x47, true, false,
377 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
378 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
379 FDP1_CAPTURE | FDP1_OUTPUT },
380 { V4L2_PIX_FMT_YVYU, { 16, 0, 0 }, 1, 2, 1, 0x47, true, true,
381 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
382 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
383 FDP1_CAPTURE | FDP1_OUTPUT },
384 { V4L2_PIX_FMT_YUV444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, false,
385 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
386 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
387 FDP1_CAPTURE | FDP1_OUTPUT },
388 { V4L2_PIX_FMT_YVU444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, true,
389 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
390 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
391 FDP1_CAPTURE | FDP1_OUTPUT },
392 { V4L2_PIX_FMT_YUV422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, false,
393 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
394 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
395 FDP1_CAPTURE | FDP1_OUTPUT },
396 { V4L2_PIX_FMT_YVU422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, true,
397 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
398 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
399 FDP1_CAPTURE | FDP1_OUTPUT },
400 { V4L2_PIX_FMT_YUV420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, false,
401 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
402 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
403 FDP1_CAPTURE | FDP1_OUTPUT },
404 { V4L2_PIX_FMT_YVU420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, true,
405 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
406 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
407 FDP1_CAPTURE | FDP1_OUTPUT },
408 };
409
fdp1_fmt_is_rgb(const struct fdp1_fmt * fmt)410 static int fdp1_fmt_is_rgb(const struct fdp1_fmt *fmt)
411 {
412 return fmt->fmt <= 0x1b; /* Last RGB code */
413 }
414
415 /*
416 * FDP1 Lookup tables range from 0...255 only
417 *
418 * Each table must be less than 256 entries, and all tables
419 * are padded out to 256 entries by duplicating the last value.
420 */
421 static const u8 fdp1_diff_adj[] = {
422 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf,
423 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3,
424 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff,
425 };
426
427 static const u8 fdp1_sad_adj[] = {
428 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf,
429 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3,
430 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff,
431 };
432
433 static const u8 fdp1_bld_gain[] = {
434 0x80,
435 };
436
437 static const u8 fdp1_dif_gain[] = {
438 0x80,
439 };
440
441 static const u8 fdp1_mdet[] = {
442 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
443 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
444 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
445 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
446 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
447 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
448 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
449 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
450 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
451 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
452 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
453 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
454 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
455 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
456 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
457 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
458 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
459 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
460 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
461 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
462 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
463 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
464 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
465 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
466 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
467 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
468 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
469 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
470 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
471 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
472 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
473 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
474 };
475
476 /* Per-queue, driver-specific private data */
477 struct fdp1_q_data {
478 const struct fdp1_fmt *fmt;
479 struct v4l2_pix_format_mplane format;
480
481 unsigned int vsize;
482 unsigned int stride_y;
483 unsigned int stride_c;
484 };
485
fdp1_find_format(u32 pixelformat)486 static const struct fdp1_fmt *fdp1_find_format(u32 pixelformat)
487 {
488 const struct fdp1_fmt *fmt;
489 unsigned int i;
490
491 for (i = 0; i < ARRAY_SIZE(fdp1_formats); i++) {
492 fmt = &fdp1_formats[i];
493 if (fmt->fourcc == pixelformat)
494 return fmt;
495 }
496
497 return NULL;
498 }
499
500 enum fdp1_deint_mode {
501 FDP1_PROGRESSIVE = 0, /* Must be zero when !deinterlacing */
502 FDP1_ADAPT2D3D,
503 FDP1_FIXED2D,
504 FDP1_FIXED3D,
505 FDP1_PREVFIELD,
506 FDP1_NEXTFIELD,
507 };
508
509 #define FDP1_DEINT_MODE_USES_NEXT(mode) \
510 (mode == FDP1_ADAPT2D3D || \
511 mode == FDP1_FIXED3D || \
512 mode == FDP1_NEXTFIELD)
513
514 #define FDP1_DEINT_MODE_USES_PREV(mode) \
515 (mode == FDP1_ADAPT2D3D || \
516 mode == FDP1_FIXED3D || \
517 mode == FDP1_PREVFIELD)
518
519 /*
520 * FDP1 operates on potentially 3 fields, which are tracked
521 * from the VB buffers using this context structure.
522 * Will always be a field or a full frame, never two fields.
523 */
524 struct fdp1_field_buffer {
525 struct vb2_v4l2_buffer *vb;
526 dma_addr_t addrs[3];
527
528 /* Should be NONE:TOP:BOTTOM only */
529 enum v4l2_field field;
530
531 /* Flag to indicate this is the last field in the vb */
532 bool last_field;
533
534 /* Buffer queue lists */
535 struct list_head list;
536 };
537
538 struct fdp1_buffer {
539 struct v4l2_m2m_buffer m2m_buf;
540 struct fdp1_field_buffer fields[2];
541 unsigned int num_fields;
542 };
543
to_fdp1_buffer(struct vb2_v4l2_buffer * vb)544 static inline struct fdp1_buffer *to_fdp1_buffer(struct vb2_v4l2_buffer *vb)
545 {
546 return container_of(vb, struct fdp1_buffer, m2m_buf.vb);
547 }
548
549 struct fdp1_job {
550 struct fdp1_field_buffer *previous;
551 struct fdp1_field_buffer *active;
552 struct fdp1_field_buffer *next;
553 struct fdp1_field_buffer *dst;
554
555 /* A job can only be on one list at a time */
556 struct list_head list;
557 };
558
559 struct fdp1_dev {
560 struct v4l2_device v4l2_dev;
561 struct video_device vfd;
562
563 struct mutex dev_mutex;
564 spinlock_t irqlock;
565 spinlock_t device_process_lock;
566
567 void __iomem *regs;
568 unsigned int irq;
569 struct device *dev;
570
571 /* Job Queues */
572 struct fdp1_job jobs[FDP1_NUMBER_JOBS];
573 struct list_head free_job_list;
574 struct list_head queued_job_list;
575 struct list_head hw_job_list;
576
577 unsigned int clk_rate;
578
579 struct rcar_fcp_device *fcp;
580 struct v4l2_m2m_dev *m2m_dev;
581 };
582
583 struct fdp1_ctx {
584 struct v4l2_fh fh;
585 struct fdp1_dev *fdp1;
586
587 struct v4l2_ctrl_handler hdl;
588 unsigned int sequence;
589
590 /* Processed buffers in this transaction */
591 u8 num_processed;
592
593 /* Transaction length (i.e. how many buffers per transaction) */
594 u32 translen;
595
596 /* Abort requested by m2m */
597 int aborting;
598
599 /* Deinterlace processing mode */
600 enum fdp1_deint_mode deint_mode;
601
602 /*
603 * Adaptive 2D/3D mode uses a shared mask
604 * This is allocated at streamon, if the ADAPT2D3D mode
605 * is requested
606 */
607 unsigned int smsk_size;
608 dma_addr_t smsk_addr[2];
609 void *smsk_cpu;
610
611 /* Capture pipeline, can specify an alpha value
612 * for supported formats. 0-255 only
613 */
614 unsigned char alpha;
615
616 /* Source and destination queue data */
617 struct fdp1_q_data out_q; /* HW Source */
618 struct fdp1_q_data cap_q; /* HW Destination */
619
620 /*
621 * Field Queues
622 * Interlaced fields are used on 3 occasions, and tracked in this list.
623 *
624 * V4L2 Buffers are tracked inside the fdp1_buffer
625 * and released when the last 'field' completes
626 */
627 struct list_head fields_queue;
628 unsigned int buffers_queued;
629
630 /*
631 * For de-interlacing we need to track our previous buffer
632 * while preparing our job lists.
633 */
634 struct fdp1_field_buffer *previous;
635 };
636
fh_to_ctx(struct v4l2_fh * fh)637 static inline struct fdp1_ctx *fh_to_ctx(struct v4l2_fh *fh)
638 {
639 return container_of(fh, struct fdp1_ctx, fh);
640 }
641
get_q_data(struct fdp1_ctx * ctx,enum v4l2_buf_type type)642 static struct fdp1_q_data *get_q_data(struct fdp1_ctx *ctx,
643 enum v4l2_buf_type type)
644 {
645 if (V4L2_TYPE_IS_OUTPUT(type))
646 return &ctx->out_q;
647 else
648 return &ctx->cap_q;
649 }
650
651 /*
652 * list_remove_job: Take the first item off the specified job list
653 *
654 * Returns: pointer to a job, or NULL if the list is empty.
655 */
list_remove_job(struct fdp1_dev * fdp1,struct list_head * list)656 static struct fdp1_job *list_remove_job(struct fdp1_dev *fdp1,
657 struct list_head *list)
658 {
659 struct fdp1_job *job;
660 unsigned long flags;
661
662 spin_lock_irqsave(&fdp1->irqlock, flags);
663 job = list_first_entry_or_null(list, struct fdp1_job, list);
664 if (job)
665 list_del(&job->list);
666 spin_unlock_irqrestore(&fdp1->irqlock, flags);
667
668 return job;
669 }
670
671 /*
672 * list_add_job: Add a job to the specified job list
673 *
674 * Returns: void - always succeeds
675 */
list_add_job(struct fdp1_dev * fdp1,struct list_head * list,struct fdp1_job * job)676 static void list_add_job(struct fdp1_dev *fdp1,
677 struct list_head *list,
678 struct fdp1_job *job)
679 {
680 unsigned long flags;
681
682 spin_lock_irqsave(&fdp1->irqlock, flags);
683 list_add_tail(&job->list, list);
684 spin_unlock_irqrestore(&fdp1->irqlock, flags);
685 }
686
fdp1_job_alloc(struct fdp1_dev * fdp1)687 static struct fdp1_job *fdp1_job_alloc(struct fdp1_dev *fdp1)
688 {
689 return list_remove_job(fdp1, &fdp1->free_job_list);
690 }
691
fdp1_job_free(struct fdp1_dev * fdp1,struct fdp1_job * job)692 static void fdp1_job_free(struct fdp1_dev *fdp1, struct fdp1_job *job)
693 {
694 /* Ensure that all residue from previous jobs is gone */
695 memset(job, 0, sizeof(struct fdp1_job));
696
697 list_add_job(fdp1, &fdp1->free_job_list, job);
698 }
699
queue_job(struct fdp1_dev * fdp1,struct fdp1_job * job)700 static void queue_job(struct fdp1_dev *fdp1, struct fdp1_job *job)
701 {
702 list_add_job(fdp1, &fdp1->queued_job_list, job);
703 }
704
get_queued_job(struct fdp1_dev * fdp1)705 static struct fdp1_job *get_queued_job(struct fdp1_dev *fdp1)
706 {
707 return list_remove_job(fdp1, &fdp1->queued_job_list);
708 }
709
queue_hw_job(struct fdp1_dev * fdp1,struct fdp1_job * job)710 static void queue_hw_job(struct fdp1_dev *fdp1, struct fdp1_job *job)
711 {
712 list_add_job(fdp1, &fdp1->hw_job_list, job);
713 }
714
get_hw_queued_job(struct fdp1_dev * fdp1)715 static struct fdp1_job *get_hw_queued_job(struct fdp1_dev *fdp1)
716 {
717 return list_remove_job(fdp1, &fdp1->hw_job_list);
718 }
719
720 /*
721 * Buffer lists handling
722 */
fdp1_field_complete(struct fdp1_ctx * ctx,struct fdp1_field_buffer * fbuf)723 static void fdp1_field_complete(struct fdp1_ctx *ctx,
724 struct fdp1_field_buffer *fbuf)
725 {
726 /* job->previous may be on the first field */
727 if (!fbuf)
728 return;
729
730 if (fbuf->last_field)
731 v4l2_m2m_buf_done(fbuf->vb, VB2_BUF_STATE_DONE);
732 }
733
fdp1_queue_field(struct fdp1_ctx * ctx,struct fdp1_field_buffer * fbuf)734 static void fdp1_queue_field(struct fdp1_ctx *ctx,
735 struct fdp1_field_buffer *fbuf)
736 {
737 unsigned long flags;
738
739 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
740 list_add_tail(&fbuf->list, &ctx->fields_queue);
741 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
742
743 ctx->buffers_queued++;
744 }
745
fdp1_dequeue_field(struct fdp1_ctx * ctx)746 static struct fdp1_field_buffer *fdp1_dequeue_field(struct fdp1_ctx *ctx)
747 {
748 struct fdp1_field_buffer *fbuf;
749 unsigned long flags;
750
751 ctx->buffers_queued--;
752
753 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
754 fbuf = list_first_entry_or_null(&ctx->fields_queue,
755 struct fdp1_field_buffer, list);
756 if (fbuf)
757 list_del(&fbuf->list);
758 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
759
760 return fbuf;
761 }
762
763 /*
764 * Return the next field in the queue - or NULL,
765 * without removing the item from the list
766 */
fdp1_peek_queued_field(struct fdp1_ctx * ctx)767 static struct fdp1_field_buffer *fdp1_peek_queued_field(struct fdp1_ctx *ctx)
768 {
769 struct fdp1_field_buffer *fbuf;
770 unsigned long flags;
771
772 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
773 fbuf = list_first_entry_or_null(&ctx->fields_queue,
774 struct fdp1_field_buffer, list);
775 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
776
777 return fbuf;
778 }
779
fdp1_read(struct fdp1_dev * fdp1,unsigned int reg)780 static u32 fdp1_read(struct fdp1_dev *fdp1, unsigned int reg)
781 {
782 u32 value = ioread32(fdp1->regs + reg);
783
784 if (debug >= 2)
785 dprintk(fdp1, "Read 0x%08x from 0x%04x\n", value, reg);
786
787 return value;
788 }
789
fdp1_write(struct fdp1_dev * fdp1,u32 val,unsigned int reg)790 static void fdp1_write(struct fdp1_dev *fdp1, u32 val, unsigned int reg)
791 {
792 if (debug >= 2)
793 dprintk(fdp1, "Write 0x%08x to 0x%04x\n", val, reg);
794
795 iowrite32(val, fdp1->regs + reg);
796 }
797
798 /* IPC registers are to be programmed with constant values */
fdp1_set_ipc_dli(struct fdp1_ctx * ctx)799 static void fdp1_set_ipc_dli(struct fdp1_ctx *ctx)
800 {
801 struct fdp1_dev *fdp1 = ctx->fdp1;
802
803 fdp1_write(fdp1, FD1_IPC_SMSK_THRESH_CONST, FD1_IPC_SMSK_THRESH);
804 fdp1_write(fdp1, FD1_IPC_COMB_DET_CONST, FD1_IPC_COMB_DET);
805 fdp1_write(fdp1, FD1_IPC_MOTDEC_CONST, FD1_IPC_MOTDEC);
806
807 fdp1_write(fdp1, FD1_IPC_DLI_BLEND_CONST, FD1_IPC_DLI_BLEND);
808 fdp1_write(fdp1, FD1_IPC_DLI_HGAIN_CONST, FD1_IPC_DLI_HGAIN);
809 fdp1_write(fdp1, FD1_IPC_DLI_SPRS_CONST, FD1_IPC_DLI_SPRS);
810 fdp1_write(fdp1, FD1_IPC_DLI_ANGLE_CONST, FD1_IPC_DLI_ANGLE);
811 fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX0_CONST, FD1_IPC_DLI_ISOPIX0);
812 fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX1_CONST, FD1_IPC_DLI_ISOPIX1);
813 }
814
815
fdp1_set_ipc_sensor(struct fdp1_ctx * ctx)816 static void fdp1_set_ipc_sensor(struct fdp1_ctx *ctx)
817 {
818 struct fdp1_dev *fdp1 = ctx->fdp1;
819 struct fdp1_q_data *src_q_data = &ctx->out_q;
820 unsigned int x0, x1;
821 unsigned int hsize = src_q_data->format.width;
822 unsigned int vsize = src_q_data->format.height;
823
824 x0 = hsize / 3;
825 x1 = 2 * hsize / 3;
826
827 fdp1_write(fdp1, FD1_IPC_SENSOR_TH0_CONST, FD1_IPC_SENSOR_TH0);
828 fdp1_write(fdp1, FD1_IPC_SENSOR_TH1_CONST, FD1_IPC_SENSOR_TH1);
829 fdp1_write(fdp1, FD1_IPC_SENSOR_CTL0_CONST, FD1_IPC_SENSOR_CTL0);
830 fdp1_write(fdp1, FD1_IPC_SENSOR_CTL1_CONST, FD1_IPC_SENSOR_CTL1);
831
832 fdp1_write(fdp1, ((hsize - 1) << FD1_IPC_SENSOR_CTL2_X_SHIFT) |
833 ((vsize - 1) << FD1_IPC_SENSOR_CTL2_Y_SHIFT),
834 FD1_IPC_SENSOR_CTL2);
835
836 fdp1_write(fdp1, (x0 << FD1_IPC_SENSOR_CTL3_0_SHIFT) |
837 (x1 << FD1_IPC_SENSOR_CTL3_1_SHIFT),
838 FD1_IPC_SENSOR_CTL3);
839 }
840
841 /*
842 * fdp1_write_lut: Write a padded LUT to the hw
843 *
844 * FDP1 uses constant data for de-interlacing processing,
845 * with large tables. These hardware tables are all 256 bytes
846 * long, however they often contain repeated data at the end.
847 *
848 * The last byte of the table is written to all remaining entries.
849 */
fdp1_write_lut(struct fdp1_dev * fdp1,const u8 * lut,unsigned int len,unsigned int base)850 static void fdp1_write_lut(struct fdp1_dev *fdp1, const u8 *lut,
851 unsigned int len, unsigned int base)
852 {
853 unsigned int i;
854 u8 pad;
855
856 /* Tables larger than the hw are clipped */
857 len = min(len, 256u);
858
859 for (i = 0; i < len; i++)
860 fdp1_write(fdp1, lut[i], base + (i*4));
861
862 /* Tables are padded with the last entry */
863 pad = lut[i-1];
864
865 for (; i < 256; i++)
866 fdp1_write(fdp1, pad, base + (i*4));
867 }
868
fdp1_set_lut(struct fdp1_dev * fdp1)869 static void fdp1_set_lut(struct fdp1_dev *fdp1)
870 {
871 fdp1_write_lut(fdp1, fdp1_diff_adj, ARRAY_SIZE(fdp1_diff_adj),
872 FD1_LUT_DIF_ADJ);
873 fdp1_write_lut(fdp1, fdp1_sad_adj, ARRAY_SIZE(fdp1_sad_adj),
874 FD1_LUT_SAD_ADJ);
875 fdp1_write_lut(fdp1, fdp1_bld_gain, ARRAY_SIZE(fdp1_bld_gain),
876 FD1_LUT_BLD_GAIN);
877 fdp1_write_lut(fdp1, fdp1_dif_gain, ARRAY_SIZE(fdp1_dif_gain),
878 FD1_LUT_DIF_GAIN);
879 fdp1_write_lut(fdp1, fdp1_mdet, ARRAY_SIZE(fdp1_mdet),
880 FD1_LUT_MDET);
881 }
882
fdp1_configure_rpf(struct fdp1_ctx * ctx,struct fdp1_job * job)883 static void fdp1_configure_rpf(struct fdp1_ctx *ctx,
884 struct fdp1_job *job)
885 {
886 struct fdp1_dev *fdp1 = ctx->fdp1;
887 u32 picture_size;
888 u32 pstride;
889 u32 format;
890 u32 smsk_addr;
891
892 struct fdp1_q_data *q_data = &ctx->out_q;
893
894 /* Picture size is common to Source and Destination frames */
895 picture_size = (q_data->format.width << FD1_RPF_SIZE_H_SHIFT)
896 | (q_data->vsize << FD1_RPF_SIZE_V_SHIFT);
897
898 /* Strides */
899 pstride = q_data->stride_y << FD1_RPF_PSTRIDE_Y_SHIFT;
900 if (q_data->format.num_planes > 1)
901 pstride |= q_data->stride_c << FD1_RPF_PSTRIDE_C_SHIFT;
902
903 /* Format control */
904 format = q_data->fmt->fmt;
905 if (q_data->fmt->swap_yc)
906 format |= FD1_RPF_FORMAT_RSPYCS;
907
908 if (q_data->fmt->swap_uv)
909 format |= FD1_RPF_FORMAT_RSPUVS;
910
911 if (job->active->field == V4L2_FIELD_BOTTOM) {
912 format |= FD1_RPF_FORMAT_CF; /* Set for Bottom field */
913 smsk_addr = ctx->smsk_addr[0];
914 } else {
915 smsk_addr = ctx->smsk_addr[1];
916 }
917
918 /* Deint mode is non-zero when deinterlacing */
919 if (ctx->deint_mode)
920 format |= FD1_RPF_FORMAT_CIPM;
921
922 fdp1_write(fdp1, format, FD1_RPF_FORMAT);
923 fdp1_write(fdp1, q_data->fmt->swap, FD1_RPF_SWAP);
924 fdp1_write(fdp1, picture_size, FD1_RPF_SIZE);
925 fdp1_write(fdp1, pstride, FD1_RPF_PSTRIDE);
926 fdp1_write(fdp1, smsk_addr, FD1_RPF_SMSK_ADDR);
927
928 /* Previous Field Channel (CH0) */
929 if (job->previous)
930 fdp1_write(fdp1, job->previous->addrs[0], FD1_RPF0_ADDR_Y);
931
932 /* Current Field Channel (CH1) */
933 fdp1_write(fdp1, job->active->addrs[0], FD1_RPF1_ADDR_Y);
934 fdp1_write(fdp1, job->active->addrs[1], FD1_RPF1_ADDR_C0);
935 fdp1_write(fdp1, job->active->addrs[2], FD1_RPF1_ADDR_C1);
936
937 /* Next Field Channel (CH2) */
938 if (job->next)
939 fdp1_write(fdp1, job->next->addrs[0], FD1_RPF2_ADDR_Y);
940 }
941
fdp1_configure_wpf(struct fdp1_ctx * ctx,struct fdp1_job * job)942 static void fdp1_configure_wpf(struct fdp1_ctx *ctx,
943 struct fdp1_job *job)
944 {
945 struct fdp1_dev *fdp1 = ctx->fdp1;
946 struct fdp1_q_data *src_q_data = &ctx->out_q;
947 struct fdp1_q_data *q_data = &ctx->cap_q;
948 u32 pstride;
949 u32 format;
950 u32 swap;
951 u32 rndctl;
952
953 pstride = q_data->format.plane_fmt[0].bytesperline
954 << FD1_WPF_PSTRIDE_Y_SHIFT;
955
956 if (q_data->format.num_planes > 1)
957 pstride |= q_data->format.plane_fmt[1].bytesperline
958 << FD1_WPF_PSTRIDE_C_SHIFT;
959
960 format = q_data->fmt->fmt; /* Output Format Code */
961
962 if (q_data->fmt->swap_yc)
963 format |= FD1_WPF_FORMAT_WSPYCS;
964
965 if (q_data->fmt->swap_uv)
966 format |= FD1_WPF_FORMAT_WSPUVS;
967
968 if (fdp1_fmt_is_rgb(q_data->fmt)) {
969 /* Enable Colour Space conversion */
970 format |= FD1_WPF_FORMAT_CSC;
971
972 /* Set WRTM */
973 if (src_q_data->format.ycbcr_enc == V4L2_YCBCR_ENC_709)
974 format |= FD1_WPF_FORMAT_WRTM_709_16;
975 else if (src_q_data->format.quantization ==
976 V4L2_QUANTIZATION_FULL_RANGE)
977 format |= FD1_WPF_FORMAT_WRTM_601_0;
978 else
979 format |= FD1_WPF_FORMAT_WRTM_601_16;
980 }
981
982 /* Set an alpha value into the Pad Value */
983 format |= ctx->alpha << FD1_WPF_FORMAT_PDV_SHIFT;
984
985 /* Determine picture rounding and clipping */
986 rndctl = FD1_WPF_RNDCTL_CBRM; /* Rounding Off */
987 rndctl |= FD1_WPF_RNDCTL_CLMD_NOCLIP;
988
989 /* WPF Swap needs both ISWAP and OSWAP setting */
990 swap = q_data->fmt->swap << FD1_WPF_SWAP_OSWAP_SHIFT;
991 swap |= src_q_data->fmt->swap << FD1_WPF_SWAP_SSWAP_SHIFT;
992
993 fdp1_write(fdp1, format, FD1_WPF_FORMAT);
994 fdp1_write(fdp1, rndctl, FD1_WPF_RNDCTL);
995 fdp1_write(fdp1, swap, FD1_WPF_SWAP);
996 fdp1_write(fdp1, pstride, FD1_WPF_PSTRIDE);
997
998 fdp1_write(fdp1, job->dst->addrs[0], FD1_WPF_ADDR_Y);
999 fdp1_write(fdp1, job->dst->addrs[1], FD1_WPF_ADDR_C0);
1000 fdp1_write(fdp1, job->dst->addrs[2], FD1_WPF_ADDR_C1);
1001 }
1002
fdp1_configure_deint_mode(struct fdp1_ctx * ctx,struct fdp1_job * job)1003 static void fdp1_configure_deint_mode(struct fdp1_ctx *ctx,
1004 struct fdp1_job *job)
1005 {
1006 struct fdp1_dev *fdp1 = ctx->fdp1;
1007 u32 opmode = FD1_CTL_OPMODE_VIMD_NOINTERRUPT;
1008 u32 ipcmode = FD1_IPC_MODE_DLI; /* Always set */
1009 u32 channels = FD1_CTL_CHACT_WR | FD1_CTL_CHACT_RD1; /* Always on */
1010
1011 /* De-interlacing Mode */
1012 switch (ctx->deint_mode) {
1013 default:
1014 case FDP1_PROGRESSIVE:
1015 dprintk(fdp1, "Progressive Mode\n");
1016 opmode |= FD1_CTL_OPMODE_PRG;
1017 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1018 break;
1019 case FDP1_ADAPT2D3D:
1020 dprintk(fdp1, "Adapt2D3D Mode\n");
1021 if (ctx->sequence == 0 || ctx->aborting)
1022 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1023 else
1024 ipcmode |= FD1_IPC_MODE_DIM_ADAPT2D3D;
1025
1026 if (ctx->sequence > 1) {
1027 channels |= FD1_CTL_CHACT_SMW;
1028 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2;
1029 }
1030
1031 if (ctx->sequence > 2)
1032 channels |= FD1_CTL_CHACT_SMR;
1033
1034 break;
1035 case FDP1_FIXED3D:
1036 dprintk(fdp1, "Fixed 3D Mode\n");
1037 ipcmode |= FD1_IPC_MODE_DIM_FIXED3D;
1038 /* Except for first and last frame, enable all channels */
1039 if (!(ctx->sequence == 0 || ctx->aborting))
1040 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2;
1041 break;
1042 case FDP1_FIXED2D:
1043 dprintk(fdp1, "Fixed 2D Mode\n");
1044 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1045 /* No extra channels enabled */
1046 break;
1047 case FDP1_PREVFIELD:
1048 dprintk(fdp1, "Previous Field Mode\n");
1049 ipcmode |= FD1_IPC_MODE_DIM_PREVFIELD;
1050 channels |= FD1_CTL_CHACT_RD0; /* Previous */
1051 break;
1052 case FDP1_NEXTFIELD:
1053 dprintk(fdp1, "Next Field Mode\n");
1054 ipcmode |= FD1_IPC_MODE_DIM_NEXTFIELD;
1055 channels |= FD1_CTL_CHACT_RD2; /* Next */
1056 break;
1057 }
1058
1059 fdp1_write(fdp1, channels, FD1_CTL_CHACT);
1060 fdp1_write(fdp1, opmode, FD1_CTL_OPMODE);
1061 fdp1_write(fdp1, ipcmode, FD1_IPC_MODE);
1062 }
1063
1064 /*
1065 * fdp1_device_process() - Run the hardware
1066 *
1067 * Configure and start the hardware to generate a single frame
1068 * of output given our input parameters.
1069 */
fdp1_device_process(struct fdp1_ctx * ctx)1070 static int fdp1_device_process(struct fdp1_ctx *ctx)
1071
1072 {
1073 struct fdp1_dev *fdp1 = ctx->fdp1;
1074 struct fdp1_job *job;
1075 unsigned long flags;
1076
1077 spin_lock_irqsave(&fdp1->device_process_lock, flags);
1078
1079 /* Get a job to process */
1080 job = get_queued_job(fdp1);
1081 if (!job) {
1082 /*
1083 * VINT can call us to see if we can queue another job.
1084 * If we have no work to do, we simply return.
1085 */
1086 spin_unlock_irqrestore(&fdp1->device_process_lock, flags);
1087 return 0;
1088 }
1089
1090 /* First Frame only? ... */
1091 fdp1_write(fdp1, FD1_CTL_CLKCTRL_CSTP_N, FD1_CTL_CLKCTRL);
1092
1093 /* Set the mode, and configuration */
1094 fdp1_configure_deint_mode(ctx, job);
1095
1096 /* DLI Static Configuration */
1097 fdp1_set_ipc_dli(ctx);
1098
1099 /* Sensor Configuration */
1100 fdp1_set_ipc_sensor(ctx);
1101
1102 /* Setup the source picture */
1103 fdp1_configure_rpf(ctx, job);
1104
1105 /* Setup the destination picture */
1106 fdp1_configure_wpf(ctx, job);
1107
1108 /* Line Memory Pixel Number Register for linear access */
1109 fdp1_write(fdp1, FD1_IPC_LMEM_LINEAR, FD1_IPC_LMEM);
1110
1111 /* Enable Interrupts */
1112 fdp1_write(fdp1, FD1_CTL_IRQ_MASK, FD1_CTL_IRQENB);
1113
1114 /* Finally, the Immediate Registers */
1115
1116 /* This job is now in the HW queue */
1117 queue_hw_job(fdp1, job);
1118
1119 /* Start the command */
1120 fdp1_write(fdp1, FD1_CTL_CMD_STRCMD, FD1_CTL_CMD);
1121
1122 /* Registers will update to HW at next VINT */
1123 fdp1_write(fdp1, FD1_CTL_REGEND_REGEND, FD1_CTL_REGEND);
1124
1125 /* Enable VINT Generator */
1126 fdp1_write(fdp1, FD1_CTL_SGCMD_SGEN, FD1_CTL_SGCMD);
1127
1128 spin_unlock_irqrestore(&fdp1->device_process_lock, flags);
1129
1130 return 0;
1131 }
1132
1133 /*
1134 * mem2mem callbacks
1135 */
1136
1137 /**
1138 * job_ready() - check whether an instance is ready to be scheduled to run
1139 */
fdp1_m2m_job_ready(void * priv)1140 static int fdp1_m2m_job_ready(void *priv)
1141 {
1142 struct fdp1_ctx *ctx = priv;
1143 struct fdp1_q_data *src_q_data = &ctx->out_q;
1144 int srcbufs = 1;
1145 int dstbufs = 1;
1146
1147 dprintk(ctx->fdp1, "+ Src: %d : Dst: %d\n",
1148 v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx),
1149 v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx));
1150
1151 /* One output buffer is required for each field */
1152 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
1153 dstbufs = 2;
1154
1155 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < srcbufs
1156 || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < dstbufs) {
1157 dprintk(ctx->fdp1, "Not enough buffers available\n");
1158 return 0;
1159 }
1160
1161 return 1;
1162 }
1163
fdp1_m2m_job_abort(void * priv)1164 static void fdp1_m2m_job_abort(void *priv)
1165 {
1166 struct fdp1_ctx *ctx = priv;
1167
1168 dprintk(ctx->fdp1, "+\n");
1169
1170 /* Will cancel the transaction in the next interrupt handler */
1171 ctx->aborting = 1;
1172
1173 /* Immediate abort sequence */
1174 fdp1_write(ctx->fdp1, 0, FD1_CTL_SGCMD);
1175 fdp1_write(ctx->fdp1, FD1_CTL_SRESET_SRST, FD1_CTL_SRESET);
1176 }
1177
1178 /*
1179 * fdp1_prepare_job: Prepare and queue a new job for a single action of work
1180 *
1181 * Prepare the next field, (or frame in progressive) and an output
1182 * buffer for the hardware to perform a single operation.
1183 */
fdp1_prepare_job(struct fdp1_ctx * ctx)1184 static struct fdp1_job *fdp1_prepare_job(struct fdp1_ctx *ctx)
1185 {
1186 struct vb2_v4l2_buffer *vbuf;
1187 struct fdp1_buffer *fbuf;
1188 struct fdp1_dev *fdp1 = ctx->fdp1;
1189 struct fdp1_job *job;
1190 unsigned int buffers_required = 1;
1191
1192 dprintk(fdp1, "+\n");
1193
1194 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode))
1195 buffers_required = 2;
1196
1197 if (ctx->buffers_queued < buffers_required)
1198 return NULL;
1199
1200 job = fdp1_job_alloc(fdp1);
1201 if (!job) {
1202 dprintk(fdp1, "No free jobs currently available\n");
1203 return NULL;
1204 }
1205
1206 job->active = fdp1_dequeue_field(ctx);
1207 if (!job->active) {
1208 /* Buffer check should prevent this ever happening */
1209 dprintk(fdp1, "No input buffers currently available\n");
1210
1211 fdp1_job_free(fdp1, job);
1212 return NULL;
1213 }
1214
1215 dprintk(fdp1, "+ Buffer en-route...\n");
1216
1217 /* Source buffers have been prepared on our buffer_queue
1218 * Prepare our Output buffer
1219 */
1220 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1221 fbuf = to_fdp1_buffer(vbuf);
1222 job->dst = &fbuf->fields[0];
1223
1224 job->active->vb->sequence = ctx->sequence;
1225 job->dst->vb->sequence = ctx->sequence;
1226 ctx->sequence++;
1227
1228 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) {
1229 job->previous = ctx->previous;
1230
1231 /* Active buffer becomes the next job's previous buffer */
1232 ctx->previous = job->active;
1233 }
1234
1235 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode)) {
1236 /* Must be called after 'active' is dequeued */
1237 job->next = fdp1_peek_queued_field(ctx);
1238 }
1239
1240 /* Transfer timestamps and flags from src->dst */
1241
1242 job->dst->vb->vb2_buf.timestamp = job->active->vb->vb2_buf.timestamp;
1243
1244 job->dst->vb->flags = job->active->vb->flags &
1245 V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
1246
1247 /* Ideally, the frame-end function will just 'check' to see
1248 * if there are more jobs instead
1249 */
1250 ctx->translen++;
1251
1252 /* Finally, Put this job on the processing queue */
1253 queue_job(fdp1, job);
1254
1255 dprintk(fdp1, "Job Queued translen = %d\n", ctx->translen);
1256
1257 return job;
1258 }
1259
1260 /* fdp1_m2m_device_run() - prepares and starts the device for an M2M task
1261 *
1262 * A single input buffer is taken and serialised into our fdp1_buffer
1263 * queue. The queue is then processed to create as many jobs as possible
1264 * from our available input.
1265 */
fdp1_m2m_device_run(void * priv)1266 static void fdp1_m2m_device_run(void *priv)
1267 {
1268 struct fdp1_ctx *ctx = priv;
1269 struct fdp1_dev *fdp1 = ctx->fdp1;
1270 struct vb2_v4l2_buffer *src_vb;
1271 struct fdp1_buffer *buf;
1272 unsigned int i;
1273
1274 dprintk(fdp1, "+\n");
1275
1276 ctx->translen = 0;
1277
1278 /* Get our incoming buffer of either one or two fields, or one frame */
1279 src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1280 buf = to_fdp1_buffer(src_vb);
1281
1282 for (i = 0; i < buf->num_fields; i++) {
1283 struct fdp1_field_buffer *fbuf = &buf->fields[i];
1284
1285 fdp1_queue_field(ctx, fbuf);
1286 dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n",
1287 i, fbuf->last_field);
1288 }
1289
1290 /* Queue as many jobs as our data provides for */
1291 while (fdp1_prepare_job(ctx))
1292 ;
1293
1294 if (ctx->translen == 0) {
1295 dprintk(fdp1, "No jobs were processed. M2M action complete\n");
1296 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx);
1297 return;
1298 }
1299
1300 /* Kick the job processing action */
1301 fdp1_device_process(ctx);
1302 }
1303
1304 /*
1305 * device_frame_end:
1306 *
1307 * Handles the M2M level after a buffer completion event.
1308 */
device_frame_end(struct fdp1_dev * fdp1,enum vb2_buffer_state state)1309 static void device_frame_end(struct fdp1_dev *fdp1,
1310 enum vb2_buffer_state state)
1311 {
1312 struct fdp1_ctx *ctx;
1313 unsigned long flags;
1314 struct fdp1_job *job = get_hw_queued_job(fdp1);
1315
1316 dprintk(fdp1, "+\n");
1317
1318 ctx = v4l2_m2m_get_curr_priv(fdp1->m2m_dev);
1319
1320 if (ctx == NULL) {
1321 v4l2_err(&fdp1->v4l2_dev,
1322 "Instance released before the end of transaction\n");
1323 return;
1324 }
1325
1326 ctx->num_processed++;
1327
1328 /*
1329 * fdp1_field_complete will call buf_done only when the last vb2_buffer
1330 * reference is complete
1331 */
1332 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
1333 fdp1_field_complete(ctx, job->previous);
1334 else
1335 fdp1_field_complete(ctx, job->active);
1336
1337 spin_lock_irqsave(&fdp1->irqlock, flags);
1338 v4l2_m2m_buf_done(job->dst->vb, state);
1339 job->dst = NULL;
1340 spin_unlock_irqrestore(&fdp1->irqlock, flags);
1341
1342 /* Move this job back to the free job list */
1343 fdp1_job_free(fdp1, job);
1344
1345 dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n",
1346 ctx->num_processed, ctx->translen);
1347
1348 if (ctx->num_processed == ctx->translen ||
1349 ctx->aborting) {
1350 dprintk(ctx->fdp1, "Finishing transaction\n");
1351 ctx->num_processed = 0;
1352 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx);
1353 } else {
1354 /*
1355 * For pipelined performance support, this would
1356 * be called from a VINT handler
1357 */
1358 fdp1_device_process(ctx);
1359 }
1360 }
1361
1362 /*
1363 * video ioctls
1364 */
fdp1_vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)1365 static int fdp1_vidioc_querycap(struct file *file, void *priv,
1366 struct v4l2_capability *cap)
1367 {
1368 strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
1369 strlcpy(cap->card, DRIVER_NAME, sizeof(cap->card));
1370 snprintf(cap->bus_info, sizeof(cap->bus_info),
1371 "platform:%s", DRIVER_NAME);
1372 return 0;
1373 }
1374
fdp1_enum_fmt(struct v4l2_fmtdesc * f,u32 type)1375 static int fdp1_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
1376 {
1377 unsigned int i, num;
1378
1379 num = 0;
1380
1381 for (i = 0; i < ARRAY_SIZE(fdp1_formats); ++i) {
1382 if (fdp1_formats[i].types & type) {
1383 if (num == f->index)
1384 break;
1385 ++num;
1386 }
1387 }
1388
1389 /* Format not found */
1390 if (i >= ARRAY_SIZE(fdp1_formats))
1391 return -EINVAL;
1392
1393 /* Format found */
1394 f->pixelformat = fdp1_formats[i].fourcc;
1395
1396 return 0;
1397 }
1398
fdp1_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)1399 static int fdp1_enum_fmt_vid_cap(struct file *file, void *priv,
1400 struct v4l2_fmtdesc *f)
1401 {
1402 return fdp1_enum_fmt(f, FDP1_CAPTURE);
1403 }
1404
fdp1_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)1405 static int fdp1_enum_fmt_vid_out(struct file *file, void *priv,
1406 struct v4l2_fmtdesc *f)
1407 {
1408 return fdp1_enum_fmt(f, FDP1_OUTPUT);
1409 }
1410
fdp1_g_fmt(struct file * file,void * priv,struct v4l2_format * f)1411 static int fdp1_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1412 {
1413 struct fdp1_q_data *q_data;
1414 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1415
1416 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
1417 return -EINVAL;
1418
1419 q_data = get_q_data(ctx, f->type);
1420 f->fmt.pix_mp = q_data->format;
1421
1422 return 0;
1423 }
1424
fdp1_compute_stride(struct v4l2_pix_format_mplane * pix,const struct fdp1_fmt * fmt)1425 static void fdp1_compute_stride(struct v4l2_pix_format_mplane *pix,
1426 const struct fdp1_fmt *fmt)
1427 {
1428 unsigned int i;
1429
1430 /* Compute and clamp the stride and image size. */
1431 for (i = 0; i < min_t(unsigned int, fmt->num_planes, 2U); ++i) {
1432 unsigned int hsub = i > 0 ? fmt->hsub : 1;
1433 unsigned int vsub = i > 0 ? fmt->vsub : 1;
1434 /* From VSP : TODO: Confirm alignment limits for FDP1 */
1435 unsigned int align = 128;
1436 unsigned int bpl;
1437
1438 bpl = clamp_t(unsigned int, pix->plane_fmt[i].bytesperline,
1439 pix->width / hsub * fmt->bpp[i] / 8,
1440 round_down(FDP1_MAX_STRIDE, align));
1441
1442 pix->plane_fmt[i].bytesperline = round_up(bpl, align);
1443 pix->plane_fmt[i].sizeimage = pix->plane_fmt[i].bytesperline
1444 * pix->height / vsub;
1445
1446 memset(pix->plane_fmt[i].reserved, 0,
1447 sizeof(pix->plane_fmt[i].reserved));
1448 }
1449
1450 if (fmt->num_planes == 3) {
1451 /* The two chroma planes must have the same stride. */
1452 pix->plane_fmt[2].bytesperline = pix->plane_fmt[1].bytesperline;
1453 pix->plane_fmt[2].sizeimage = pix->plane_fmt[1].sizeimage;
1454
1455 memset(pix->plane_fmt[2].reserved, 0,
1456 sizeof(pix->plane_fmt[2].reserved));
1457 }
1458 }
1459
fdp1_try_fmt_output(struct fdp1_ctx * ctx,const struct fdp1_fmt ** fmtinfo,struct v4l2_pix_format_mplane * pix)1460 static void fdp1_try_fmt_output(struct fdp1_ctx *ctx,
1461 const struct fdp1_fmt **fmtinfo,
1462 struct v4l2_pix_format_mplane *pix)
1463 {
1464 const struct fdp1_fmt *fmt;
1465 unsigned int width;
1466 unsigned int height;
1467
1468 /* Validate the pixel format to ensure the output queue supports it. */
1469 fmt = fdp1_find_format(pix->pixelformat);
1470 if (!fmt || !(fmt->types & FDP1_OUTPUT))
1471 fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV);
1472
1473 if (fmtinfo)
1474 *fmtinfo = fmt;
1475
1476 pix->pixelformat = fmt->fourcc;
1477 pix->num_planes = fmt->num_planes;
1478
1479 /*
1480 * Progressive video and all interlaced field orders are acceptable.
1481 * Default to V4L2_FIELD_INTERLACED.
1482 */
1483 if (pix->field != V4L2_FIELD_NONE &&
1484 pix->field != V4L2_FIELD_ALTERNATE &&
1485 !V4L2_FIELD_HAS_BOTH(pix->field))
1486 pix->field = V4L2_FIELD_INTERLACED;
1487
1488 /*
1489 * The deinterlacer doesn't care about the colorspace, accept all values
1490 * and default to V4L2_COLORSPACE_SMPTE170M. The YUV to RGB conversion
1491 * at the output of the deinterlacer supports a subset of encodings and
1492 * quantization methods and will only be available when the colorspace
1493 * allows it.
1494 */
1495 if (pix->colorspace == V4L2_COLORSPACE_DEFAULT)
1496 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1497
1498 /*
1499 * Align the width and height for YUV 4:2:2 and 4:2:0 formats and clamp
1500 * them to the supported frame size range. The height boundary are
1501 * related to the full frame, divide them by two when the format passes
1502 * fields in separate buffers.
1503 */
1504 width = round_down(pix->width, fmt->hsub);
1505 pix->width = clamp(width, FDP1_MIN_W, FDP1_MAX_W);
1506
1507 height = round_down(pix->height, fmt->vsub);
1508 if (pix->field == V4L2_FIELD_ALTERNATE)
1509 pix->height = clamp(height, FDP1_MIN_H / 2, FDP1_MAX_H / 2);
1510 else
1511 pix->height = clamp(height, FDP1_MIN_H, FDP1_MAX_H);
1512
1513 fdp1_compute_stride(pix, fmt);
1514 }
1515
fdp1_try_fmt_capture(struct fdp1_ctx * ctx,const struct fdp1_fmt ** fmtinfo,struct v4l2_pix_format_mplane * pix)1516 static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx,
1517 const struct fdp1_fmt **fmtinfo,
1518 struct v4l2_pix_format_mplane *pix)
1519 {
1520 struct fdp1_q_data *src_data = &ctx->out_q;
1521 enum v4l2_colorspace colorspace;
1522 enum v4l2_ycbcr_encoding ycbcr_enc;
1523 enum v4l2_quantization quantization;
1524 const struct fdp1_fmt *fmt;
1525 bool allow_rgb;
1526
1527 /*
1528 * Validate the pixel format. We can only accept RGB output formats if
1529 * the input encoding and quantization are compatible with the format
1530 * conversions supported by the hardware. The supported combinations are
1531 *
1532 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_LIM_RANGE
1533 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_FULL_RANGE
1534 * V4L2_YCBCR_ENC_709 + V4L2_QUANTIZATION_LIM_RANGE
1535 */
1536 colorspace = src_data->format.colorspace;
1537
1538 ycbcr_enc = src_data->format.ycbcr_enc;
1539 if (ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1540 ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(colorspace);
1541
1542 quantization = src_data->format.quantization;
1543 if (quantization == V4L2_QUANTIZATION_DEFAULT)
1544 quantization = V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace,
1545 ycbcr_enc);
1546
1547 allow_rgb = ycbcr_enc == V4L2_YCBCR_ENC_601 ||
1548 (ycbcr_enc == V4L2_YCBCR_ENC_709 &&
1549 quantization == V4L2_QUANTIZATION_LIM_RANGE);
1550
1551 fmt = fdp1_find_format(pix->pixelformat);
1552 if (!fmt || (!allow_rgb && fdp1_fmt_is_rgb(fmt)))
1553 fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV);
1554
1555 if (fmtinfo)
1556 *fmtinfo = fmt;
1557
1558 pix->pixelformat = fmt->fourcc;
1559 pix->num_planes = fmt->num_planes;
1560 pix->field = V4L2_FIELD_NONE;
1561
1562 /*
1563 * The colorspace on the capture queue is copied from the output queue
1564 * as the hardware can't change the colorspace. It can convert YCbCr to
1565 * RGB though, in which case the encoding and quantization are set to
1566 * default values as anything else wouldn't make sense.
1567 */
1568 pix->colorspace = src_data->format.colorspace;
1569 pix->xfer_func = src_data->format.xfer_func;
1570
1571 if (fdp1_fmt_is_rgb(fmt)) {
1572 pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1573 pix->quantization = V4L2_QUANTIZATION_DEFAULT;
1574 } else {
1575 pix->ycbcr_enc = src_data->format.ycbcr_enc;
1576 pix->quantization = src_data->format.quantization;
1577 }
1578
1579 /*
1580 * The frame width is identical to the output queue, and the height is
1581 * either doubled or identical depending on whether the output queue
1582 * field order contains one or two fields per frame.
1583 */
1584 pix->width = src_data->format.width;
1585 if (src_data->format.field == V4L2_FIELD_ALTERNATE)
1586 pix->height = 2 * src_data->format.height;
1587 else
1588 pix->height = src_data->format.height;
1589
1590 fdp1_compute_stride(pix, fmt);
1591 }
1592
fdp1_try_fmt(struct file * file,void * priv,struct v4l2_format * f)1593 static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1594 {
1595 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1596
1597 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1598 fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp);
1599 else
1600 fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp);
1601
1602 dprintk(ctx->fdp1, "Try %s format: %4.4s (0x%08x) %ux%u field %u\n",
1603 V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
1604 (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
1605 f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
1606
1607 return 0;
1608 }
1609
fdp1_set_format(struct fdp1_ctx * ctx,struct v4l2_pix_format_mplane * pix,enum v4l2_buf_type type)1610 static void fdp1_set_format(struct fdp1_ctx *ctx,
1611 struct v4l2_pix_format_mplane *pix,
1612 enum v4l2_buf_type type)
1613 {
1614 struct fdp1_q_data *q_data = get_q_data(ctx, type);
1615 const struct fdp1_fmt *fmtinfo;
1616
1617 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1618 fdp1_try_fmt_output(ctx, &fmtinfo, pix);
1619 else
1620 fdp1_try_fmt_capture(ctx, &fmtinfo, pix);
1621
1622 q_data->fmt = fmtinfo;
1623 q_data->format = *pix;
1624
1625 q_data->vsize = pix->height;
1626 if (pix->field != V4L2_FIELD_NONE)
1627 q_data->vsize /= 2;
1628
1629 q_data->stride_y = pix->plane_fmt[0].bytesperline;
1630 q_data->stride_c = pix->plane_fmt[1].bytesperline;
1631
1632 /* Adjust strides for interleaved buffers */
1633 if (pix->field == V4L2_FIELD_INTERLACED ||
1634 pix->field == V4L2_FIELD_INTERLACED_TB ||
1635 pix->field == V4L2_FIELD_INTERLACED_BT) {
1636 q_data->stride_y *= 2;
1637 q_data->stride_c *= 2;
1638 }
1639
1640 /* Propagate the format from the output node to the capture node. */
1641 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1642 struct fdp1_q_data *dst_data = &ctx->cap_q;
1643
1644 /*
1645 * Copy the format, clear the per-plane bytes per line and image
1646 * size, override the field and double the height if needed.
1647 */
1648 dst_data->format = q_data->format;
1649 memset(dst_data->format.plane_fmt, 0,
1650 sizeof(dst_data->format.plane_fmt));
1651
1652 dst_data->format.field = V4L2_FIELD_NONE;
1653 if (pix->field == V4L2_FIELD_ALTERNATE)
1654 dst_data->format.height *= 2;
1655
1656 fdp1_try_fmt_capture(ctx, &dst_data->fmt, &dst_data->format);
1657
1658 dst_data->vsize = dst_data->format.height;
1659 dst_data->stride_y = dst_data->format.plane_fmt[0].bytesperline;
1660 dst_data->stride_c = dst_data->format.plane_fmt[1].bytesperline;
1661 }
1662 }
1663
fdp1_s_fmt(struct file * file,void * priv,struct v4l2_format * f)1664 static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
1665 {
1666 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1667 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
1668 struct vb2_queue *vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
1669
1670 if (vb2_is_busy(vq)) {
1671 v4l2_err(&ctx->fdp1->v4l2_dev, "%s queue busy\n", __func__);
1672 return -EBUSY;
1673 }
1674
1675 fdp1_set_format(ctx, &f->fmt.pix_mp, f->type);
1676
1677 dprintk(ctx->fdp1, "Set %s format: %4.4s (0x%08x) %ux%u field %u\n",
1678 V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
1679 (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
1680 f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
1681
1682 return 0;
1683 }
1684
fdp1_g_ctrl(struct v4l2_ctrl * ctrl)1685 static int fdp1_g_ctrl(struct v4l2_ctrl *ctrl)
1686 {
1687 struct fdp1_ctx *ctx =
1688 container_of(ctrl->handler, struct fdp1_ctx, hdl);
1689 struct fdp1_q_data *src_q_data = &ctx->out_q;
1690
1691 switch (ctrl->id) {
1692 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1693 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
1694 ctrl->val = 2;
1695 else
1696 ctrl->val = 1;
1697 return 0;
1698 }
1699
1700 return 1;
1701 }
1702
fdp1_s_ctrl(struct v4l2_ctrl * ctrl)1703 static int fdp1_s_ctrl(struct v4l2_ctrl *ctrl)
1704 {
1705 struct fdp1_ctx *ctx =
1706 container_of(ctrl->handler, struct fdp1_ctx, hdl);
1707
1708 switch (ctrl->id) {
1709 case V4L2_CID_ALPHA_COMPONENT:
1710 ctx->alpha = ctrl->val;
1711 break;
1712
1713 case V4L2_CID_DEINTERLACING_MODE:
1714 ctx->deint_mode = ctrl->val;
1715 break;
1716 }
1717
1718 return 0;
1719 }
1720
1721 static const struct v4l2_ctrl_ops fdp1_ctrl_ops = {
1722 .s_ctrl = fdp1_s_ctrl,
1723 .g_volatile_ctrl = fdp1_g_ctrl,
1724 };
1725
1726 static const char * const fdp1_ctrl_deint_menu[] = {
1727 "Progressive",
1728 "Adaptive 2D/3D",
1729 "Fixed 2D",
1730 "Fixed 3D",
1731 "Previous field",
1732 "Next field",
1733 NULL
1734 };
1735
1736 static const struct v4l2_ioctl_ops fdp1_ioctl_ops = {
1737 .vidioc_querycap = fdp1_vidioc_querycap,
1738
1739 .vidioc_enum_fmt_vid_cap_mplane = fdp1_enum_fmt_vid_cap,
1740 .vidioc_enum_fmt_vid_out_mplane = fdp1_enum_fmt_vid_out,
1741 .vidioc_g_fmt_vid_cap_mplane = fdp1_g_fmt,
1742 .vidioc_g_fmt_vid_out_mplane = fdp1_g_fmt,
1743 .vidioc_try_fmt_vid_cap_mplane = fdp1_try_fmt,
1744 .vidioc_try_fmt_vid_out_mplane = fdp1_try_fmt,
1745 .vidioc_s_fmt_vid_cap_mplane = fdp1_s_fmt,
1746 .vidioc_s_fmt_vid_out_mplane = fdp1_s_fmt,
1747
1748 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1749 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1750 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1751 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1752 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
1753 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
1754 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
1755
1756 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1757 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1758
1759 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1760 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1761 };
1762
1763 /*
1764 * Queue operations
1765 */
1766
fdp1_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_ctxs[])1767 static int fdp1_queue_setup(struct vb2_queue *vq,
1768 unsigned int *nbuffers, unsigned int *nplanes,
1769 unsigned int sizes[],
1770 struct device *alloc_ctxs[])
1771 {
1772 struct fdp1_ctx *ctx = vb2_get_drv_priv(vq);
1773 struct fdp1_q_data *q_data;
1774 unsigned int i;
1775
1776 q_data = get_q_data(ctx, vq->type);
1777
1778 if (*nplanes) {
1779 if (*nplanes > FDP1_MAX_PLANES)
1780 return -EINVAL;
1781
1782 return 0;
1783 }
1784
1785 *nplanes = q_data->format.num_planes;
1786
1787 for (i = 0; i < *nplanes; i++)
1788 sizes[i] = q_data->format.plane_fmt[i].sizeimage;
1789
1790 return 0;
1791 }
1792
fdp1_buf_prepare_field(struct fdp1_q_data * q_data,struct vb2_v4l2_buffer * vbuf,unsigned int field_num)1793 static void fdp1_buf_prepare_field(struct fdp1_q_data *q_data,
1794 struct vb2_v4l2_buffer *vbuf,
1795 unsigned int field_num)
1796 {
1797 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1798 struct fdp1_field_buffer *fbuf = &buf->fields[field_num];
1799 unsigned int num_fields;
1800 unsigned int i;
1801
1802 num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1803
1804 fbuf->vb = vbuf;
1805 fbuf->last_field = (field_num + 1) == num_fields;
1806
1807 for (i = 0; i < vbuf->vb2_buf.num_planes; ++i)
1808 fbuf->addrs[i] = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, i);
1809
1810 switch (vbuf->field) {
1811 case V4L2_FIELD_INTERLACED:
1812 /*
1813 * Interlaced means bottom-top for 60Hz TV standards (NTSC) and
1814 * top-bottom for 50Hz. As TV standards are not applicable to
1815 * the mem-to-mem API, use the height as a heuristic.
1816 */
1817 fbuf->field = (q_data->format.height < 576) == field_num
1818 ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1819 break;
1820 case V4L2_FIELD_INTERLACED_TB:
1821 case V4L2_FIELD_SEQ_TB:
1822 fbuf->field = field_num ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
1823 break;
1824 case V4L2_FIELD_INTERLACED_BT:
1825 case V4L2_FIELD_SEQ_BT:
1826 fbuf->field = field_num ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1827 break;
1828 default:
1829 fbuf->field = vbuf->field;
1830 break;
1831 }
1832
1833 /* Buffer is completed */
1834 if (!field_num)
1835 return;
1836
1837 /* Adjust buffer addresses for second field */
1838 switch (vbuf->field) {
1839 case V4L2_FIELD_INTERLACED:
1840 case V4L2_FIELD_INTERLACED_TB:
1841 case V4L2_FIELD_INTERLACED_BT:
1842 for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
1843 fbuf->addrs[i] +=
1844 (i == 0 ? q_data->stride_y : q_data->stride_c);
1845 break;
1846 case V4L2_FIELD_SEQ_TB:
1847 case V4L2_FIELD_SEQ_BT:
1848 for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
1849 fbuf->addrs[i] += q_data->vsize *
1850 (i == 0 ? q_data->stride_y : q_data->stride_c);
1851 break;
1852 }
1853 }
1854
fdp1_buf_prepare(struct vb2_buffer * vb)1855 static int fdp1_buf_prepare(struct vb2_buffer *vb)
1856 {
1857 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1858 struct fdp1_q_data *q_data = get_q_data(ctx, vb->vb2_queue->type);
1859 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1860 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1861 unsigned int i;
1862
1863 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1864 bool field_valid = true;
1865
1866 /* Validate the buffer field. */
1867 switch (q_data->format.field) {
1868 case V4L2_FIELD_NONE:
1869 if (vbuf->field != V4L2_FIELD_NONE)
1870 field_valid = false;
1871 break;
1872
1873 case V4L2_FIELD_ALTERNATE:
1874 if (vbuf->field != V4L2_FIELD_TOP &&
1875 vbuf->field != V4L2_FIELD_BOTTOM)
1876 field_valid = false;
1877 break;
1878
1879 case V4L2_FIELD_INTERLACED:
1880 case V4L2_FIELD_SEQ_TB:
1881 case V4L2_FIELD_SEQ_BT:
1882 case V4L2_FIELD_INTERLACED_TB:
1883 case V4L2_FIELD_INTERLACED_BT:
1884 if (vbuf->field != q_data->format.field)
1885 field_valid = false;
1886 break;
1887 }
1888
1889 if (!field_valid) {
1890 dprintk(ctx->fdp1,
1891 "buffer field %u invalid for format field %u\n",
1892 vbuf->field, q_data->format.field);
1893 return -EINVAL;
1894 }
1895 } else {
1896 vbuf->field = V4L2_FIELD_NONE;
1897 }
1898
1899 /* Validate the planes sizes. */
1900 for (i = 0; i < q_data->format.num_planes; i++) {
1901 unsigned long size = q_data->format.plane_fmt[i].sizeimage;
1902
1903 if (vb2_plane_size(vb, i) < size) {
1904 dprintk(ctx->fdp1,
1905 "data will not fit into plane [%u/%u] (%lu < %lu)\n",
1906 i, q_data->format.num_planes,
1907 vb2_plane_size(vb, i), size);
1908 return -EINVAL;
1909 }
1910
1911 /* We have known size formats all around */
1912 vb2_set_plane_payload(vb, i, size);
1913 }
1914
1915 buf->num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1916 for (i = 0; i < buf->num_fields; ++i)
1917 fdp1_buf_prepare_field(q_data, vbuf, i);
1918
1919 return 0;
1920 }
1921
fdp1_buf_queue(struct vb2_buffer * vb)1922 static void fdp1_buf_queue(struct vb2_buffer *vb)
1923 {
1924 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1925 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1926
1927 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1928 }
1929
fdp1_start_streaming(struct vb2_queue * q,unsigned int count)1930 static int fdp1_start_streaming(struct vb2_queue *q, unsigned int count)
1931 {
1932 struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1933 struct fdp1_q_data *q_data = get_q_data(ctx, q->type);
1934
1935 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1936 /*
1937 * Force our deint_mode when we are progressive,
1938 * ignoring any setting on the device from the user,
1939 * Otherwise, lock in the requested de-interlace mode.
1940 */
1941 if (q_data->format.field == V4L2_FIELD_NONE)
1942 ctx->deint_mode = FDP1_PROGRESSIVE;
1943
1944 if (ctx->deint_mode == FDP1_ADAPT2D3D) {
1945 u32 stride;
1946 dma_addr_t smsk_base;
1947 const u32 bpp = 2; /* bytes per pixel */
1948
1949 stride = round_up(q_data->format.width, 8);
1950
1951 ctx->smsk_size = bpp * stride * q_data->vsize;
1952
1953 ctx->smsk_cpu = dma_alloc_coherent(ctx->fdp1->dev,
1954 ctx->smsk_size, &smsk_base, GFP_KERNEL);
1955
1956 if (ctx->smsk_cpu == NULL) {
1957 dprintk(ctx->fdp1, "Failed to alloc smsk\n");
1958 return -ENOMEM;
1959 }
1960
1961 ctx->smsk_addr[0] = smsk_base;
1962 ctx->smsk_addr[1] = smsk_base + (ctx->smsk_size/2);
1963 }
1964 }
1965
1966 return 0;
1967 }
1968
fdp1_stop_streaming(struct vb2_queue * q)1969 static void fdp1_stop_streaming(struct vb2_queue *q)
1970 {
1971 struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1972 struct vb2_v4l2_buffer *vbuf;
1973 unsigned long flags;
1974
1975 while (1) {
1976 if (V4L2_TYPE_IS_OUTPUT(q->type))
1977 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1978 else
1979 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1980 if (vbuf == NULL)
1981 break;
1982 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
1983 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1984 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
1985 }
1986
1987 /* Empty Output queues */
1988 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1989 /* Empty our internal queues */
1990 struct fdp1_field_buffer *fbuf;
1991
1992 /* Free any queued buffers */
1993 fbuf = fdp1_dequeue_field(ctx);
1994 while (fbuf != NULL) {
1995 fdp1_field_complete(ctx, fbuf);
1996 fbuf = fdp1_dequeue_field(ctx);
1997 }
1998
1999 /* Free smsk_data */
2000 if (ctx->smsk_cpu) {
2001 dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size,
2002 ctx->smsk_cpu, ctx->smsk_addr[0]);
2003 ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0;
2004 ctx->smsk_cpu = NULL;
2005 }
2006
2007 WARN(!list_empty(&ctx->fields_queue),
2008 "Buffer queue not empty");
2009 } else {
2010 /* Empty Capture queues (Jobs) */
2011 struct fdp1_job *job;
2012
2013 job = get_queued_job(ctx->fdp1);
2014 while (job) {
2015 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
2016 fdp1_field_complete(ctx, job->previous);
2017 else
2018 fdp1_field_complete(ctx, job->active);
2019
2020 v4l2_m2m_buf_done(job->dst->vb, VB2_BUF_STATE_ERROR);
2021 job->dst = NULL;
2022
2023 job = get_queued_job(ctx->fdp1);
2024 }
2025
2026 /* Free any held buffer in the ctx */
2027 fdp1_field_complete(ctx, ctx->previous);
2028
2029 WARN(!list_empty(&ctx->fdp1->queued_job_list),
2030 "Queued Job List not empty");
2031
2032 WARN(!list_empty(&ctx->fdp1->hw_job_list),
2033 "HW Job list not empty");
2034 }
2035 }
2036
2037 static const struct vb2_ops fdp1_qops = {
2038 .queue_setup = fdp1_queue_setup,
2039 .buf_prepare = fdp1_buf_prepare,
2040 .buf_queue = fdp1_buf_queue,
2041 .start_streaming = fdp1_start_streaming,
2042 .stop_streaming = fdp1_stop_streaming,
2043 .wait_prepare = vb2_ops_wait_prepare,
2044 .wait_finish = vb2_ops_wait_finish,
2045 };
2046
queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)2047 static int queue_init(void *priv, struct vb2_queue *src_vq,
2048 struct vb2_queue *dst_vq)
2049 {
2050 struct fdp1_ctx *ctx = priv;
2051 int ret;
2052
2053 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2054 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
2055 src_vq->drv_priv = ctx;
2056 src_vq->buf_struct_size = sizeof(struct fdp1_buffer);
2057 src_vq->ops = &fdp1_qops;
2058 src_vq->mem_ops = &vb2_dma_contig_memops;
2059 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2060 src_vq->lock = &ctx->fdp1->dev_mutex;
2061 src_vq->dev = ctx->fdp1->dev;
2062
2063 ret = vb2_queue_init(src_vq);
2064 if (ret)
2065 return ret;
2066
2067 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2068 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
2069 dst_vq->drv_priv = ctx;
2070 dst_vq->buf_struct_size = sizeof(struct fdp1_buffer);
2071 dst_vq->ops = &fdp1_qops;
2072 dst_vq->mem_ops = &vb2_dma_contig_memops;
2073 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2074 dst_vq->lock = &ctx->fdp1->dev_mutex;
2075 dst_vq->dev = ctx->fdp1->dev;
2076
2077 return vb2_queue_init(dst_vq);
2078 }
2079
2080 /*
2081 * File operations
2082 */
fdp1_open(struct file * file)2083 static int fdp1_open(struct file *file)
2084 {
2085 struct fdp1_dev *fdp1 = video_drvdata(file);
2086 struct v4l2_pix_format_mplane format;
2087 struct fdp1_ctx *ctx = NULL;
2088 struct v4l2_ctrl *ctrl;
2089 int ret = 0;
2090
2091 if (mutex_lock_interruptible(&fdp1->dev_mutex))
2092 return -ERESTARTSYS;
2093
2094 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2095 if (!ctx) {
2096 ret = -ENOMEM;
2097 goto done;
2098 }
2099
2100 v4l2_fh_init(&ctx->fh, video_devdata(file));
2101 file->private_data = &ctx->fh;
2102 ctx->fdp1 = fdp1;
2103
2104 /* Initialise Queues */
2105 INIT_LIST_HEAD(&ctx->fields_queue);
2106
2107 ctx->translen = 1;
2108 ctx->sequence = 0;
2109
2110 /* Initialise controls */
2111
2112 v4l2_ctrl_handler_init(&ctx->hdl, 3);
2113 v4l2_ctrl_new_std_menu_items(&ctx->hdl, &fdp1_ctrl_ops,
2114 V4L2_CID_DEINTERLACING_MODE,
2115 FDP1_NEXTFIELD, BIT(0), FDP1_FIXED3D,
2116 fdp1_ctrl_deint_menu);
2117
2118 ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2119 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1);
2120 if (ctrl)
2121 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
2122
2123 v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2124 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
2125
2126 if (ctx->hdl.error) {
2127 ret = ctx->hdl.error;
2128 v4l2_ctrl_handler_free(&ctx->hdl);
2129 goto done;
2130 }
2131
2132 ctx->fh.ctrl_handler = &ctx->hdl;
2133 v4l2_ctrl_handler_setup(&ctx->hdl);
2134
2135 /* Configure default parameters. */
2136 memset(&format, 0, sizeof(format));
2137 fdp1_set_format(ctx, &format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
2138
2139 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fdp1->m2m_dev, ctx, &queue_init);
2140
2141 if (IS_ERR(ctx->fh.m2m_ctx)) {
2142 ret = PTR_ERR(ctx->fh.m2m_ctx);
2143
2144 v4l2_ctrl_handler_free(&ctx->hdl);
2145 kfree(ctx);
2146 goto done;
2147 }
2148
2149 /* Perform any power management required */
2150 pm_runtime_get_sync(fdp1->dev);
2151
2152 v4l2_fh_add(&ctx->fh);
2153
2154 dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n",
2155 ctx, ctx->fh.m2m_ctx);
2156
2157 done:
2158 mutex_unlock(&fdp1->dev_mutex);
2159 return ret;
2160 }
2161
fdp1_release(struct file * file)2162 static int fdp1_release(struct file *file)
2163 {
2164 struct fdp1_dev *fdp1 = video_drvdata(file);
2165 struct fdp1_ctx *ctx = fh_to_ctx(file->private_data);
2166
2167 dprintk(fdp1, "Releasing instance %p\n", ctx);
2168
2169 v4l2_fh_del(&ctx->fh);
2170 v4l2_fh_exit(&ctx->fh);
2171 v4l2_ctrl_handler_free(&ctx->hdl);
2172 mutex_lock(&fdp1->dev_mutex);
2173 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2174 mutex_unlock(&fdp1->dev_mutex);
2175 kfree(ctx);
2176
2177 pm_runtime_put(fdp1->dev);
2178
2179 return 0;
2180 }
2181
2182 static const struct v4l2_file_operations fdp1_fops = {
2183 .owner = THIS_MODULE,
2184 .open = fdp1_open,
2185 .release = fdp1_release,
2186 .poll = v4l2_m2m_fop_poll,
2187 .unlocked_ioctl = video_ioctl2,
2188 .mmap = v4l2_m2m_fop_mmap,
2189 };
2190
2191 static const struct video_device fdp1_videodev = {
2192 .name = DRIVER_NAME,
2193 .vfl_dir = VFL_DIR_M2M,
2194 .fops = &fdp1_fops,
2195 .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
2196 .ioctl_ops = &fdp1_ioctl_ops,
2197 .minor = -1,
2198 .release = video_device_release_empty,
2199 };
2200
2201 static const struct v4l2_m2m_ops m2m_ops = {
2202 .device_run = fdp1_m2m_device_run,
2203 .job_ready = fdp1_m2m_job_ready,
2204 .job_abort = fdp1_m2m_job_abort,
2205 };
2206
fdp1_irq_handler(int irq,void * dev_id)2207 static irqreturn_t fdp1_irq_handler(int irq, void *dev_id)
2208 {
2209 struct fdp1_dev *fdp1 = dev_id;
2210 u32 int_status;
2211 u32 ctl_status;
2212 u32 vint_cnt;
2213 u32 cycles;
2214
2215 int_status = fdp1_read(fdp1, FD1_CTL_IRQSTA);
2216 cycles = fdp1_read(fdp1, FD1_CTL_VCYCLE_STAT);
2217 ctl_status = fdp1_read(fdp1, FD1_CTL_STATUS);
2218 vint_cnt = (ctl_status & FD1_CTL_STATUS_VINT_CNT_MASK) >>
2219 FD1_CTL_STATUS_VINT_CNT_SHIFT;
2220
2221 /* Clear interrupts */
2222 fdp1_write(fdp1, ~(int_status) & FD1_CTL_IRQ_MASK, FD1_CTL_IRQSTA);
2223
2224 if (debug >= 2) {
2225 dprintk(fdp1, "IRQ: 0x%x %s%s%s\n", int_status,
2226 int_status & FD1_CTL_IRQ_VERE ? "[Error]" : "[!E]",
2227 int_status & FD1_CTL_IRQ_VINTE ? "[VSync]" : "[!V]",
2228 int_status & FD1_CTL_IRQ_FREE ? "[FrameEnd]" : "[!F]");
2229
2230 dprintk(fdp1, "CycleStatus = %d (%dms)\n",
2231 cycles, cycles/(fdp1->clk_rate/1000));
2232
2233 dprintk(fdp1,
2234 "Control Status = 0x%08x : VINT_CNT = %d %s:%s:%s:%s\n",
2235 ctl_status, vint_cnt,
2236 ctl_status & FD1_CTL_STATUS_SGREGSET ? "RegSet" : "",
2237 ctl_status & FD1_CTL_STATUS_SGVERR ? "Vsync Error" : "",
2238 ctl_status & FD1_CTL_STATUS_SGFREND ? "FrameEnd" : "",
2239 ctl_status & FD1_CTL_STATUS_BSY ? "Busy" : "");
2240 dprintk(fdp1, "***********************************\n");
2241 }
2242
2243 /* Spurious interrupt */
2244 if (!(FD1_CTL_IRQ_MASK & int_status))
2245 return IRQ_NONE;
2246
2247 /* Work completed, release the frame */
2248 if (FD1_CTL_IRQ_VERE & int_status)
2249 device_frame_end(fdp1, VB2_BUF_STATE_ERROR);
2250 else if (FD1_CTL_IRQ_FREE & int_status)
2251 device_frame_end(fdp1, VB2_BUF_STATE_DONE);
2252
2253 return IRQ_HANDLED;
2254 }
2255
fdp1_probe(struct platform_device * pdev)2256 static int fdp1_probe(struct platform_device *pdev)
2257 {
2258 struct fdp1_dev *fdp1;
2259 struct video_device *vfd;
2260 struct device_node *fcp_node;
2261 struct resource *res;
2262 struct clk *clk;
2263 unsigned int i;
2264
2265 int ret;
2266 int hw_version;
2267
2268 fdp1 = devm_kzalloc(&pdev->dev, sizeof(*fdp1), GFP_KERNEL);
2269 if (!fdp1)
2270 return -ENOMEM;
2271
2272 INIT_LIST_HEAD(&fdp1->free_job_list);
2273 INIT_LIST_HEAD(&fdp1->queued_job_list);
2274 INIT_LIST_HEAD(&fdp1->hw_job_list);
2275
2276 /* Initialise the jobs on the free list */
2277 for (i = 0; i < ARRAY_SIZE(fdp1->jobs); i++)
2278 list_add(&fdp1->jobs[i].list, &fdp1->free_job_list);
2279
2280 mutex_init(&fdp1->dev_mutex);
2281
2282 spin_lock_init(&fdp1->irqlock);
2283 spin_lock_init(&fdp1->device_process_lock);
2284 fdp1->dev = &pdev->dev;
2285 platform_set_drvdata(pdev, fdp1);
2286
2287 /* Memory-mapped registers */
2288 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2289 fdp1->regs = devm_ioremap_resource(&pdev->dev, res);
2290 if (IS_ERR(fdp1->regs))
2291 return PTR_ERR(fdp1->regs);
2292
2293 /* Interrupt service routine registration */
2294 fdp1->irq = ret = platform_get_irq(pdev, 0);
2295 if (ret < 0) {
2296 dev_err(&pdev->dev, "cannot find IRQ\n");
2297 return ret;
2298 }
2299
2300 ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0,
2301 dev_name(&pdev->dev), fdp1);
2302 if (ret) {
2303 dev_err(&pdev->dev, "cannot claim IRQ %d\n", fdp1->irq);
2304 return ret;
2305 }
2306
2307 /* FCP */
2308 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
2309 if (fcp_node) {
2310 fdp1->fcp = rcar_fcp_get(fcp_node);
2311 of_node_put(fcp_node);
2312 if (IS_ERR(fdp1->fcp)) {
2313 dev_dbg(&pdev->dev, "FCP not found (%ld)\n",
2314 PTR_ERR(fdp1->fcp));
2315 return PTR_ERR(fdp1->fcp);
2316 }
2317 }
2318
2319 /* Determine our clock rate */
2320 clk = clk_get(&pdev->dev, NULL);
2321 if (IS_ERR(clk))
2322 return PTR_ERR(clk);
2323
2324 fdp1->clk_rate = clk_get_rate(clk);
2325 clk_put(clk);
2326
2327 /* V4L2 device registration */
2328 ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev);
2329 if (ret) {
2330 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2331 return ret;
2332 }
2333
2334 /* M2M registration */
2335 fdp1->m2m_dev = v4l2_m2m_init(&m2m_ops);
2336 if (IS_ERR(fdp1->m2m_dev)) {
2337 v4l2_err(&fdp1->v4l2_dev, "Failed to init mem2mem device\n");
2338 ret = PTR_ERR(fdp1->m2m_dev);
2339 goto unreg_dev;
2340 }
2341
2342 /* Video registration */
2343 fdp1->vfd = fdp1_videodev;
2344 vfd = &fdp1->vfd;
2345 vfd->lock = &fdp1->dev_mutex;
2346 vfd->v4l2_dev = &fdp1->v4l2_dev;
2347 video_set_drvdata(vfd, fdp1);
2348 strlcpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));
2349
2350 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
2351 if (ret) {
2352 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2353 goto release_m2m;
2354 }
2355
2356 v4l2_info(&fdp1->v4l2_dev,
2357 "Device registered as /dev/video%d\n", vfd->num);
2358
2359 /* Power up the cells to read HW */
2360 pm_runtime_enable(&pdev->dev);
2361 pm_runtime_get_sync(fdp1->dev);
2362
2363 hw_version = fdp1_read(fdp1, FD1_IP_INTDATA);
2364 switch (hw_version) {
2365 case FD1_IP_H3_ES1:
2366 dprintk(fdp1, "FDP1 Version R-Car H3 ES1\n");
2367 break;
2368 case FD1_IP_M3W:
2369 dprintk(fdp1, "FDP1 Version R-Car M3-W\n");
2370 break;
2371 case FD1_IP_H3:
2372 dprintk(fdp1, "FDP1 Version R-Car H3\n");
2373 break;
2374 case FD1_IP_M3N:
2375 dprintk(fdp1, "FDP1 Version R-Car M3N\n");
2376 break;
2377 case FD1_IP_E3:
2378 dprintk(fdp1, "FDP1 Version R-Car E3\n");
2379 break;
2380 default:
2381 dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n",
2382 hw_version);
2383 }
2384
2385 /* Allow the hw to sleep until an open call puts it to use */
2386 pm_runtime_put(fdp1->dev);
2387
2388 return 0;
2389
2390 release_m2m:
2391 v4l2_m2m_release(fdp1->m2m_dev);
2392
2393 unreg_dev:
2394 v4l2_device_unregister(&fdp1->v4l2_dev);
2395
2396 return ret;
2397 }
2398
fdp1_remove(struct platform_device * pdev)2399 static int fdp1_remove(struct platform_device *pdev)
2400 {
2401 struct fdp1_dev *fdp1 = platform_get_drvdata(pdev);
2402
2403 v4l2_m2m_release(fdp1->m2m_dev);
2404 video_unregister_device(&fdp1->vfd);
2405 v4l2_device_unregister(&fdp1->v4l2_dev);
2406 pm_runtime_disable(&pdev->dev);
2407
2408 return 0;
2409 }
2410
fdp1_pm_runtime_suspend(struct device * dev)2411 static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev)
2412 {
2413 struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2414
2415 rcar_fcp_disable(fdp1->fcp);
2416
2417 return 0;
2418 }
2419
fdp1_pm_runtime_resume(struct device * dev)2420 static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev)
2421 {
2422 struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2423
2424 /* Program in the static LUTs */
2425 fdp1_set_lut(fdp1);
2426
2427 return rcar_fcp_enable(fdp1->fcp);
2428 }
2429
2430 static const struct dev_pm_ops fdp1_pm_ops = {
2431 SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend,
2432 fdp1_pm_runtime_resume,
2433 NULL)
2434 };
2435
2436 static const struct of_device_id fdp1_dt_ids[] = {
2437 { .compatible = "renesas,fdp1" },
2438 { },
2439 };
2440 MODULE_DEVICE_TABLE(of, fdp1_dt_ids);
2441
2442 static struct platform_driver fdp1_pdrv = {
2443 .probe = fdp1_probe,
2444 .remove = fdp1_remove,
2445 .driver = {
2446 .name = DRIVER_NAME,
2447 .of_match_table = fdp1_dt_ids,
2448 .pm = &fdp1_pm_ops,
2449 },
2450 };
2451
2452 module_platform_driver(fdp1_pdrv);
2453
2454 MODULE_DESCRIPTION("Renesas R-Car Fine Display Processor Driver");
2455 MODULE_AUTHOR("Kieran Bingham <kieran@bingham.xyz>");
2456 MODULE_LICENSE("GPL");
2457 MODULE_ALIAS("platform:" DRIVER_NAME);
2458