1 // SPDX-License-Identifier: GPL-2.0+
3 * Renesas R-Car Fine Display Processor
5 * Video format converter and frame deinterlacer device.
7 * Author: Kieran Bingham, <kieran@bingham.xyz>
8 * Copyright (c) 2016 Renesas Electronics Corporation.
10 * This code is developed and inspired from the vim2m, rcar_jpu,
11 * m2m-deinterlace, and vsp1 drivers.
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/dma-mapping.h>
18 #include <linux/interrupt.h>
19 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/sched.h>
24 #include <linux/slab.h>
25 #include <linux/timer.h>
26 #include <media/rcar-fcp.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-event.h>
30 #include <media/v4l2-ioctl.h>
31 #include <media/v4l2-mem2mem.h>
32 #include <media/videobuf2-dma-contig.h>
34 static unsigned int debug;
35 module_param(debug, uint, 0644);
36 MODULE_PARM_DESC(debug, "activate debug info");
38 /* Minimum and maximum frame width/height */
39 #define FDP1_MIN_W 80U
40 #define FDP1_MIN_H 80U
42 #define FDP1_MAX_W 3840U
43 #define FDP1_MAX_H 2160U
45 #define FDP1_MAX_PLANES 3U
46 #define FDP1_MAX_STRIDE 8190U
48 /* Flags that indicate a format can be used for capture/output */
49 #define FDP1_CAPTURE BIT(0)
50 #define FDP1_OUTPUT BIT(1)
52 #define DRIVER_NAME "rcar_fdp1"
54 /* Number of Job's to have available on the processing queue */
55 #define FDP1_NUMBER_JOBS 8
57 #define dprintk(fdp1, fmt, arg...) \
58 v4l2_dbg(1, debug, &fdp1->v4l2_dev, "%s: " fmt, __func__, ## arg)
61 * FDP1 registers and bits
64 /* FDP1 start register - Imm */
65 #define FD1_CTL_CMD 0x0000
66 #define FD1_CTL_CMD_STRCMD BIT(0)
68 /* Sync generator register - Imm */
69 #define FD1_CTL_SGCMD 0x0004
70 #define FD1_CTL_SGCMD_SGEN BIT(0)
72 /* Register set end register - Imm */
73 #define FD1_CTL_REGEND 0x0008
74 #define FD1_CTL_REGEND_REGEND BIT(0)
76 /* Channel activation register - Vupdt */
77 #define FD1_CTL_CHACT 0x000c
78 #define FD1_CTL_CHACT_SMW BIT(9)
79 #define FD1_CTL_CHACT_WR BIT(8)
80 #define FD1_CTL_CHACT_SMR BIT(3)
81 #define FD1_CTL_CHACT_RD2 BIT(2)
82 #define FD1_CTL_CHACT_RD1 BIT(1)
83 #define FD1_CTL_CHACT_RD0 BIT(0)
85 /* Operation Mode Register - Vupdt */
86 #define FD1_CTL_OPMODE 0x0010
87 #define FD1_CTL_OPMODE_PRG BIT(4)
88 #define FD1_CTL_OPMODE_VIMD_INTERRUPT (0 << 0)
89 #define FD1_CTL_OPMODE_VIMD_BESTEFFORT (1 << 0)
90 #define FD1_CTL_OPMODE_VIMD_NOINTERRUPT (2 << 0)
92 #define FD1_CTL_VPERIOD 0x0014
93 #define FD1_CTL_CLKCTRL 0x0018
94 #define FD1_CTL_CLKCTRL_CSTP_N BIT(0)
96 /* Software reset register */
97 #define FD1_CTL_SRESET 0x001c
98 #define FD1_CTL_SRESET_SRST BIT(0)
100 /* Control status register (V-update-status) */
101 #define FD1_CTL_STATUS 0x0024
102 #define FD1_CTL_STATUS_VINT_CNT_MASK GENMASK(31, 16)
103 #define FD1_CTL_STATUS_VINT_CNT_SHIFT 16
104 #define FD1_CTL_STATUS_SGREGSET BIT(10)
105 #define FD1_CTL_STATUS_SGVERR BIT(9)
106 #define FD1_CTL_STATUS_SGFREND BIT(8)
107 #define FD1_CTL_STATUS_BSY BIT(0)
109 #define FD1_CTL_VCYCLE_STAT 0x0028
111 /* Interrupt enable register */
112 #define FD1_CTL_IRQENB 0x0038
113 /* Interrupt status register */
114 #define FD1_CTL_IRQSTA 0x003c
115 /* Interrupt control register */
116 #define FD1_CTL_IRQFSET 0x0040
118 /* Common IRQ Bit settings */
119 #define FD1_CTL_IRQ_VERE BIT(16)
120 #define FD1_CTL_IRQ_VINTE BIT(4)
121 #define FD1_CTL_IRQ_FREE BIT(0)
122 #define FD1_CTL_IRQ_MASK (FD1_CTL_IRQ_VERE | \
123 FD1_CTL_IRQ_VINTE | \
127 #define FD1_RPF_SIZE 0x0060
128 #define FD1_RPF_SIZE_MASK GENMASK(12, 0)
129 #define FD1_RPF_SIZE_H_SHIFT 16
130 #define FD1_RPF_SIZE_V_SHIFT 0
132 #define FD1_RPF_FORMAT 0x0064
133 #define FD1_RPF_FORMAT_CIPM BIT(16)
134 #define FD1_RPF_FORMAT_RSPYCS BIT(13)
135 #define FD1_RPF_FORMAT_RSPUVS BIT(12)
136 #define FD1_RPF_FORMAT_CF BIT(8)
138 #define FD1_RPF_PSTRIDE 0x0068
139 #define FD1_RPF_PSTRIDE_Y_SHIFT 16
140 #define FD1_RPF_PSTRIDE_C_SHIFT 0
142 /* RPF0 Source Component Y Address register */
143 #define FD1_RPF0_ADDR_Y 0x006c
145 /* RPF1 Current Picture Registers */
146 #define FD1_RPF1_ADDR_Y 0x0078
147 #define FD1_RPF1_ADDR_C0 0x007c
148 #define FD1_RPF1_ADDR_C1 0x0080
150 /* RPF2 next picture register */
151 #define FD1_RPF2_ADDR_Y 0x0084
153 #define FD1_RPF_SMSK_ADDR 0x0090
154 #define FD1_RPF_SWAP 0x0094
157 #define FD1_WPF_FORMAT 0x00c0
158 #define FD1_WPF_FORMAT_PDV_SHIFT 24
159 #define FD1_WPF_FORMAT_FCNL BIT(20)
160 #define FD1_WPF_FORMAT_WSPYCS BIT(15)
161 #define FD1_WPF_FORMAT_WSPUVS BIT(14)
162 #define FD1_WPF_FORMAT_WRTM_601_16 (0 << 9)
163 #define FD1_WPF_FORMAT_WRTM_601_0 (1 << 9)
164 #define FD1_WPF_FORMAT_WRTM_709_16 (2 << 9)
165 #define FD1_WPF_FORMAT_CSC BIT(8)
167 #define FD1_WPF_RNDCTL 0x00c4
168 #define FD1_WPF_RNDCTL_CBRM BIT(28)
169 #define FD1_WPF_RNDCTL_CLMD_NOCLIP (0 << 12)
170 #define FD1_WPF_RNDCTL_CLMD_CLIP_16_235 (1 << 12)
171 #define FD1_WPF_RNDCTL_CLMD_CLIP_1_254 (2 << 12)
173 #define FD1_WPF_PSTRIDE 0x00c8
174 #define FD1_WPF_PSTRIDE_Y_SHIFT 16
175 #define FD1_WPF_PSTRIDE_C_SHIFT 0
177 /* WPF Destination picture */
178 #define FD1_WPF_ADDR_Y 0x00cc
179 #define FD1_WPF_ADDR_C0 0x00d0
180 #define FD1_WPF_ADDR_C1 0x00d4
181 #define FD1_WPF_SWAP 0x00d8
182 #define FD1_WPF_SWAP_OSWAP_SHIFT 0
183 #define FD1_WPF_SWAP_SSWAP_SHIFT 4
186 #define FD1_RWPF_SWAP_BYTE BIT(0)
187 #define FD1_RWPF_SWAP_WORD BIT(1)
188 #define FD1_RWPF_SWAP_LWRD BIT(2)
189 #define FD1_RWPF_SWAP_LLWD BIT(3)
192 #define FD1_IPC_MODE 0x0100
193 #define FD1_IPC_MODE_DLI BIT(8)
194 #define FD1_IPC_MODE_DIM_ADAPT2D3D (0 << 0)
195 #define FD1_IPC_MODE_DIM_FIXED2D (1 << 0)
196 #define FD1_IPC_MODE_DIM_FIXED3D (2 << 0)
197 #define FD1_IPC_MODE_DIM_PREVFIELD (3 << 0)
198 #define FD1_IPC_MODE_DIM_NEXTFIELD (4 << 0)
200 #define FD1_IPC_SMSK_THRESH 0x0104
201 #define FD1_IPC_SMSK_THRESH_CONST 0x00010002
203 #define FD1_IPC_COMB_DET 0x0108
204 #define FD1_IPC_COMB_DET_CONST 0x00200040
206 #define FD1_IPC_MOTDEC 0x010c
207 #define FD1_IPC_MOTDEC_CONST 0x00008020
210 #define FD1_IPC_DLI_BLEND 0x0120
211 #define FD1_IPC_DLI_BLEND_CONST 0x0080ff02
213 #define FD1_IPC_DLI_HGAIN 0x0124
214 #define FD1_IPC_DLI_HGAIN_CONST 0x001000ff
216 #define FD1_IPC_DLI_SPRS 0x0128
217 #define FD1_IPC_DLI_SPRS_CONST 0x009004ff
219 #define FD1_IPC_DLI_ANGLE 0x012c
220 #define FD1_IPC_DLI_ANGLE_CONST 0x0004080c
222 #define FD1_IPC_DLI_ISOPIX0 0x0130
223 #define FD1_IPC_DLI_ISOPIX0_CONST 0xff10ff10
225 #define FD1_IPC_DLI_ISOPIX1 0x0134
226 #define FD1_IPC_DLI_ISOPIX1_CONST 0x0000ff10
228 /* Sensor registers */
229 #define FD1_IPC_SENSOR_TH0 0x0140
230 #define FD1_IPC_SENSOR_TH0_CONST 0x20208080
232 #define FD1_IPC_SENSOR_TH1 0x0144
233 #define FD1_IPC_SENSOR_TH1_CONST 0
235 #define FD1_IPC_SENSOR_CTL0 0x0170
236 #define FD1_IPC_SENSOR_CTL0_CONST 0x00002201
238 #define FD1_IPC_SENSOR_CTL1 0x0174
239 #define FD1_IPC_SENSOR_CTL1_CONST 0
241 #define FD1_IPC_SENSOR_CTL2 0x0178
242 #define FD1_IPC_SENSOR_CTL2_X_SHIFT 16
243 #define FD1_IPC_SENSOR_CTL2_Y_SHIFT 0
245 #define FD1_IPC_SENSOR_CTL3 0x017c
246 #define FD1_IPC_SENSOR_CTL3_0_SHIFT 16
247 #define FD1_IPC_SENSOR_CTL3_1_SHIFT 0
249 /* Line memory pixel number register */
250 #define FD1_IPC_LMEM 0x01e0
251 #define FD1_IPC_LMEM_LINEAR 1024
252 #define FD1_IPC_LMEM_TILE 960
254 /* Internal Data (HW Version) */
255 #define FD1_IP_INTDATA 0x0800
256 /* R-Car Gen2 HW manual says zero, but actual value matches R-Car H3 ES1.x */
257 #define FD1_IP_GEN2 0x02010101
258 #define FD1_IP_M3W 0x02010202
259 #define FD1_IP_H3 0x02010203
260 #define FD1_IP_M3N 0x02010204
261 #define FD1_IP_E3 0x02010205
264 #define FD1_LUT_DIF_ADJ 0x1000
265 #define FD1_LUT_SAD_ADJ 0x1400
266 #define FD1_LUT_BLD_GAIN 0x1800
267 #define FD1_LUT_DIF_GAIN 0x1c00
268 #define FD1_LUT_MDET 0x2000
271 * struct fdp1_fmt - The FDP1 internal format data
272 * @fourcc: the fourcc code, to match the V4L2 API
273 * @bpp: bits per pixel per plane
274 * @num_planes: number of planes
275 * @hsub: horizontal subsampling factor
276 * @vsub: vertical subsampling factor
277 * @fmt: 7-bit format code for the fdp1 hardware
278 * @swap_yc: the Y and C components are swapped (Y comes before C)
279 * @swap_uv: the U and V components are swapped (V comes before U)
280 * @swap: swap register control
281 * @types: types of queue this format is applicable to
296 static const struct fdp1_fmt fdp1_formats[] = {
297 /* RGB formats are only supported by the Write Pixel Formatter */
299 { V4L2_PIX_FMT_RGB332, { 8, 0, 0 }, 1, 1, 1, 0x00, false, false,
300 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
301 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
303 { V4L2_PIX_FMT_XRGB444, { 16, 0, 0 }, 1, 1, 1, 0x01, false, false,
304 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
307 { V4L2_PIX_FMT_XRGB555, { 16, 0, 0 }, 1, 1, 1, 0x04, false, false,
308 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
311 { V4L2_PIX_FMT_RGB565, { 16, 0, 0 }, 1, 1, 1, 0x06, false, false,
312 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
315 { V4L2_PIX_FMT_ABGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
316 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD,
318 { V4L2_PIX_FMT_XBGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
319 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD,
321 { V4L2_PIX_FMT_ARGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
322 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
323 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
325 { V4L2_PIX_FMT_XRGB32, { 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,
329 { V4L2_PIX_FMT_RGB24, { 24, 0, 0 }, 1, 1, 1, 0x15, false, false,
330 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
331 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
333 { V4L2_PIX_FMT_BGR24, { 24, 0, 0 }, 1, 1, 1, 0x18, false, false,
334 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
335 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
337 { V4L2_PIX_FMT_ARGB444, { 16, 0, 0 }, 1, 1, 1, 0x19, false, false,
338 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
341 { V4L2_PIX_FMT_ARGB555, { 16, 0, 0 }, 1, 1, 1, 0x1b, false, false,
342 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
346 /* YUV Formats are supported by Read and Write Pixel Formatters */
348 { V4L2_PIX_FMT_NV16M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, false,
349 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
350 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
351 FDP1_CAPTURE | FDP1_OUTPUT },
352 { V4L2_PIX_FMT_NV61M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, true,
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_NV12M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, false,
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_NV21M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, true,
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_UYVY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, false,
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_VYUY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, true,
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_YUYV, { 16, 0, 0 }, 1, 2, 1, 0x47, true, false,
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_YVYU, { 16, 0, 0 }, 1, 2, 1, 0x47, true, true,
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_YUV444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, false,
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_YVU444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, true,
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_YUV422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, false,
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_YVU422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, true,
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_YUV420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, false,
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_YVU420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, true,
401 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
402 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE,
403 FDP1_CAPTURE | FDP1_OUTPUT },
406 static int fdp1_fmt_is_rgb(const struct fdp1_fmt *fmt)
408 return fmt->fmt <= 0x1b; /* Last RGB code */
412 * FDP1 Lookup tables range from 0...255 only
414 * Each table must be less than 256 entries, and all tables
415 * are padded out to 256 entries by duplicating the last value.
417 static const u8 fdp1_diff_adj[] = {
418 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf,
419 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3,
420 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff,
423 static const u8 fdp1_sad_adj[] = {
424 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf,
425 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3,
426 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff,
429 static const u8 fdp1_bld_gain[] = {
433 static const u8 fdp1_dif_gain[] = {
437 static const u8 fdp1_mdet[] = {
438 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
439 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
440 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
441 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
442 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
443 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
444 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
445 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
446 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
447 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
448 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
449 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
450 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
451 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
452 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
453 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
454 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
455 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
456 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
457 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
458 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
459 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
460 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
461 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
462 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
463 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
464 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
465 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
466 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
467 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
468 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
469 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
472 /* Per-queue, driver-specific private data */
474 const struct fdp1_fmt *fmt;
475 struct v4l2_pix_format_mplane format;
478 unsigned int stride_y;
479 unsigned int stride_c;
482 static const struct fdp1_fmt *fdp1_find_format(u32 pixelformat)
484 const struct fdp1_fmt *fmt;
487 for (i = 0; i < ARRAY_SIZE(fdp1_formats); i++) {
488 fmt = &fdp1_formats[i];
489 if (fmt->fourcc == pixelformat)
496 enum fdp1_deint_mode {
497 FDP1_PROGRESSIVE = 0, /* Must be zero when !deinterlacing */
505 #define FDP1_DEINT_MODE_USES_NEXT(mode) \
506 (mode == FDP1_ADAPT2D3D || \
507 mode == FDP1_FIXED3D || \
508 mode == FDP1_NEXTFIELD)
510 #define FDP1_DEINT_MODE_USES_PREV(mode) \
511 (mode == FDP1_ADAPT2D3D || \
512 mode == FDP1_FIXED3D || \
513 mode == FDP1_PREVFIELD)
516 * FDP1 operates on potentially 3 fields, which are tracked
517 * from the VB buffers using this context structure.
518 * Will always be a field or a full frame, never two fields.
520 struct fdp1_field_buffer {
521 struct vb2_v4l2_buffer *vb;
524 /* Should be NONE:TOP:BOTTOM only */
525 enum v4l2_field field;
527 /* Flag to indicate this is the last field in the vb */
530 /* Buffer queue lists */
531 struct list_head list;
535 struct v4l2_m2m_buffer m2m_buf;
536 struct fdp1_field_buffer fields[2];
537 unsigned int num_fields;
540 static inline struct fdp1_buffer *to_fdp1_buffer(struct vb2_v4l2_buffer *vb)
542 return container_of(vb, struct fdp1_buffer, m2m_buf.vb);
546 struct fdp1_field_buffer *previous;
547 struct fdp1_field_buffer *active;
548 struct fdp1_field_buffer *next;
549 struct fdp1_field_buffer *dst;
551 /* A job can only be on one list at a time */
552 struct list_head list;
556 struct v4l2_device v4l2_dev;
557 struct video_device vfd;
559 struct mutex dev_mutex;
561 spinlock_t device_process_lock;
568 struct fdp1_job jobs[FDP1_NUMBER_JOBS];
569 struct list_head free_job_list;
570 struct list_head queued_job_list;
571 struct list_head hw_job_list;
573 unsigned int clk_rate;
575 struct rcar_fcp_device *fcp;
576 struct v4l2_m2m_dev *m2m_dev;
581 struct fdp1_dev *fdp1;
583 struct v4l2_ctrl_handler hdl;
584 unsigned int sequence;
586 /* Processed buffers in this transaction */
589 /* Transaction length (i.e. how many buffers per transaction) */
592 /* Abort requested by m2m */
595 /* Deinterlace processing mode */
596 enum fdp1_deint_mode deint_mode;
599 * Adaptive 2D/3D mode uses a shared mask
600 * This is allocated at streamon, if the ADAPT2D3D mode
603 unsigned int smsk_size;
604 dma_addr_t smsk_addr[2];
607 /* Capture pipeline, can specify an alpha value
608 * for supported formats. 0-255 only
612 /* Source and destination queue data */
613 struct fdp1_q_data out_q; /* HW Source */
614 struct fdp1_q_data cap_q; /* HW Destination */
618 * Interlaced fields are used on 3 occasions, and tracked in this list.
620 * V4L2 Buffers are tracked inside the fdp1_buffer
621 * and released when the last 'field' completes
623 struct list_head fields_queue;
624 unsigned int buffers_queued;
627 * For de-interlacing we need to track our previous buffer
628 * while preparing our job lists.
630 struct fdp1_field_buffer *previous;
633 static inline struct fdp1_ctx *fh_to_ctx(struct v4l2_fh *fh)
635 return container_of(fh, struct fdp1_ctx, fh);
638 static struct fdp1_q_data *get_q_data(struct fdp1_ctx *ctx,
639 enum v4l2_buf_type type)
641 if (V4L2_TYPE_IS_OUTPUT(type))
648 * list_remove_job: Take the first item off the specified job list
650 * Returns: pointer to a job, or NULL if the list is empty.
652 static struct fdp1_job *list_remove_job(struct fdp1_dev *fdp1,
653 struct list_head *list)
655 struct fdp1_job *job;
658 spin_lock_irqsave(&fdp1->irqlock, flags);
659 job = list_first_entry_or_null(list, struct fdp1_job, list);
661 list_del(&job->list);
662 spin_unlock_irqrestore(&fdp1->irqlock, flags);
668 * list_add_job: Add a job to the specified job list
670 * Returns: void - always succeeds
672 static void list_add_job(struct fdp1_dev *fdp1,
673 struct list_head *list,
674 struct fdp1_job *job)
678 spin_lock_irqsave(&fdp1->irqlock, flags);
679 list_add_tail(&job->list, list);
680 spin_unlock_irqrestore(&fdp1->irqlock, flags);
683 static struct fdp1_job *fdp1_job_alloc(struct fdp1_dev *fdp1)
685 return list_remove_job(fdp1, &fdp1->free_job_list);
688 static void fdp1_job_free(struct fdp1_dev *fdp1, struct fdp1_job *job)
690 /* Ensure that all residue from previous jobs is gone */
691 memset(job, 0, sizeof(struct fdp1_job));
693 list_add_job(fdp1, &fdp1->free_job_list, job);
696 static void queue_job(struct fdp1_dev *fdp1, struct fdp1_job *job)
698 list_add_job(fdp1, &fdp1->queued_job_list, job);
701 static struct fdp1_job *get_queued_job(struct fdp1_dev *fdp1)
703 return list_remove_job(fdp1, &fdp1->queued_job_list);
706 static void queue_hw_job(struct fdp1_dev *fdp1, struct fdp1_job *job)
708 list_add_job(fdp1, &fdp1->hw_job_list, job);
711 static struct fdp1_job *get_hw_queued_job(struct fdp1_dev *fdp1)
713 return list_remove_job(fdp1, &fdp1->hw_job_list);
717 * Buffer lists handling
719 static void fdp1_field_complete(struct fdp1_ctx *ctx,
720 struct fdp1_field_buffer *fbuf)
722 /* job->previous may be on the first field */
726 if (fbuf->last_field)
727 v4l2_m2m_buf_done(fbuf->vb, VB2_BUF_STATE_DONE);
730 static void fdp1_queue_field(struct fdp1_ctx *ctx,
731 struct fdp1_field_buffer *fbuf)
735 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
736 list_add_tail(&fbuf->list, &ctx->fields_queue);
737 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
739 ctx->buffers_queued++;
742 static struct fdp1_field_buffer *fdp1_dequeue_field(struct fdp1_ctx *ctx)
744 struct fdp1_field_buffer *fbuf;
747 ctx->buffers_queued--;
749 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
750 fbuf = list_first_entry_or_null(&ctx->fields_queue,
751 struct fdp1_field_buffer, list);
753 list_del(&fbuf->list);
754 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
760 * Return the next field in the queue - or NULL,
761 * without removing the item from the list
763 static struct fdp1_field_buffer *fdp1_peek_queued_field(struct fdp1_ctx *ctx)
765 struct fdp1_field_buffer *fbuf;
768 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
769 fbuf = list_first_entry_or_null(&ctx->fields_queue,
770 struct fdp1_field_buffer, list);
771 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
776 static u32 fdp1_read(struct fdp1_dev *fdp1, unsigned int reg)
778 u32 value = ioread32(fdp1->regs + reg);
781 dprintk(fdp1, "Read 0x%08x from 0x%04x\n", value, reg);
786 static void fdp1_write(struct fdp1_dev *fdp1, u32 val, unsigned int reg)
789 dprintk(fdp1, "Write 0x%08x to 0x%04x\n", val, reg);
791 iowrite32(val, fdp1->regs + reg);
794 /* IPC registers are to be programmed with constant values */
795 static void fdp1_set_ipc_dli(struct fdp1_ctx *ctx)
797 struct fdp1_dev *fdp1 = ctx->fdp1;
799 fdp1_write(fdp1, FD1_IPC_SMSK_THRESH_CONST, FD1_IPC_SMSK_THRESH);
800 fdp1_write(fdp1, FD1_IPC_COMB_DET_CONST, FD1_IPC_COMB_DET);
801 fdp1_write(fdp1, FD1_IPC_MOTDEC_CONST, FD1_IPC_MOTDEC);
803 fdp1_write(fdp1, FD1_IPC_DLI_BLEND_CONST, FD1_IPC_DLI_BLEND);
804 fdp1_write(fdp1, FD1_IPC_DLI_HGAIN_CONST, FD1_IPC_DLI_HGAIN);
805 fdp1_write(fdp1, FD1_IPC_DLI_SPRS_CONST, FD1_IPC_DLI_SPRS);
806 fdp1_write(fdp1, FD1_IPC_DLI_ANGLE_CONST, FD1_IPC_DLI_ANGLE);
807 fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX0_CONST, FD1_IPC_DLI_ISOPIX0);
808 fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX1_CONST, FD1_IPC_DLI_ISOPIX1);
812 static void fdp1_set_ipc_sensor(struct fdp1_ctx *ctx)
814 struct fdp1_dev *fdp1 = ctx->fdp1;
815 struct fdp1_q_data *src_q_data = &ctx->out_q;
817 unsigned int hsize = src_q_data->format.width;
818 unsigned int vsize = src_q_data->format.height;
823 fdp1_write(fdp1, FD1_IPC_SENSOR_TH0_CONST, FD1_IPC_SENSOR_TH0);
824 fdp1_write(fdp1, FD1_IPC_SENSOR_TH1_CONST, FD1_IPC_SENSOR_TH1);
825 fdp1_write(fdp1, FD1_IPC_SENSOR_CTL0_CONST, FD1_IPC_SENSOR_CTL0);
826 fdp1_write(fdp1, FD1_IPC_SENSOR_CTL1_CONST, FD1_IPC_SENSOR_CTL1);
828 fdp1_write(fdp1, ((hsize - 1) << FD1_IPC_SENSOR_CTL2_X_SHIFT) |
829 ((vsize - 1) << FD1_IPC_SENSOR_CTL2_Y_SHIFT),
830 FD1_IPC_SENSOR_CTL2);
832 fdp1_write(fdp1, (x0 << FD1_IPC_SENSOR_CTL3_0_SHIFT) |
833 (x1 << FD1_IPC_SENSOR_CTL3_1_SHIFT),
834 FD1_IPC_SENSOR_CTL3);
838 * fdp1_write_lut: Write a padded LUT to the hw
840 * FDP1 uses constant data for de-interlacing processing,
841 * with large tables. These hardware tables are all 256 bytes
842 * long, however they often contain repeated data at the end.
844 * The last byte of the table is written to all remaining entries.
846 static void fdp1_write_lut(struct fdp1_dev *fdp1, const u8 *lut,
847 unsigned int len, unsigned int base)
852 /* Tables larger than the hw are clipped */
853 len = min(len, 256u);
855 for (i = 0; i < len; i++)
856 fdp1_write(fdp1, lut[i], base + (i*4));
858 /* Tables are padded with the last entry */
862 fdp1_write(fdp1, pad, base + (i*4));
865 static void fdp1_set_lut(struct fdp1_dev *fdp1)
867 fdp1_write_lut(fdp1, fdp1_diff_adj, ARRAY_SIZE(fdp1_diff_adj),
869 fdp1_write_lut(fdp1, fdp1_sad_adj, ARRAY_SIZE(fdp1_sad_adj),
871 fdp1_write_lut(fdp1, fdp1_bld_gain, ARRAY_SIZE(fdp1_bld_gain),
873 fdp1_write_lut(fdp1, fdp1_dif_gain, ARRAY_SIZE(fdp1_dif_gain),
875 fdp1_write_lut(fdp1, fdp1_mdet, ARRAY_SIZE(fdp1_mdet),
879 static void fdp1_configure_rpf(struct fdp1_ctx *ctx,
880 struct fdp1_job *job)
882 struct fdp1_dev *fdp1 = ctx->fdp1;
888 struct fdp1_q_data *q_data = &ctx->out_q;
890 /* Picture size is common to Source and Destination frames */
891 picture_size = (q_data->format.width << FD1_RPF_SIZE_H_SHIFT)
892 | (q_data->vsize << FD1_RPF_SIZE_V_SHIFT);
895 pstride = q_data->stride_y << FD1_RPF_PSTRIDE_Y_SHIFT;
896 if (q_data->format.num_planes > 1)
897 pstride |= q_data->stride_c << FD1_RPF_PSTRIDE_C_SHIFT;
900 format = q_data->fmt->fmt;
901 if (q_data->fmt->swap_yc)
902 format |= FD1_RPF_FORMAT_RSPYCS;
904 if (q_data->fmt->swap_uv)
905 format |= FD1_RPF_FORMAT_RSPUVS;
907 if (job->active->field == V4L2_FIELD_BOTTOM) {
908 format |= FD1_RPF_FORMAT_CF; /* Set for Bottom field */
909 smsk_addr = ctx->smsk_addr[0];
911 smsk_addr = ctx->smsk_addr[1];
914 /* Deint mode is non-zero when deinterlacing */
916 format |= FD1_RPF_FORMAT_CIPM;
918 fdp1_write(fdp1, format, FD1_RPF_FORMAT);
919 fdp1_write(fdp1, q_data->fmt->swap, FD1_RPF_SWAP);
920 fdp1_write(fdp1, picture_size, FD1_RPF_SIZE);
921 fdp1_write(fdp1, pstride, FD1_RPF_PSTRIDE);
922 fdp1_write(fdp1, smsk_addr, FD1_RPF_SMSK_ADDR);
924 /* Previous Field Channel (CH0) */
926 fdp1_write(fdp1, job->previous->addrs[0], FD1_RPF0_ADDR_Y);
928 /* Current Field Channel (CH1) */
929 fdp1_write(fdp1, job->active->addrs[0], FD1_RPF1_ADDR_Y);
930 fdp1_write(fdp1, job->active->addrs[1], FD1_RPF1_ADDR_C0);
931 fdp1_write(fdp1, job->active->addrs[2], FD1_RPF1_ADDR_C1);
933 /* Next Field Channel (CH2) */
935 fdp1_write(fdp1, job->next->addrs[0], FD1_RPF2_ADDR_Y);
938 static void fdp1_configure_wpf(struct fdp1_ctx *ctx,
939 struct fdp1_job *job)
941 struct fdp1_dev *fdp1 = ctx->fdp1;
942 struct fdp1_q_data *src_q_data = &ctx->out_q;
943 struct fdp1_q_data *q_data = &ctx->cap_q;
949 pstride = q_data->format.plane_fmt[0].bytesperline
950 << FD1_WPF_PSTRIDE_Y_SHIFT;
952 if (q_data->format.num_planes > 1)
953 pstride |= q_data->format.plane_fmt[1].bytesperline
954 << FD1_WPF_PSTRIDE_C_SHIFT;
956 format = q_data->fmt->fmt; /* Output Format Code */
958 if (q_data->fmt->swap_yc)
959 format |= FD1_WPF_FORMAT_WSPYCS;
961 if (q_data->fmt->swap_uv)
962 format |= FD1_WPF_FORMAT_WSPUVS;
964 if (fdp1_fmt_is_rgb(q_data->fmt)) {
965 /* Enable Colour Space conversion */
966 format |= FD1_WPF_FORMAT_CSC;
969 if (src_q_data->format.ycbcr_enc == V4L2_YCBCR_ENC_709)
970 format |= FD1_WPF_FORMAT_WRTM_709_16;
971 else if (src_q_data->format.quantization ==
972 V4L2_QUANTIZATION_FULL_RANGE)
973 format |= FD1_WPF_FORMAT_WRTM_601_0;
975 format |= FD1_WPF_FORMAT_WRTM_601_16;
978 /* Set an alpha value into the Pad Value */
979 format |= ctx->alpha << FD1_WPF_FORMAT_PDV_SHIFT;
981 /* Determine picture rounding and clipping */
982 rndctl = FD1_WPF_RNDCTL_CBRM; /* Rounding Off */
983 rndctl |= FD1_WPF_RNDCTL_CLMD_NOCLIP;
985 /* WPF Swap needs both ISWAP and OSWAP setting */
986 swap = q_data->fmt->swap << FD1_WPF_SWAP_OSWAP_SHIFT;
987 swap |= src_q_data->fmt->swap << FD1_WPF_SWAP_SSWAP_SHIFT;
989 fdp1_write(fdp1, format, FD1_WPF_FORMAT);
990 fdp1_write(fdp1, rndctl, FD1_WPF_RNDCTL);
991 fdp1_write(fdp1, swap, FD1_WPF_SWAP);
992 fdp1_write(fdp1, pstride, FD1_WPF_PSTRIDE);
994 fdp1_write(fdp1, job->dst->addrs[0], FD1_WPF_ADDR_Y);
995 fdp1_write(fdp1, job->dst->addrs[1], FD1_WPF_ADDR_C0);
996 fdp1_write(fdp1, job->dst->addrs[2], FD1_WPF_ADDR_C1);
999 static void fdp1_configure_deint_mode(struct fdp1_ctx *ctx,
1000 struct fdp1_job *job)
1002 struct fdp1_dev *fdp1 = ctx->fdp1;
1003 u32 opmode = FD1_CTL_OPMODE_VIMD_NOINTERRUPT;
1004 u32 ipcmode = FD1_IPC_MODE_DLI; /* Always set */
1005 u32 channels = FD1_CTL_CHACT_WR | FD1_CTL_CHACT_RD1; /* Always on */
1007 /* De-interlacing Mode */
1008 switch (ctx->deint_mode) {
1010 case FDP1_PROGRESSIVE:
1011 dprintk(fdp1, "Progressive Mode\n");
1012 opmode |= FD1_CTL_OPMODE_PRG;
1013 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1015 case FDP1_ADAPT2D3D:
1016 dprintk(fdp1, "Adapt2D3D Mode\n");
1017 if (ctx->sequence == 0 || ctx->aborting)
1018 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1020 ipcmode |= FD1_IPC_MODE_DIM_ADAPT2D3D;
1022 if (ctx->sequence > 1) {
1023 channels |= FD1_CTL_CHACT_SMW;
1024 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2;
1027 if (ctx->sequence > 2)
1028 channels |= FD1_CTL_CHACT_SMR;
1032 dprintk(fdp1, "Fixed 3D Mode\n");
1033 ipcmode |= FD1_IPC_MODE_DIM_FIXED3D;
1034 /* Except for first and last frame, enable all channels */
1035 if (!(ctx->sequence == 0 || ctx->aborting))
1036 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2;
1039 dprintk(fdp1, "Fixed 2D Mode\n");
1040 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1041 /* No extra channels enabled */
1043 case FDP1_PREVFIELD:
1044 dprintk(fdp1, "Previous Field Mode\n");
1045 ipcmode |= FD1_IPC_MODE_DIM_PREVFIELD;
1046 channels |= FD1_CTL_CHACT_RD0; /* Previous */
1048 case FDP1_NEXTFIELD:
1049 dprintk(fdp1, "Next Field Mode\n");
1050 ipcmode |= FD1_IPC_MODE_DIM_NEXTFIELD;
1051 channels |= FD1_CTL_CHACT_RD2; /* Next */
1055 fdp1_write(fdp1, channels, FD1_CTL_CHACT);
1056 fdp1_write(fdp1, opmode, FD1_CTL_OPMODE);
1057 fdp1_write(fdp1, ipcmode, FD1_IPC_MODE);
1061 * fdp1_device_process() - Run the hardware
1063 * Configure and start the hardware to generate a single frame
1064 * of output given our input parameters.
1066 static int fdp1_device_process(struct fdp1_ctx *ctx)
1069 struct fdp1_dev *fdp1 = ctx->fdp1;
1070 struct fdp1_job *job;
1071 unsigned long flags;
1073 spin_lock_irqsave(&fdp1->device_process_lock, flags);
1075 /* Get a job to process */
1076 job = get_queued_job(fdp1);
1079 * VINT can call us to see if we can queue another job.
1080 * If we have no work to do, we simply return.
1082 spin_unlock_irqrestore(&fdp1->device_process_lock, flags);
1086 /* First Frame only? ... */
1087 fdp1_write(fdp1, FD1_CTL_CLKCTRL_CSTP_N, FD1_CTL_CLKCTRL);
1089 /* Set the mode, and configuration */
1090 fdp1_configure_deint_mode(ctx, job);
1092 /* DLI Static Configuration */
1093 fdp1_set_ipc_dli(ctx);
1095 /* Sensor Configuration */
1096 fdp1_set_ipc_sensor(ctx);
1098 /* Setup the source picture */
1099 fdp1_configure_rpf(ctx, job);
1101 /* Setup the destination picture */
1102 fdp1_configure_wpf(ctx, job);
1104 /* Line Memory Pixel Number Register for linear access */
1105 fdp1_write(fdp1, FD1_IPC_LMEM_LINEAR, FD1_IPC_LMEM);
1107 /* Enable Interrupts */
1108 fdp1_write(fdp1, FD1_CTL_IRQ_MASK, FD1_CTL_IRQENB);
1110 /* Finally, the Immediate Registers */
1112 /* This job is now in the HW queue */
1113 queue_hw_job(fdp1, job);
1115 /* Start the command */
1116 fdp1_write(fdp1, FD1_CTL_CMD_STRCMD, FD1_CTL_CMD);
1118 /* Registers will update to HW at next VINT */
1119 fdp1_write(fdp1, FD1_CTL_REGEND_REGEND, FD1_CTL_REGEND);
1121 /* Enable VINT Generator */
1122 fdp1_write(fdp1, FD1_CTL_SGCMD_SGEN, FD1_CTL_SGCMD);
1124 spin_unlock_irqrestore(&fdp1->device_process_lock, flags);
1134 * job_ready() - check whether an instance is ready to be scheduled to run
1136 static int fdp1_m2m_job_ready(void *priv)
1138 struct fdp1_ctx *ctx = priv;
1139 struct fdp1_q_data *src_q_data = &ctx->out_q;
1143 dprintk(ctx->fdp1, "+ Src: %d : Dst: %d\n",
1144 v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx),
1145 v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx));
1147 /* One output buffer is required for each field */
1148 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
1151 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < srcbufs
1152 || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < dstbufs) {
1153 dprintk(ctx->fdp1, "Not enough buffers available\n");
1160 static void fdp1_m2m_job_abort(void *priv)
1162 struct fdp1_ctx *ctx = priv;
1164 dprintk(ctx->fdp1, "+\n");
1166 /* Will cancel the transaction in the next interrupt handler */
1169 /* Immediate abort sequence */
1170 fdp1_write(ctx->fdp1, 0, FD1_CTL_SGCMD);
1171 fdp1_write(ctx->fdp1, FD1_CTL_SRESET_SRST, FD1_CTL_SRESET);
1175 * fdp1_prepare_job: Prepare and queue a new job for a single action of work
1177 * Prepare the next field, (or frame in progressive) and an output
1178 * buffer for the hardware to perform a single operation.
1180 static struct fdp1_job *fdp1_prepare_job(struct fdp1_ctx *ctx)
1182 struct vb2_v4l2_buffer *vbuf;
1183 struct fdp1_buffer *fbuf;
1184 struct fdp1_dev *fdp1 = ctx->fdp1;
1185 struct fdp1_job *job;
1186 unsigned int buffers_required = 1;
1188 dprintk(fdp1, "+\n");
1190 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode))
1191 buffers_required = 2;
1193 if (ctx->buffers_queued < buffers_required)
1196 job = fdp1_job_alloc(fdp1);
1198 dprintk(fdp1, "No free jobs currently available\n");
1202 job->active = fdp1_dequeue_field(ctx);
1204 /* Buffer check should prevent this ever happening */
1205 dprintk(fdp1, "No input buffers currently available\n");
1207 fdp1_job_free(fdp1, job);
1211 dprintk(fdp1, "+ Buffer en-route...\n");
1213 /* Source buffers have been prepared on our buffer_queue
1214 * Prepare our Output buffer
1216 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1217 fbuf = to_fdp1_buffer(vbuf);
1218 job->dst = &fbuf->fields[0];
1220 job->active->vb->sequence = ctx->sequence;
1221 job->dst->vb->sequence = ctx->sequence;
1224 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) {
1225 job->previous = ctx->previous;
1227 /* Active buffer becomes the next job's previous buffer */
1228 ctx->previous = job->active;
1231 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode)) {
1232 /* Must be called after 'active' is dequeued */
1233 job->next = fdp1_peek_queued_field(ctx);
1236 /* Transfer timestamps and flags from src->dst */
1238 job->dst->vb->vb2_buf.timestamp = job->active->vb->vb2_buf.timestamp;
1240 job->dst->vb->flags = job->active->vb->flags &
1241 V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
1243 /* Ideally, the frame-end function will just 'check' to see
1244 * if there are more jobs instead
1248 /* Finally, Put this job on the processing queue */
1249 queue_job(fdp1, job);
1251 dprintk(fdp1, "Job Queued translen = %d\n", ctx->translen);
1256 /* fdp1_m2m_device_run() - prepares and starts the device for an M2M task
1258 * A single input buffer is taken and serialised into our fdp1_buffer
1259 * queue. The queue is then processed to create as many jobs as possible
1260 * from our available input.
1262 static void fdp1_m2m_device_run(void *priv)
1264 struct fdp1_ctx *ctx = priv;
1265 struct fdp1_dev *fdp1 = ctx->fdp1;
1266 struct vb2_v4l2_buffer *src_vb;
1267 struct fdp1_buffer *buf;
1270 dprintk(fdp1, "+\n");
1274 /* Get our incoming buffer of either one or two fields, or one frame */
1275 src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1276 buf = to_fdp1_buffer(src_vb);
1278 for (i = 0; i < buf->num_fields; i++) {
1279 struct fdp1_field_buffer *fbuf = &buf->fields[i];
1281 fdp1_queue_field(ctx, fbuf);
1282 dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n",
1283 i, fbuf->last_field);
1286 /* Queue as many jobs as our data provides for */
1287 while (fdp1_prepare_job(ctx))
1290 if (ctx->translen == 0) {
1291 dprintk(fdp1, "No jobs were processed. M2M action complete\n");
1292 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx);
1296 /* Kick the job processing action */
1297 fdp1_device_process(ctx);
1303 * Handles the M2M level after a buffer completion event.
1305 static void device_frame_end(struct fdp1_dev *fdp1,
1306 enum vb2_buffer_state state)
1308 struct fdp1_ctx *ctx;
1309 unsigned long flags;
1310 struct fdp1_job *job = get_hw_queued_job(fdp1);
1312 dprintk(fdp1, "+\n");
1314 ctx = v4l2_m2m_get_curr_priv(fdp1->m2m_dev);
1317 v4l2_err(&fdp1->v4l2_dev,
1318 "Instance released before the end of transaction\n");
1322 ctx->num_processed++;
1325 * fdp1_field_complete will call buf_done only when the last vb2_buffer
1326 * reference is complete
1328 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
1329 fdp1_field_complete(ctx, job->previous);
1331 fdp1_field_complete(ctx, job->active);
1333 spin_lock_irqsave(&fdp1->irqlock, flags);
1334 v4l2_m2m_buf_done(job->dst->vb, state);
1336 spin_unlock_irqrestore(&fdp1->irqlock, flags);
1338 /* Move this job back to the free job list */
1339 fdp1_job_free(fdp1, job);
1341 dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n",
1342 ctx->num_processed, ctx->translen);
1344 if (ctx->num_processed == ctx->translen ||
1346 dprintk(ctx->fdp1, "Finishing transaction\n");
1347 ctx->num_processed = 0;
1348 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx);
1351 * For pipelined performance support, this would
1352 * be called from a VINT handler
1354 fdp1_device_process(ctx);
1361 static int fdp1_vidioc_querycap(struct file *file, void *priv,
1362 struct v4l2_capability *cap)
1364 strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
1365 strscpy(cap->card, DRIVER_NAME, sizeof(cap->card));
1366 snprintf(cap->bus_info, sizeof(cap->bus_info),
1367 "platform:%s", DRIVER_NAME);
1371 static int fdp1_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
1373 unsigned int i, num;
1377 for (i = 0; i < ARRAY_SIZE(fdp1_formats); ++i) {
1378 if (fdp1_formats[i].types & type) {
1379 if (num == f->index)
1385 /* Format not found */
1386 if (i >= ARRAY_SIZE(fdp1_formats))
1390 f->pixelformat = fdp1_formats[i].fourcc;
1395 static int fdp1_enum_fmt_vid_cap(struct file *file, void *priv,
1396 struct v4l2_fmtdesc *f)
1398 return fdp1_enum_fmt(f, FDP1_CAPTURE);
1401 static int fdp1_enum_fmt_vid_out(struct file *file, void *priv,
1402 struct v4l2_fmtdesc *f)
1404 return fdp1_enum_fmt(f, FDP1_OUTPUT);
1407 static int fdp1_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1409 struct fdp1_q_data *q_data;
1410 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1412 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
1415 q_data = get_q_data(ctx, f->type);
1416 f->fmt.pix_mp = q_data->format;
1421 static void fdp1_compute_stride(struct v4l2_pix_format_mplane *pix,
1422 const struct fdp1_fmt *fmt)
1426 /* Compute and clamp the stride and image size. */
1427 for (i = 0; i < min_t(unsigned int, fmt->num_planes, 2U); ++i) {
1428 unsigned int hsub = i > 0 ? fmt->hsub : 1;
1429 unsigned int vsub = i > 0 ? fmt->vsub : 1;
1430 /* From VSP : TODO: Confirm alignment limits for FDP1 */
1431 unsigned int align = 128;
1434 bpl = clamp_t(unsigned int, pix->plane_fmt[i].bytesperline,
1435 pix->width / hsub * fmt->bpp[i] / 8,
1436 round_down(FDP1_MAX_STRIDE, align));
1438 pix->plane_fmt[i].bytesperline = round_up(bpl, align);
1439 pix->plane_fmt[i].sizeimage = pix->plane_fmt[i].bytesperline
1440 * pix->height / vsub;
1444 if (fmt->num_planes == 3) {
1445 /* The two chroma planes must have the same stride. */
1446 pix->plane_fmt[2].bytesperline = pix->plane_fmt[1].bytesperline;
1447 pix->plane_fmt[2].sizeimage = pix->plane_fmt[1].sizeimage;
1452 static void fdp1_try_fmt_output(struct fdp1_ctx *ctx,
1453 const struct fdp1_fmt **fmtinfo,
1454 struct v4l2_pix_format_mplane *pix)
1456 const struct fdp1_fmt *fmt;
1458 unsigned int height;
1460 /* Validate the pixel format to ensure the output queue supports it. */
1461 fmt = fdp1_find_format(pix->pixelformat);
1462 if (!fmt || !(fmt->types & FDP1_OUTPUT))
1463 fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV);
1468 pix->pixelformat = fmt->fourcc;
1469 pix->num_planes = fmt->num_planes;
1472 * Progressive video and all interlaced field orders are acceptable.
1473 * Default to V4L2_FIELD_INTERLACED.
1475 if (pix->field != V4L2_FIELD_NONE &&
1476 pix->field != V4L2_FIELD_ALTERNATE &&
1477 !V4L2_FIELD_HAS_BOTH(pix->field))
1478 pix->field = V4L2_FIELD_INTERLACED;
1481 * The deinterlacer doesn't care about the colorspace, accept all values
1482 * and default to V4L2_COLORSPACE_SMPTE170M. The YUV to RGB conversion
1483 * at the output of the deinterlacer supports a subset of encodings and
1484 * quantization methods and will only be available when the colorspace
1487 if (pix->colorspace == V4L2_COLORSPACE_DEFAULT)
1488 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1491 * Align the width and height for YUV 4:2:2 and 4:2:0 formats and clamp
1492 * them to the supported frame size range. The height boundary are
1493 * related to the full frame, divide them by two when the format passes
1494 * fields in separate buffers.
1496 width = round_down(pix->width, fmt->hsub);
1497 pix->width = clamp(width, FDP1_MIN_W, FDP1_MAX_W);
1499 height = round_down(pix->height, fmt->vsub);
1500 if (pix->field == V4L2_FIELD_ALTERNATE)
1501 pix->height = clamp(height, FDP1_MIN_H / 2, FDP1_MAX_H / 2);
1503 pix->height = clamp(height, FDP1_MIN_H, FDP1_MAX_H);
1505 fdp1_compute_stride(pix, fmt);
1508 static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx,
1509 const struct fdp1_fmt **fmtinfo,
1510 struct v4l2_pix_format_mplane *pix)
1512 struct fdp1_q_data *src_data = &ctx->out_q;
1513 enum v4l2_colorspace colorspace;
1514 enum v4l2_ycbcr_encoding ycbcr_enc;
1515 enum v4l2_quantization quantization;
1516 const struct fdp1_fmt *fmt;
1520 * Validate the pixel format. We can only accept RGB output formats if
1521 * the input encoding and quantization are compatible with the format
1522 * conversions supported by the hardware. The supported combinations are
1524 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_LIM_RANGE
1525 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_FULL_RANGE
1526 * V4L2_YCBCR_ENC_709 + V4L2_QUANTIZATION_LIM_RANGE
1528 colorspace = src_data->format.colorspace;
1530 ycbcr_enc = src_data->format.ycbcr_enc;
1531 if (ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1532 ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(colorspace);
1534 quantization = src_data->format.quantization;
1535 if (quantization == V4L2_QUANTIZATION_DEFAULT)
1536 quantization = V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace,
1539 allow_rgb = ycbcr_enc == V4L2_YCBCR_ENC_601 ||
1540 (ycbcr_enc == V4L2_YCBCR_ENC_709 &&
1541 quantization == V4L2_QUANTIZATION_LIM_RANGE);
1543 fmt = fdp1_find_format(pix->pixelformat);
1544 if (!fmt || (!allow_rgb && fdp1_fmt_is_rgb(fmt)))
1545 fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV);
1550 pix->pixelformat = fmt->fourcc;
1551 pix->num_planes = fmt->num_planes;
1552 pix->field = V4L2_FIELD_NONE;
1555 * The colorspace on the capture queue is copied from the output queue
1556 * as the hardware can't change the colorspace. It can convert YCbCr to
1557 * RGB though, in which case the encoding and quantization are set to
1558 * default values as anything else wouldn't make sense.
1560 pix->colorspace = src_data->format.colorspace;
1561 pix->xfer_func = src_data->format.xfer_func;
1563 if (fdp1_fmt_is_rgb(fmt)) {
1564 pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1565 pix->quantization = V4L2_QUANTIZATION_DEFAULT;
1567 pix->ycbcr_enc = src_data->format.ycbcr_enc;
1568 pix->quantization = src_data->format.quantization;
1572 * The frame width is identical to the output queue, and the height is
1573 * either doubled or identical depending on whether the output queue
1574 * field order contains one or two fields per frame.
1576 pix->width = src_data->format.width;
1577 if (src_data->format.field == V4L2_FIELD_ALTERNATE)
1578 pix->height = 2 * src_data->format.height;
1580 pix->height = src_data->format.height;
1582 fdp1_compute_stride(pix, fmt);
1585 static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1587 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1589 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1590 fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp);
1592 fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp);
1594 dprintk(ctx->fdp1, "Try %s format: %4.4s (0x%08x) %ux%u field %u\n",
1595 V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
1596 (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
1597 f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
1602 static void fdp1_set_format(struct fdp1_ctx *ctx,
1603 struct v4l2_pix_format_mplane *pix,
1604 enum v4l2_buf_type type)
1606 struct fdp1_q_data *q_data = get_q_data(ctx, type);
1607 const struct fdp1_fmt *fmtinfo;
1609 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1610 fdp1_try_fmt_output(ctx, &fmtinfo, pix);
1612 fdp1_try_fmt_capture(ctx, &fmtinfo, pix);
1614 q_data->fmt = fmtinfo;
1615 q_data->format = *pix;
1617 q_data->vsize = pix->height;
1618 if (pix->field != V4L2_FIELD_NONE)
1621 q_data->stride_y = pix->plane_fmt[0].bytesperline;
1622 q_data->stride_c = pix->plane_fmt[1].bytesperline;
1624 /* Adjust strides for interleaved buffers */
1625 if (pix->field == V4L2_FIELD_INTERLACED ||
1626 pix->field == V4L2_FIELD_INTERLACED_TB ||
1627 pix->field == V4L2_FIELD_INTERLACED_BT) {
1628 q_data->stride_y *= 2;
1629 q_data->stride_c *= 2;
1632 /* Propagate the format from the output node to the capture node. */
1633 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1634 struct fdp1_q_data *dst_data = &ctx->cap_q;
1637 * Copy the format, clear the per-plane bytes per line and image
1638 * size, override the field and double the height if needed.
1640 dst_data->format = q_data->format;
1641 memset(dst_data->format.plane_fmt, 0,
1642 sizeof(dst_data->format.plane_fmt));
1644 dst_data->format.field = V4L2_FIELD_NONE;
1645 if (pix->field == V4L2_FIELD_ALTERNATE)
1646 dst_data->format.height *= 2;
1648 fdp1_try_fmt_capture(ctx, &dst_data->fmt, &dst_data->format);
1650 dst_data->vsize = dst_data->format.height;
1651 dst_data->stride_y = dst_data->format.plane_fmt[0].bytesperline;
1652 dst_data->stride_c = dst_data->format.plane_fmt[1].bytesperline;
1656 static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
1658 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1659 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
1660 struct vb2_queue *vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
1662 if (vb2_is_busy(vq)) {
1663 v4l2_err(&ctx->fdp1->v4l2_dev, "%s queue busy\n", __func__);
1667 fdp1_set_format(ctx, &f->fmt.pix_mp, f->type);
1669 dprintk(ctx->fdp1, "Set %s format: %4.4s (0x%08x) %ux%u field %u\n",
1670 V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
1671 (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
1672 f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
1677 static int fdp1_g_ctrl(struct v4l2_ctrl *ctrl)
1679 struct fdp1_ctx *ctx =
1680 container_of(ctrl->handler, struct fdp1_ctx, hdl);
1681 struct fdp1_q_data *src_q_data = &ctx->out_q;
1684 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1685 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
1695 static int fdp1_s_ctrl(struct v4l2_ctrl *ctrl)
1697 struct fdp1_ctx *ctx =
1698 container_of(ctrl->handler, struct fdp1_ctx, hdl);
1701 case V4L2_CID_ALPHA_COMPONENT:
1702 ctx->alpha = ctrl->val;
1705 case V4L2_CID_DEINTERLACING_MODE:
1706 ctx->deint_mode = ctrl->val;
1713 static const struct v4l2_ctrl_ops fdp1_ctrl_ops = {
1714 .s_ctrl = fdp1_s_ctrl,
1715 .g_volatile_ctrl = fdp1_g_ctrl,
1718 static const char * const fdp1_ctrl_deint_menu[] = {
1728 static const struct v4l2_ioctl_ops fdp1_ioctl_ops = {
1729 .vidioc_querycap = fdp1_vidioc_querycap,
1731 .vidioc_enum_fmt_vid_cap = fdp1_enum_fmt_vid_cap,
1732 .vidioc_enum_fmt_vid_out = fdp1_enum_fmt_vid_out,
1733 .vidioc_g_fmt_vid_cap_mplane = fdp1_g_fmt,
1734 .vidioc_g_fmt_vid_out_mplane = fdp1_g_fmt,
1735 .vidioc_try_fmt_vid_cap_mplane = fdp1_try_fmt,
1736 .vidioc_try_fmt_vid_out_mplane = fdp1_try_fmt,
1737 .vidioc_s_fmt_vid_cap_mplane = fdp1_s_fmt,
1738 .vidioc_s_fmt_vid_out_mplane = fdp1_s_fmt,
1740 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1741 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1742 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1743 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1744 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
1745 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
1746 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
1748 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1749 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1751 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1752 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1759 static int fdp1_queue_setup(struct vb2_queue *vq,
1760 unsigned int *nbuffers, unsigned int *nplanes,
1761 unsigned int sizes[],
1762 struct device *alloc_ctxs[])
1764 struct fdp1_ctx *ctx = vb2_get_drv_priv(vq);
1765 struct fdp1_q_data *q_data;
1768 q_data = get_q_data(ctx, vq->type);
1771 if (*nplanes > FDP1_MAX_PLANES)
1777 *nplanes = q_data->format.num_planes;
1779 for (i = 0; i < *nplanes; i++)
1780 sizes[i] = q_data->format.plane_fmt[i].sizeimage;
1785 static void fdp1_buf_prepare_field(struct fdp1_q_data *q_data,
1786 struct vb2_v4l2_buffer *vbuf,
1787 unsigned int field_num)
1789 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1790 struct fdp1_field_buffer *fbuf = &buf->fields[field_num];
1791 unsigned int num_fields;
1794 num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1797 fbuf->last_field = (field_num + 1) == num_fields;
1799 for (i = 0; i < vbuf->vb2_buf.num_planes; ++i)
1800 fbuf->addrs[i] = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, i);
1802 switch (vbuf->field) {
1803 case V4L2_FIELD_INTERLACED:
1805 * Interlaced means bottom-top for 60Hz TV standards (NTSC) and
1806 * top-bottom for 50Hz. As TV standards are not applicable to
1807 * the mem-to-mem API, use the height as a heuristic.
1809 fbuf->field = (q_data->format.height < 576) == field_num
1810 ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1812 case V4L2_FIELD_INTERLACED_TB:
1813 case V4L2_FIELD_SEQ_TB:
1814 fbuf->field = field_num ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
1816 case V4L2_FIELD_INTERLACED_BT:
1817 case V4L2_FIELD_SEQ_BT:
1818 fbuf->field = field_num ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1821 fbuf->field = vbuf->field;
1825 /* Buffer is completed */
1829 /* Adjust buffer addresses for second field */
1830 switch (vbuf->field) {
1831 case V4L2_FIELD_INTERLACED:
1832 case V4L2_FIELD_INTERLACED_TB:
1833 case V4L2_FIELD_INTERLACED_BT:
1834 for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
1836 (i == 0 ? q_data->stride_y : q_data->stride_c);
1838 case V4L2_FIELD_SEQ_TB:
1839 case V4L2_FIELD_SEQ_BT:
1840 for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
1841 fbuf->addrs[i] += q_data->vsize *
1842 (i == 0 ? q_data->stride_y : q_data->stride_c);
1847 static int fdp1_buf_prepare(struct vb2_buffer *vb)
1849 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1850 struct fdp1_q_data *q_data = get_q_data(ctx, vb->vb2_queue->type);
1851 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1852 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1855 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1856 bool field_valid = true;
1858 /* Validate the buffer field. */
1859 switch (q_data->format.field) {
1860 case V4L2_FIELD_NONE:
1861 if (vbuf->field != V4L2_FIELD_NONE)
1862 field_valid = false;
1865 case V4L2_FIELD_ALTERNATE:
1866 if (vbuf->field != V4L2_FIELD_TOP &&
1867 vbuf->field != V4L2_FIELD_BOTTOM)
1868 field_valid = false;
1871 case V4L2_FIELD_INTERLACED:
1872 case V4L2_FIELD_SEQ_TB:
1873 case V4L2_FIELD_SEQ_BT:
1874 case V4L2_FIELD_INTERLACED_TB:
1875 case V4L2_FIELD_INTERLACED_BT:
1876 if (vbuf->field != q_data->format.field)
1877 field_valid = false;
1883 "buffer field %u invalid for format field %u\n",
1884 vbuf->field, q_data->format.field);
1888 vbuf->field = V4L2_FIELD_NONE;
1891 /* Validate the planes sizes. */
1892 for (i = 0; i < q_data->format.num_planes; i++) {
1893 unsigned long size = q_data->format.plane_fmt[i].sizeimage;
1895 if (vb2_plane_size(vb, i) < size) {
1897 "data will not fit into plane [%u/%u] (%lu < %lu)\n",
1898 i, q_data->format.num_planes,
1899 vb2_plane_size(vb, i), size);
1903 /* We have known size formats all around */
1904 vb2_set_plane_payload(vb, i, size);
1907 buf->num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1908 for (i = 0; i < buf->num_fields; ++i)
1909 fdp1_buf_prepare_field(q_data, vbuf, i);
1914 static void fdp1_buf_queue(struct vb2_buffer *vb)
1916 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1917 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1919 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1922 static int fdp1_start_streaming(struct vb2_queue *q, unsigned int count)
1924 struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1925 struct fdp1_q_data *q_data = get_q_data(ctx, q->type);
1927 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1929 * Force our deint_mode when we are progressive,
1930 * ignoring any setting on the device from the user,
1931 * Otherwise, lock in the requested de-interlace mode.
1933 if (q_data->format.field == V4L2_FIELD_NONE)
1934 ctx->deint_mode = FDP1_PROGRESSIVE;
1936 if (ctx->deint_mode == FDP1_ADAPT2D3D) {
1938 dma_addr_t smsk_base;
1939 const u32 bpp = 2; /* bytes per pixel */
1941 stride = round_up(q_data->format.width, 8);
1943 ctx->smsk_size = bpp * stride * q_data->vsize;
1945 ctx->smsk_cpu = dma_alloc_coherent(ctx->fdp1->dev,
1946 ctx->smsk_size, &smsk_base, GFP_KERNEL);
1948 if (ctx->smsk_cpu == NULL) {
1949 dprintk(ctx->fdp1, "Failed to alloc smsk\n");
1953 ctx->smsk_addr[0] = smsk_base;
1954 ctx->smsk_addr[1] = smsk_base + (ctx->smsk_size/2);
1961 static void fdp1_stop_streaming(struct vb2_queue *q)
1963 struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1964 struct vb2_v4l2_buffer *vbuf;
1965 unsigned long flags;
1968 if (V4L2_TYPE_IS_OUTPUT(q->type))
1969 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1971 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1974 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
1975 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1976 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
1979 /* Empty Output queues */
1980 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1981 /* Empty our internal queues */
1982 struct fdp1_field_buffer *fbuf;
1984 /* Free any queued buffers */
1985 fbuf = fdp1_dequeue_field(ctx);
1986 while (fbuf != NULL) {
1987 fdp1_field_complete(ctx, fbuf);
1988 fbuf = fdp1_dequeue_field(ctx);
1991 /* Free smsk_data */
1992 if (ctx->smsk_cpu) {
1993 dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size,
1994 ctx->smsk_cpu, ctx->smsk_addr[0]);
1995 ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0;
1996 ctx->smsk_cpu = NULL;
1999 WARN(!list_empty(&ctx->fields_queue),
2000 "Buffer queue not empty");
2002 /* Empty Capture queues (Jobs) */
2003 struct fdp1_job *job;
2005 job = get_queued_job(ctx->fdp1);
2007 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
2008 fdp1_field_complete(ctx, job->previous);
2010 fdp1_field_complete(ctx, job->active);
2012 v4l2_m2m_buf_done(job->dst->vb, VB2_BUF_STATE_ERROR);
2015 job = get_queued_job(ctx->fdp1);
2018 /* Free any held buffer in the ctx */
2019 fdp1_field_complete(ctx, ctx->previous);
2021 WARN(!list_empty(&ctx->fdp1->queued_job_list),
2022 "Queued Job List not empty");
2024 WARN(!list_empty(&ctx->fdp1->hw_job_list),
2025 "HW Job list not empty");
2029 static const struct vb2_ops fdp1_qops = {
2030 .queue_setup = fdp1_queue_setup,
2031 .buf_prepare = fdp1_buf_prepare,
2032 .buf_queue = fdp1_buf_queue,
2033 .start_streaming = fdp1_start_streaming,
2034 .stop_streaming = fdp1_stop_streaming,
2035 .wait_prepare = vb2_ops_wait_prepare,
2036 .wait_finish = vb2_ops_wait_finish,
2039 static int queue_init(void *priv, struct vb2_queue *src_vq,
2040 struct vb2_queue *dst_vq)
2042 struct fdp1_ctx *ctx = priv;
2045 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2046 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
2047 src_vq->drv_priv = ctx;
2048 src_vq->buf_struct_size = sizeof(struct fdp1_buffer);
2049 src_vq->ops = &fdp1_qops;
2050 src_vq->mem_ops = &vb2_dma_contig_memops;
2051 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2052 src_vq->lock = &ctx->fdp1->dev_mutex;
2053 src_vq->dev = ctx->fdp1->dev;
2055 ret = vb2_queue_init(src_vq);
2059 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2060 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
2061 dst_vq->drv_priv = ctx;
2062 dst_vq->buf_struct_size = sizeof(struct fdp1_buffer);
2063 dst_vq->ops = &fdp1_qops;
2064 dst_vq->mem_ops = &vb2_dma_contig_memops;
2065 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2066 dst_vq->lock = &ctx->fdp1->dev_mutex;
2067 dst_vq->dev = ctx->fdp1->dev;
2069 return vb2_queue_init(dst_vq);
2075 static int fdp1_open(struct file *file)
2077 struct fdp1_dev *fdp1 = video_drvdata(file);
2078 struct v4l2_pix_format_mplane format;
2079 struct fdp1_ctx *ctx = NULL;
2080 struct v4l2_ctrl *ctrl;
2083 if (mutex_lock_interruptible(&fdp1->dev_mutex))
2084 return -ERESTARTSYS;
2086 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2092 v4l2_fh_init(&ctx->fh, video_devdata(file));
2093 file->private_data = &ctx->fh;
2096 /* Initialise Queues */
2097 INIT_LIST_HEAD(&ctx->fields_queue);
2102 /* Initialise controls */
2104 v4l2_ctrl_handler_init(&ctx->hdl, 3);
2105 v4l2_ctrl_new_std_menu_items(&ctx->hdl, &fdp1_ctrl_ops,
2106 V4L2_CID_DEINTERLACING_MODE,
2107 FDP1_NEXTFIELD, BIT(0), FDP1_FIXED3D,
2108 fdp1_ctrl_deint_menu);
2110 ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2111 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1);
2113 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
2115 v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2116 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
2118 if (ctx->hdl.error) {
2119 ret = ctx->hdl.error;
2123 ctx->fh.ctrl_handler = &ctx->hdl;
2124 v4l2_ctrl_handler_setup(&ctx->hdl);
2126 /* Configure default parameters. */
2127 memset(&format, 0, sizeof(format));
2128 fdp1_set_format(ctx, &format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
2130 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fdp1->m2m_dev, ctx, &queue_init);
2132 if (IS_ERR(ctx->fh.m2m_ctx)) {
2133 ret = PTR_ERR(ctx->fh.m2m_ctx);
2137 /* Perform any power management required */
2138 ret = pm_runtime_resume_and_get(fdp1->dev);
2142 v4l2_fh_add(&ctx->fh);
2144 dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n",
2145 ctx, ctx->fh.m2m_ctx);
2147 mutex_unlock(&fdp1->dev_mutex);
2151 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2153 v4l2_ctrl_handler_free(&ctx->hdl);
2156 mutex_unlock(&fdp1->dev_mutex);
2160 static int fdp1_release(struct file *file)
2162 struct fdp1_dev *fdp1 = video_drvdata(file);
2163 struct fdp1_ctx *ctx = fh_to_ctx(file->private_data);
2165 dprintk(fdp1, "Releasing instance %p\n", ctx);
2167 v4l2_fh_del(&ctx->fh);
2168 v4l2_fh_exit(&ctx->fh);
2169 v4l2_ctrl_handler_free(&ctx->hdl);
2170 mutex_lock(&fdp1->dev_mutex);
2171 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2172 mutex_unlock(&fdp1->dev_mutex);
2175 pm_runtime_put(fdp1->dev);
2180 static const struct v4l2_file_operations fdp1_fops = {
2181 .owner = THIS_MODULE,
2183 .release = fdp1_release,
2184 .poll = v4l2_m2m_fop_poll,
2185 .unlocked_ioctl = video_ioctl2,
2186 .mmap = v4l2_m2m_fop_mmap,
2189 static const struct video_device fdp1_videodev = {
2190 .name = DRIVER_NAME,
2191 .vfl_dir = VFL_DIR_M2M,
2193 .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
2194 .ioctl_ops = &fdp1_ioctl_ops,
2196 .release = video_device_release_empty,
2199 static const struct v4l2_m2m_ops m2m_ops = {
2200 .device_run = fdp1_m2m_device_run,
2201 .job_ready = fdp1_m2m_job_ready,
2202 .job_abort = fdp1_m2m_job_abort,
2205 static irqreturn_t fdp1_irq_handler(int irq, void *dev_id)
2207 struct fdp1_dev *fdp1 = dev_id;
2213 int_status = fdp1_read(fdp1, FD1_CTL_IRQSTA);
2214 cycles = fdp1_read(fdp1, FD1_CTL_VCYCLE_STAT);
2215 ctl_status = fdp1_read(fdp1, FD1_CTL_STATUS);
2216 vint_cnt = (ctl_status & FD1_CTL_STATUS_VINT_CNT_MASK) >>
2217 FD1_CTL_STATUS_VINT_CNT_SHIFT;
2219 /* Clear interrupts */
2220 fdp1_write(fdp1, ~(int_status) & FD1_CTL_IRQ_MASK, FD1_CTL_IRQSTA);
2223 dprintk(fdp1, "IRQ: 0x%x %s%s%s\n", int_status,
2224 int_status & FD1_CTL_IRQ_VERE ? "[Error]" : "[!E]",
2225 int_status & FD1_CTL_IRQ_VINTE ? "[VSync]" : "[!V]",
2226 int_status & FD1_CTL_IRQ_FREE ? "[FrameEnd]" : "[!F]");
2228 dprintk(fdp1, "CycleStatus = %d (%dms)\n",
2229 cycles, cycles/(fdp1->clk_rate/1000));
2232 "Control Status = 0x%08x : VINT_CNT = %d %s:%s:%s:%s\n",
2233 ctl_status, vint_cnt,
2234 ctl_status & FD1_CTL_STATUS_SGREGSET ? "RegSet" : "",
2235 ctl_status & FD1_CTL_STATUS_SGVERR ? "Vsync Error" : "",
2236 ctl_status & FD1_CTL_STATUS_SGFREND ? "FrameEnd" : "",
2237 ctl_status & FD1_CTL_STATUS_BSY ? "Busy" : "");
2238 dprintk(fdp1, "***********************************\n");
2241 /* Spurious interrupt */
2242 if (!(FD1_CTL_IRQ_MASK & int_status))
2245 /* Work completed, release the frame */
2246 if (FD1_CTL_IRQ_VERE & int_status)
2247 device_frame_end(fdp1, VB2_BUF_STATE_ERROR);
2248 else if (FD1_CTL_IRQ_FREE & int_status)
2249 device_frame_end(fdp1, VB2_BUF_STATE_DONE);
2254 static int fdp1_probe(struct platform_device *pdev)
2256 struct fdp1_dev *fdp1;
2257 struct video_device *vfd;
2258 struct device_node *fcp_node;
2265 fdp1 = devm_kzalloc(&pdev->dev, sizeof(*fdp1), GFP_KERNEL);
2269 INIT_LIST_HEAD(&fdp1->free_job_list);
2270 INIT_LIST_HEAD(&fdp1->queued_job_list);
2271 INIT_LIST_HEAD(&fdp1->hw_job_list);
2273 /* Initialise the jobs on the free list */
2274 for (i = 0; i < ARRAY_SIZE(fdp1->jobs); i++)
2275 list_add(&fdp1->jobs[i].list, &fdp1->free_job_list);
2277 mutex_init(&fdp1->dev_mutex);
2279 spin_lock_init(&fdp1->irqlock);
2280 spin_lock_init(&fdp1->device_process_lock);
2281 fdp1->dev = &pdev->dev;
2282 platform_set_drvdata(pdev, fdp1);
2284 /* Memory-mapped registers */
2285 fdp1->regs = devm_platform_ioremap_resource(pdev, 0);
2286 if (IS_ERR(fdp1->regs))
2287 return PTR_ERR(fdp1->regs);
2289 /* Interrupt service routine registration */
2290 ret = platform_get_irq(pdev, 0);
2295 ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0,
2296 dev_name(&pdev->dev), fdp1);
2298 dev_err(&pdev->dev, "cannot claim IRQ %d\n", fdp1->irq);
2303 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
2305 fdp1->fcp = rcar_fcp_get(fcp_node);
2306 of_node_put(fcp_node);
2307 if (IS_ERR(fdp1->fcp)) {
2308 dev_dbg(&pdev->dev, "FCP not found (%ld)\n",
2309 PTR_ERR(fdp1->fcp));
2310 return PTR_ERR(fdp1->fcp);
2314 /* Determine our clock rate */
2315 clk = clk_get(&pdev->dev, NULL);
2321 fdp1->clk_rate = clk_get_rate(clk);
2324 /* V4L2 device registration */
2325 ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev);
2327 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2331 /* M2M registration */
2332 fdp1->m2m_dev = v4l2_m2m_init(&m2m_ops);
2333 if (IS_ERR(fdp1->m2m_dev)) {
2334 v4l2_err(&fdp1->v4l2_dev, "Failed to init mem2mem device\n");
2335 ret = PTR_ERR(fdp1->m2m_dev);
2339 /* Video registration */
2340 fdp1->vfd = fdp1_videodev;
2342 vfd->lock = &fdp1->dev_mutex;
2343 vfd->v4l2_dev = &fdp1->v4l2_dev;
2344 video_set_drvdata(vfd, fdp1);
2345 strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));
2347 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2349 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2353 v4l2_info(&fdp1->v4l2_dev, "Device registered as /dev/video%d\n",
2356 /* Power up the cells to read HW */
2357 pm_runtime_enable(&pdev->dev);
2358 ret = pm_runtime_resume_and_get(fdp1->dev);
2362 hw_version = fdp1_read(fdp1, FD1_IP_INTDATA);
2363 switch (hw_version) {
2365 dprintk(fdp1, "FDP1 Version R-Car Gen2\n");
2368 dprintk(fdp1, "FDP1 Version R-Car M3-W\n");
2371 dprintk(fdp1, "FDP1 Version R-Car H3\n");
2374 dprintk(fdp1, "FDP1 Version R-Car M3-N\n");
2377 dprintk(fdp1, "FDP1 Version R-Car E3\n");
2380 dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n",
2384 /* Allow the hw to sleep until an open call puts it to use */
2385 pm_runtime_put(fdp1->dev);
2390 pm_runtime_disable(fdp1->dev);
2393 v4l2_m2m_release(fdp1->m2m_dev);
2396 v4l2_device_unregister(&fdp1->v4l2_dev);
2399 rcar_fcp_put(fdp1->fcp);
2403 static void fdp1_remove(struct platform_device *pdev)
2405 struct fdp1_dev *fdp1 = platform_get_drvdata(pdev);
2407 v4l2_m2m_release(fdp1->m2m_dev);
2408 video_unregister_device(&fdp1->vfd);
2409 v4l2_device_unregister(&fdp1->v4l2_dev);
2410 pm_runtime_disable(&pdev->dev);
2411 rcar_fcp_put(fdp1->fcp);
2414 static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev)
2416 struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2418 rcar_fcp_disable(fdp1->fcp);
2423 static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev)
2425 struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2427 /* Program in the static LUTs */
2430 return rcar_fcp_enable(fdp1->fcp);
2433 static const struct dev_pm_ops fdp1_pm_ops = {
2434 SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend,
2435 fdp1_pm_runtime_resume,
2439 static const struct of_device_id fdp1_dt_ids[] = {
2440 { .compatible = "renesas,fdp1" },
2443 MODULE_DEVICE_TABLE(of, fdp1_dt_ids);
2445 static struct platform_driver fdp1_pdrv = {
2446 .probe = fdp1_probe,
2447 .remove_new = fdp1_remove,
2449 .name = DRIVER_NAME,
2450 .of_match_table = fdp1_dt_ids,
2455 module_platform_driver(fdp1_pdrv);
2457 MODULE_DESCRIPTION("Renesas R-Car Fine Display Processor Driver");
2458 MODULE_AUTHOR("Kieran Bingham <kieran@bingham.xyz>");
2459 MODULE_LICENSE("GPL");
2460 MODULE_ALIAS("platform:" DRIVER_NAME);