2 * Renesas R-Car Fine Display Processor
4 * Video format converter and frame deinterlacer device.
6 * Author: Kieran Bingham, <kieran@bingham.xyz>
7 * Copyright (c) 2016 Renesas Electronics Corporation.
9 * This code is developed and inspired from the vim2m, rcar_jpu,
10 * m2m-deinterlace, and vsp1 drivers.
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
18 #include <linux/clk.h>
19 #include <linux/delay.h>
20 #include <linux/dma-mapping.h>
22 #include <linux/interrupt.h>
23 #include <linux/module.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>
39 static unsigned int debug;
40 module_param(debug, uint, 0644);
41 MODULE_PARM_DESC(debug, "activate debug info");
43 /* Minimum and maximum frame width/height */
44 #define FDP1_MIN_W 80U
45 #define FDP1_MIN_H 80U
47 #define FDP1_MAX_W 3840U
48 #define FDP1_MAX_H 2160U
50 #define FDP1_MAX_PLANES 3U
51 #define FDP1_MAX_STRIDE 8190U
53 /* Flags that indicate a format can be used for capture/output */
54 #define FDP1_CAPTURE BIT(0)
55 #define FDP1_OUTPUT BIT(1)
57 #define DRIVER_NAME "rcar_fdp1"
59 /* Number of Job's to have available on the processing queue */
60 #define FDP1_NUMBER_JOBS 8
62 #define dprintk(fdp1, fmt, arg...) \
63 v4l2_dbg(1, debug, &fdp1->v4l2_dev, "%s: " fmt, __func__, ## arg)
66 * FDP1 registers and bits
69 /* FDP1 start register - Imm */
70 #define FD1_CTL_CMD 0x0000
71 #define FD1_CTL_CMD_STRCMD BIT(0)
73 /* Sync generator register - Imm */
74 #define FD1_CTL_SGCMD 0x0004
75 #define FD1_CTL_SGCMD_SGEN BIT(0)
77 /* Register set end register - Imm */
78 #define FD1_CTL_REGEND 0x0008
79 #define FD1_CTL_REGEND_REGEND BIT(0)
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)
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)
97 #define FD1_CTL_VPERIOD 0x0014
98 #define FD1_CTL_CLKCTRL 0x0018
99 #define FD1_CTL_CLKCTRL_CSTP_N BIT(0)
101 /* Software reset register */
102 #define FD1_CTL_SRESET 0x001c
103 #define FD1_CTL_SRESET_SRST BIT(0)
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)
114 #define FD1_CTL_VCYCLE_STAT 0x0028
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
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 | \
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
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)
143 #define FD1_RPF_PSTRIDE 0x0068
144 #define FD1_RPF_PSTRIDE_Y_SHIFT 16
145 #define FD1_RPF_PSTRIDE_C_SHIFT 0
147 /* RPF0 Source Component Y Address register */
148 #define FD1_RPF0_ADDR_Y 0x006c
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
155 /* RPF2 next picture register */
156 #define FD1_RPF2_ADDR_Y 0x0084
158 #define FD1_RPF_SMSK_ADDR 0x0090
159 #define FD1_RPF_SWAP 0x0094
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)
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)
178 #define FD1_WPF_PSTRIDE 0x00c8
179 #define FD1_WPF_PSTRIDE_Y_SHIFT 16
180 #define FD1_WPF_PSTRIDE_C_SHIFT 0
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
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)
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)
205 #define FD1_IPC_SMSK_THRESH 0x0104
206 #define FD1_IPC_SMSK_THRESH_CONST 0x00010002
208 #define FD1_IPC_COMB_DET 0x0108
209 #define FD1_IPC_COMB_DET_CONST 0x00200040
211 #define FD1_IPC_MOTDEC 0x010c
212 #define FD1_IPC_MOTDEC_CONST 0x00008020
215 #define FD1_IPC_DLI_BLEND 0x0120
216 #define FD1_IPC_DLI_BLEND_CONST 0x0080ff02
218 #define FD1_IPC_DLI_HGAIN 0x0124
219 #define FD1_IPC_DLI_HGAIN_CONST 0x001000ff
221 #define FD1_IPC_DLI_SPRS 0x0128
222 #define FD1_IPC_DLI_SPRS_CONST 0x009004ff
224 #define FD1_IPC_DLI_ANGLE 0x012c
225 #define FD1_IPC_DLI_ANGLE_CONST 0x0004080c
227 #define FD1_IPC_DLI_ISOPIX0 0x0130
228 #define FD1_IPC_DLI_ISOPIX0_CONST 0xff10ff10
230 #define FD1_IPC_DLI_ISOPIX1 0x0134
231 #define FD1_IPC_DLI_ISOPIX1_CONST 0x0000ff10
233 /* Sensor registers */
234 #define FD1_IPC_SENSOR_TH0 0x0140
235 #define FD1_IPC_SENSOR_TH0_CONST 0x20208080
237 #define FD1_IPC_SENSOR_TH1 0x0144
238 #define FD1_IPC_SENSOR_TH1_CONST 0
240 #define FD1_IPC_SENSOR_CTL0 0x0170
241 #define FD1_IPC_SENSOR_CTL0_CONST 0x00002201
243 #define FD1_IPC_SENSOR_CTL1 0x0174
244 #define FD1_IPC_SENSOR_CTL1_CONST 0
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
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
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
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
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
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
300 static const struct fdp1_fmt fdp1_formats[] = {
301 /* RGB formats are only supported by the Write Pixel Formatter */
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,
307 { V4L2_PIX_FMT_XRGB444, { 16, 0, 0 }, 1, 1, 1, 0x01, false, false,
308 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
311 { V4L2_PIX_FMT_XRGB555, { 16, 0, 0 }, 1, 1, 1, 0x04, false, false,
312 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
315 { V4L2_PIX_FMT_RGB565, { 16, 0, 0 }, 1, 1, 1, 0x06, false, false,
316 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
319 { V4L2_PIX_FMT_ABGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
320 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD,
322 { V4L2_PIX_FMT_XBGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
323 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD,
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,
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,
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,
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,
341 { V4L2_PIX_FMT_ARGB444, { 16, 0, 0 }, 1, 1, 1, 0x19, false, false,
342 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
345 { V4L2_PIX_FMT_ARGB555, { 16, 0, 0 }, 1, 1, 1, 0x1b, false, false,
346 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD |
350 /* YUV Formats are supported by Read and Write Pixel Formatters */
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 },
410 static int fdp1_fmt_is_rgb(const struct fdp1_fmt *fmt)
412 return fmt->fmt <= 0x1b; /* Last RGB code */
416 * FDP1 Lookup tables range from 0...255 only
418 * Each table must be less than 256 entries, and all tables
419 * are padded out to 256 entries by duplicating the last value.
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,
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,
433 static const u8 fdp1_bld_gain[] = {
437 static const u8 fdp1_dif_gain[] = {
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
476 /* Per-queue, driver-specific private data */
478 const struct fdp1_fmt *fmt;
479 struct v4l2_pix_format_mplane format;
482 unsigned int stride_y;
483 unsigned int stride_c;
486 static const struct fdp1_fmt *fdp1_find_format(u32 pixelformat)
488 const struct fdp1_fmt *fmt;
491 for (i = 0; i < ARRAY_SIZE(fdp1_formats); i++) {
492 fmt = &fdp1_formats[i];
493 if (fmt->fourcc == pixelformat)
500 enum fdp1_deint_mode {
501 FDP1_PROGRESSIVE = 0, /* Must be zero when !deinterlacing */
509 #define FDP1_DEINT_MODE_USES_NEXT(mode) \
510 (mode == FDP1_ADAPT2D3D || \
511 mode == FDP1_FIXED3D || \
512 mode == FDP1_NEXTFIELD)
514 #define FDP1_DEINT_MODE_USES_PREV(mode) \
515 (mode == FDP1_ADAPT2D3D || \
516 mode == FDP1_FIXED3D || \
517 mode == FDP1_PREVFIELD)
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.
524 struct fdp1_field_buffer {
525 struct vb2_v4l2_buffer *vb;
528 /* Should be NONE:TOP:BOTTOM only */
529 enum v4l2_field field;
531 /* Flag to indicate this is the last field in the vb */
534 /* Buffer queue lists */
535 struct list_head list;
539 struct v4l2_m2m_buffer m2m_buf;
540 struct fdp1_field_buffer fields[2];
541 unsigned int num_fields;
544 static inline struct fdp1_buffer *to_fdp1_buffer(struct vb2_v4l2_buffer *vb)
546 return container_of(vb, struct fdp1_buffer, m2m_buf.vb);
550 struct fdp1_field_buffer *previous;
551 struct fdp1_field_buffer *active;
552 struct fdp1_field_buffer *next;
553 struct fdp1_field_buffer *dst;
555 /* A job can only be on one list at a time */
556 struct list_head list;
560 struct v4l2_device v4l2_dev;
561 struct video_device vfd;
563 struct mutex dev_mutex;
565 spinlock_t device_process_lock;
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;
577 unsigned int clk_rate;
579 struct rcar_fcp_device *fcp;
580 struct v4l2_m2m_dev *m2m_dev;
585 struct fdp1_dev *fdp1;
587 struct v4l2_ctrl_handler hdl;
588 unsigned int sequence;
590 /* Processed buffers in this transaction */
593 /* Transaction length (i.e. how many buffers per transaction) */
596 /* Abort requested by m2m */
599 /* Deinterlace processing mode */
600 enum fdp1_deint_mode deint_mode;
603 * Adaptive 2D/3D mode uses a shared mask
604 * This is allocated at streamon, if the ADAPT2D3D mode
607 unsigned int smsk_size;
608 dma_addr_t smsk_addr[2];
611 /* Capture pipeline, can specify an alpha value
612 * for supported formats. 0-255 only
616 /* Source and destination queue data */
617 struct fdp1_q_data out_q; /* HW Source */
618 struct fdp1_q_data cap_q; /* HW Destination */
622 * Interlaced fields are used on 3 occasions, and tracked in this list.
624 * V4L2 Buffers are tracked inside the fdp1_buffer
625 * and released when the last 'field' completes
627 struct list_head fields_queue;
628 unsigned int buffers_queued;
631 * For de-interlacing we need to track our previous buffer
632 * while preparing our job lists.
634 struct fdp1_field_buffer *previous;
637 static inline struct fdp1_ctx *fh_to_ctx(struct v4l2_fh *fh)
639 return container_of(fh, struct fdp1_ctx, fh);
642 static struct fdp1_q_data *get_q_data(struct fdp1_ctx *ctx,
643 enum v4l2_buf_type type)
645 if (V4L2_TYPE_IS_OUTPUT(type))
652 * list_remove_job: Take the first item off the specified job list
654 * Returns: pointer to a job, or NULL if the list is empty.
656 static struct fdp1_job *list_remove_job(struct fdp1_dev *fdp1,
657 struct list_head *list)
659 struct fdp1_job *job;
662 spin_lock_irqsave(&fdp1->irqlock, flags);
663 job = list_first_entry_or_null(list, struct fdp1_job, list);
665 list_del(&job->list);
666 spin_unlock_irqrestore(&fdp1->irqlock, flags);
672 * list_add_job: Add a job to the specified job list
674 * Returns: void - always succeeds
676 static void list_add_job(struct fdp1_dev *fdp1,
677 struct list_head *list,
678 struct fdp1_job *job)
682 spin_lock_irqsave(&fdp1->irqlock, flags);
683 list_add_tail(&job->list, list);
684 spin_unlock_irqrestore(&fdp1->irqlock, flags);
687 static struct fdp1_job *fdp1_job_alloc(struct fdp1_dev *fdp1)
689 return list_remove_job(fdp1, &fdp1->free_job_list);
692 static void fdp1_job_free(struct fdp1_dev *fdp1, struct fdp1_job *job)
694 /* Ensure that all residue from previous jobs is gone */
695 memset(job, 0, sizeof(struct fdp1_job));
697 list_add_job(fdp1, &fdp1->free_job_list, job);
700 static void queue_job(struct fdp1_dev *fdp1, struct fdp1_job *job)
702 list_add_job(fdp1, &fdp1->queued_job_list, job);
705 static struct fdp1_job *get_queued_job(struct fdp1_dev *fdp1)
707 return list_remove_job(fdp1, &fdp1->queued_job_list);
710 static void queue_hw_job(struct fdp1_dev *fdp1, struct fdp1_job *job)
712 list_add_job(fdp1, &fdp1->hw_job_list, job);
715 static struct fdp1_job *get_hw_queued_job(struct fdp1_dev *fdp1)
717 return list_remove_job(fdp1, &fdp1->hw_job_list);
721 * Buffer lists handling
723 static void fdp1_field_complete(struct fdp1_ctx *ctx,
724 struct fdp1_field_buffer *fbuf)
726 /* job->previous may be on the first field */
730 if (fbuf->last_field)
731 v4l2_m2m_buf_done(fbuf->vb, VB2_BUF_STATE_DONE);
734 static void fdp1_queue_field(struct fdp1_ctx *ctx,
735 struct fdp1_field_buffer *fbuf)
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);
743 ctx->buffers_queued++;
746 static struct fdp1_field_buffer *fdp1_dequeue_field(struct fdp1_ctx *ctx)
748 struct fdp1_field_buffer *fbuf;
751 ctx->buffers_queued--;
753 spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
754 fbuf = list_first_entry_or_null(&ctx->fields_queue,
755 struct fdp1_field_buffer, list);
757 list_del(&fbuf->list);
758 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
764 * Return the next field in the queue - or NULL,
765 * without removing the item from the list
767 static struct fdp1_field_buffer *fdp1_peek_queued_field(struct fdp1_ctx *ctx)
769 struct fdp1_field_buffer *fbuf;
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);
780 static u32 fdp1_read(struct fdp1_dev *fdp1, unsigned int reg)
782 u32 value = ioread32(fdp1->regs + reg);
785 dprintk(fdp1, "Read 0x%08x from 0x%04x\n", value, reg);
790 static void fdp1_write(struct fdp1_dev *fdp1, u32 val, unsigned int reg)
793 dprintk(fdp1, "Write 0x%08x to 0x%04x\n", val, reg);
795 iowrite32(val, fdp1->regs + reg);
798 /* IPC registers are to be programmed with constant values */
799 static void fdp1_set_ipc_dli(struct fdp1_ctx *ctx)
801 struct fdp1_dev *fdp1 = ctx->fdp1;
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);
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);
816 static void fdp1_set_ipc_sensor(struct fdp1_ctx *ctx)
818 struct fdp1_dev *fdp1 = ctx->fdp1;
819 struct fdp1_q_data *src_q_data = &ctx->out_q;
821 unsigned int hsize = src_q_data->format.width;
822 unsigned int vsize = src_q_data->format.height;
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);
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);
836 fdp1_write(fdp1, (x0 << FD1_IPC_SENSOR_CTL3_0_SHIFT) |
837 (x1 << FD1_IPC_SENSOR_CTL3_1_SHIFT),
838 FD1_IPC_SENSOR_CTL3);
842 * fdp1_write_lut: Write a padded LUT to the hw
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.
848 * The last byte of the table is written to all remaining entries.
850 static void fdp1_write_lut(struct fdp1_dev *fdp1, const u8 *lut,
851 unsigned int len, unsigned int base)
856 /* Tables larger than the hw are clipped */
857 len = min(len, 256u);
859 for (i = 0; i < len; i++)
860 fdp1_write(fdp1, lut[i], base + (i*4));
862 /* Tables are padded with the last entry */
866 fdp1_write(fdp1, pad, base + (i*4));
869 static void fdp1_set_lut(struct fdp1_dev *fdp1)
871 fdp1_write_lut(fdp1, fdp1_diff_adj, ARRAY_SIZE(fdp1_diff_adj),
873 fdp1_write_lut(fdp1, fdp1_sad_adj, ARRAY_SIZE(fdp1_sad_adj),
875 fdp1_write_lut(fdp1, fdp1_bld_gain, ARRAY_SIZE(fdp1_bld_gain),
877 fdp1_write_lut(fdp1, fdp1_dif_gain, ARRAY_SIZE(fdp1_dif_gain),
879 fdp1_write_lut(fdp1, fdp1_mdet, ARRAY_SIZE(fdp1_mdet),
883 static void fdp1_configure_rpf(struct fdp1_ctx *ctx,
884 struct fdp1_job *job)
886 struct fdp1_dev *fdp1 = ctx->fdp1;
892 struct fdp1_q_data *q_data = &ctx->out_q;
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);
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;
904 format = q_data->fmt->fmt;
905 if (q_data->fmt->swap_yc)
906 format |= FD1_RPF_FORMAT_RSPYCS;
908 if (q_data->fmt->swap_uv)
909 format |= FD1_RPF_FORMAT_RSPUVS;
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];
915 smsk_addr = ctx->smsk_addr[1];
918 /* Deint mode is non-zero when deinterlacing */
920 format |= FD1_RPF_FORMAT_CIPM;
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);
928 /* Previous Field Channel (CH0) */
930 fdp1_write(fdp1, job->previous->addrs[0], FD1_RPF0_ADDR_Y);
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);
937 /* Next Field Channel (CH2) */
939 fdp1_write(fdp1, job->next->addrs[0], FD1_RPF2_ADDR_Y);
942 static void fdp1_configure_wpf(struct fdp1_ctx *ctx,
943 struct fdp1_job *job)
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;
953 pstride = q_data->format.plane_fmt[0].bytesperline
954 << FD1_WPF_PSTRIDE_Y_SHIFT;
956 if (q_data->format.num_planes > 1)
957 pstride |= q_data->format.plane_fmt[1].bytesperline
958 << FD1_WPF_PSTRIDE_C_SHIFT;
960 format = q_data->fmt->fmt; /* Output Format Code */
962 if (q_data->fmt->swap_yc)
963 format |= FD1_WPF_FORMAT_WSPYCS;
965 if (q_data->fmt->swap_uv)
966 format |= FD1_WPF_FORMAT_WSPUVS;
968 if (fdp1_fmt_is_rgb(q_data->fmt)) {
969 /* Enable Colour Space conversion */
970 format |= FD1_WPF_FORMAT_CSC;
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;
979 format |= FD1_WPF_FORMAT_WRTM_601_16;
982 /* Set an alpha value into the Pad Value */
983 format |= ctx->alpha << FD1_WPF_FORMAT_PDV_SHIFT;
985 /* Determine picture rounding and clipping */
986 rndctl = FD1_WPF_RNDCTL_CBRM; /* Rounding Off */
987 rndctl |= FD1_WPF_RNDCTL_CLMD_NOCLIP;
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;
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);
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);
1003 static void fdp1_configure_deint_mode(struct fdp1_ctx *ctx,
1004 struct fdp1_job *job)
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 */
1011 /* De-interlacing Mode */
1012 switch (ctx->deint_mode) {
1014 case FDP1_PROGRESSIVE:
1015 dprintk(fdp1, "Progressive Mode\n");
1016 opmode |= FD1_CTL_OPMODE_PRG;
1017 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1019 case FDP1_ADAPT2D3D:
1020 dprintk(fdp1, "Adapt2D3D Mode\n");
1021 if (ctx->sequence == 0 || ctx->aborting)
1022 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1024 ipcmode |= FD1_IPC_MODE_DIM_ADAPT2D3D;
1026 if (ctx->sequence > 1) {
1027 channels |= FD1_CTL_CHACT_SMW;
1028 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2;
1031 if (ctx->sequence > 2)
1032 channels |= FD1_CTL_CHACT_SMR;
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;
1043 dprintk(fdp1, "Fixed 2D Mode\n");
1044 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D;
1045 /* No extra channels enabled */
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 */
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 */
1059 fdp1_write(fdp1, channels, FD1_CTL_CHACT);
1060 fdp1_write(fdp1, opmode, FD1_CTL_OPMODE);
1061 fdp1_write(fdp1, ipcmode, FD1_IPC_MODE);
1065 * fdp1_device_process() - Run the hardware
1067 * Configure and start the hardware to generate a single frame
1068 * of output given our input parameters.
1070 static int fdp1_device_process(struct fdp1_ctx *ctx)
1073 struct fdp1_dev *fdp1 = ctx->fdp1;
1074 struct fdp1_job *job;
1075 unsigned long flags;
1077 spin_lock_irqsave(&fdp1->device_process_lock, flags);
1079 /* Get a job to process */
1080 job = get_queued_job(fdp1);
1083 * VINT can call us to see if we can queue another job.
1084 * If we have no work to do, we simply return.
1086 spin_unlock_irqrestore(&fdp1->device_process_lock, flags);
1090 /* First Frame only? ... */
1091 fdp1_write(fdp1, FD1_CTL_CLKCTRL_CSTP_N, FD1_CTL_CLKCTRL);
1093 /* Set the mode, and configuration */
1094 fdp1_configure_deint_mode(ctx, job);
1096 /* DLI Static Configuration */
1097 fdp1_set_ipc_dli(ctx);
1099 /* Sensor Configuration */
1100 fdp1_set_ipc_sensor(ctx);
1102 /* Setup the source picture */
1103 fdp1_configure_rpf(ctx, job);
1105 /* Setup the destination picture */
1106 fdp1_configure_wpf(ctx, job);
1108 /* Line Memory Pixel Number Register for linear access */
1109 fdp1_write(fdp1, FD1_IPC_LMEM_LINEAR, FD1_IPC_LMEM);
1111 /* Enable Interrupts */
1112 fdp1_write(fdp1, FD1_CTL_IRQ_MASK, FD1_CTL_IRQENB);
1114 /* Finally, the Immediate Registers */
1116 /* This job is now in the HW queue */
1117 queue_hw_job(fdp1, job);
1119 /* Start the command */
1120 fdp1_write(fdp1, FD1_CTL_CMD_STRCMD, FD1_CTL_CMD);
1122 /* Registers will update to HW at next VINT */
1123 fdp1_write(fdp1, FD1_CTL_REGEND_REGEND, FD1_CTL_REGEND);
1125 /* Enable VINT Generator */
1126 fdp1_write(fdp1, FD1_CTL_SGCMD_SGEN, FD1_CTL_SGCMD);
1128 spin_unlock_irqrestore(&fdp1->device_process_lock, flags);
1138 * job_ready() - check whether an instance is ready to be scheduled to run
1140 static int fdp1_m2m_job_ready(void *priv)
1142 struct fdp1_ctx *ctx = priv;
1143 struct fdp1_q_data *src_q_data = &ctx->out_q;
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));
1151 /* One output buffer is required for each field */
1152 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
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");
1164 static void fdp1_m2m_job_abort(void *priv)
1166 struct fdp1_ctx *ctx = priv;
1168 dprintk(ctx->fdp1, "+\n");
1170 /* Will cancel the transaction in the next interrupt handler */
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);
1179 * fdp1_prepare_job: Prepare and queue a new job for a single action of work
1181 * Prepare the next field, (or frame in progressive) and an output
1182 * buffer for the hardware to perform a single operation.
1184 static struct fdp1_job *fdp1_prepare_job(struct fdp1_ctx *ctx)
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;
1192 dprintk(fdp1, "+\n");
1194 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode))
1195 buffers_required = 2;
1197 if (ctx->buffers_queued < buffers_required)
1200 job = fdp1_job_alloc(fdp1);
1202 dprintk(fdp1, "No free jobs currently available\n");
1206 job->active = fdp1_dequeue_field(ctx);
1208 /* Buffer check should prevent this ever happening */
1209 dprintk(fdp1, "No input buffers currently available\n");
1211 fdp1_job_free(fdp1, job);
1215 dprintk(fdp1, "+ Buffer en-route...\n");
1217 /* Source buffers have been prepared on our buffer_queue
1218 * Prepare our Output buffer
1220 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1221 fbuf = to_fdp1_buffer(vbuf);
1222 job->dst = &fbuf->fields[0];
1224 job->active->vb->sequence = ctx->sequence;
1225 job->dst->vb->sequence = ctx->sequence;
1228 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) {
1229 job->previous = ctx->previous;
1231 /* Active buffer becomes the next job's previous buffer */
1232 ctx->previous = job->active;
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);
1240 /* Transfer timestamps and flags from src->dst */
1242 job->dst->vb->vb2_buf.timestamp = job->active->vb->vb2_buf.timestamp;
1244 job->dst->vb->flags = job->active->vb->flags &
1245 V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
1247 /* Ideally, the frame-end function will just 'check' to see
1248 * if there are more jobs instead
1252 /* Finally, Put this job on the processing queue */
1253 queue_job(fdp1, job);
1255 dprintk(fdp1, "Job Queued translen = %d\n", ctx->translen);
1260 /* fdp1_m2m_device_run() - prepares and starts the device for an M2M task
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.
1266 static void fdp1_m2m_device_run(void *priv)
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;
1274 dprintk(fdp1, "+\n");
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);
1282 for (i = 0; i < buf->num_fields; i++) {
1283 struct fdp1_field_buffer *fbuf = &buf->fields[i];
1285 fdp1_queue_field(ctx, fbuf);
1286 dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n",
1287 i, fbuf->last_field);
1290 /* Queue as many jobs as our data provides for */
1291 while (fdp1_prepare_job(ctx))
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);
1300 /* Kick the job processing action */
1301 fdp1_device_process(ctx);
1307 * Handles the M2M level after a buffer completion event.
1309 static void device_frame_end(struct fdp1_dev *fdp1,
1310 enum vb2_buffer_state state)
1312 struct fdp1_ctx *ctx;
1313 unsigned long flags;
1314 struct fdp1_job *job = get_hw_queued_job(fdp1);
1316 dprintk(fdp1, "+\n");
1318 ctx = v4l2_m2m_get_curr_priv(fdp1->m2m_dev);
1321 v4l2_err(&fdp1->v4l2_dev,
1322 "Instance released before the end of transaction\n");
1326 ctx->num_processed++;
1329 * fdp1_field_complete will call buf_done only when the last vb2_buffer
1330 * reference is complete
1332 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
1333 fdp1_field_complete(ctx, job->previous);
1335 fdp1_field_complete(ctx, job->active);
1337 spin_lock_irqsave(&fdp1->irqlock, flags);
1338 v4l2_m2m_buf_done(job->dst->vb, state);
1340 spin_unlock_irqrestore(&fdp1->irqlock, flags);
1342 /* Move this job back to the free job list */
1343 fdp1_job_free(fdp1, job);
1345 dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n",
1346 ctx->num_processed, ctx->translen);
1348 if (ctx->num_processed == ctx->translen ||
1350 dprintk(ctx->fdp1, "Finishing transaction\n");
1351 ctx->num_processed = 0;
1352 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx);
1355 * For pipelined performance support, this would
1356 * be called from a VINT handler
1358 fdp1_device_process(ctx);
1365 static int fdp1_vidioc_querycap(struct file *file, void *priv,
1366 struct v4l2_capability *cap)
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);
1375 static int fdp1_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
1377 unsigned int i, num;
1381 for (i = 0; i < ARRAY_SIZE(fdp1_formats); ++i) {
1382 if (fdp1_formats[i].types & type) {
1383 if (num == f->index)
1389 /* Format not found */
1390 if (i >= ARRAY_SIZE(fdp1_formats))
1394 f->pixelformat = fdp1_formats[i].fourcc;
1399 static int fdp1_enum_fmt_vid_cap(struct file *file, void *priv,
1400 struct v4l2_fmtdesc *f)
1402 return fdp1_enum_fmt(f, FDP1_CAPTURE);
1405 static int fdp1_enum_fmt_vid_out(struct file *file, void *priv,
1406 struct v4l2_fmtdesc *f)
1408 return fdp1_enum_fmt(f, FDP1_OUTPUT);
1411 static int fdp1_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1413 struct fdp1_q_data *q_data;
1414 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1416 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
1419 q_data = get_q_data(ctx, f->type);
1420 f->fmt.pix_mp = q_data->format;
1425 static void fdp1_compute_stride(struct v4l2_pix_format_mplane *pix,
1426 const struct fdp1_fmt *fmt)
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;
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));
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;
1446 memset(pix->plane_fmt[i].reserved, 0,
1447 sizeof(pix->plane_fmt[i].reserved));
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;
1455 memset(pix->plane_fmt[2].reserved, 0,
1456 sizeof(pix->plane_fmt[2].reserved));
1460 static void fdp1_try_fmt_output(struct fdp1_ctx *ctx,
1461 const struct fdp1_fmt **fmtinfo,
1462 struct v4l2_pix_format_mplane *pix)
1464 const struct fdp1_fmt *fmt;
1466 unsigned int height;
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);
1476 pix->pixelformat = fmt->fourcc;
1477 pix->num_planes = fmt->num_planes;
1480 * Progressive video and all interlaced field orders are acceptable.
1481 * Default to V4L2_FIELD_INTERLACED.
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;
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
1495 if (pix->colorspace == V4L2_COLORSPACE_DEFAULT)
1496 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
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.
1504 width = round_down(pix->width, fmt->hsub);
1505 pix->width = clamp(width, FDP1_MIN_W, FDP1_MAX_W);
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);
1511 pix->height = clamp(height, FDP1_MIN_H, FDP1_MAX_H);
1513 fdp1_compute_stride(pix, fmt);
1516 static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx,
1517 const struct fdp1_fmt **fmtinfo,
1518 struct v4l2_pix_format_mplane *pix)
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;
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
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
1536 colorspace = src_data->format.colorspace;
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);
1542 quantization = src_data->format.quantization;
1543 if (quantization == V4L2_QUANTIZATION_DEFAULT)
1544 quantization = V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace,
1547 allow_rgb = ycbcr_enc == V4L2_YCBCR_ENC_601 ||
1548 (ycbcr_enc == V4L2_YCBCR_ENC_709 &&
1549 quantization == V4L2_QUANTIZATION_LIM_RANGE);
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);
1558 pix->pixelformat = fmt->fourcc;
1559 pix->num_planes = fmt->num_planes;
1560 pix->field = V4L2_FIELD_NONE;
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.
1568 pix->colorspace = src_data->format.colorspace;
1569 pix->xfer_func = src_data->format.xfer_func;
1571 if (fdp1_fmt_is_rgb(fmt)) {
1572 pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1573 pix->quantization = V4L2_QUANTIZATION_DEFAULT;
1575 pix->ycbcr_enc = src_data->format.ycbcr_enc;
1576 pix->quantization = src_data->format.quantization;
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.
1584 pix->width = src_data->format.width;
1585 if (src_data->format.field == V4L2_FIELD_ALTERNATE)
1586 pix->height = 2 * src_data->format.height;
1588 pix->height = src_data->format.height;
1590 fdp1_compute_stride(pix, fmt);
1593 static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1595 struct fdp1_ctx *ctx = fh_to_ctx(priv);
1597 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1598 fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp);
1600 fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp);
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);
1610 static void fdp1_set_format(struct fdp1_ctx *ctx,
1611 struct v4l2_pix_format_mplane *pix,
1612 enum v4l2_buf_type type)
1614 struct fdp1_q_data *q_data = get_q_data(ctx, type);
1615 const struct fdp1_fmt *fmtinfo;
1617 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1618 fdp1_try_fmt_output(ctx, &fmtinfo, pix);
1620 fdp1_try_fmt_capture(ctx, &fmtinfo, pix);
1622 q_data->fmt = fmtinfo;
1623 q_data->format = *pix;
1625 q_data->vsize = pix->height;
1626 if (pix->field != V4L2_FIELD_NONE)
1629 q_data->stride_y = pix->plane_fmt[0].bytesperline;
1630 q_data->stride_c = pix->plane_fmt[1].bytesperline;
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;
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;
1645 * Copy the format, clear the per-plane bytes per line and image
1646 * size, override the field and double the height if needed.
1648 dst_data->format = q_data->format;
1649 memset(dst_data->format.plane_fmt, 0,
1650 sizeof(dst_data->format.plane_fmt));
1652 dst_data->format.field = V4L2_FIELD_NONE;
1653 if (pix->field == V4L2_FIELD_ALTERNATE)
1654 dst_data->format.height *= 2;
1656 fdp1_try_fmt_capture(ctx, &dst_data->fmt, &dst_data->format);
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;
1664 static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
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);
1670 if (vb2_is_busy(vq)) {
1671 v4l2_err(&ctx->fdp1->v4l2_dev, "%s queue busy\n", __func__);
1675 fdp1_set_format(ctx, &f->fmt.pix_mp, f->type);
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);
1685 static int fdp1_g_ctrl(struct v4l2_ctrl *ctrl)
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;
1692 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1693 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
1703 static int fdp1_s_ctrl(struct v4l2_ctrl *ctrl)
1705 struct fdp1_ctx *ctx =
1706 container_of(ctrl->handler, struct fdp1_ctx, hdl);
1709 case V4L2_CID_ALPHA_COMPONENT:
1710 ctx->alpha = ctrl->val;
1713 case V4L2_CID_DEINTERLACING_MODE:
1714 ctx->deint_mode = ctrl->val;
1721 static const struct v4l2_ctrl_ops fdp1_ctrl_ops = {
1722 .s_ctrl = fdp1_s_ctrl,
1723 .g_volatile_ctrl = fdp1_g_ctrl,
1726 static const char * const fdp1_ctrl_deint_menu[] = {
1736 static const struct v4l2_ioctl_ops fdp1_ioctl_ops = {
1737 .vidioc_querycap = fdp1_vidioc_querycap,
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,
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,
1756 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1757 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1759 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1760 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
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[])
1772 struct fdp1_ctx *ctx = vb2_get_drv_priv(vq);
1773 struct fdp1_q_data *q_data;
1776 q_data = get_q_data(ctx, vq->type);
1779 if (*nplanes > FDP1_MAX_PLANES)
1785 *nplanes = q_data->format.num_planes;
1787 for (i = 0; i < *nplanes; i++)
1788 sizes[i] = q_data->format.plane_fmt[i].sizeimage;
1793 static void fdp1_buf_prepare_field(struct fdp1_q_data *q_data,
1794 struct vb2_v4l2_buffer *vbuf,
1795 unsigned int field_num)
1797 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1798 struct fdp1_field_buffer *fbuf = &buf->fields[field_num];
1799 unsigned int num_fields;
1802 num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1805 fbuf->last_field = (field_num + 1) == num_fields;
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);
1810 switch (vbuf->field) {
1811 case V4L2_FIELD_INTERLACED:
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.
1817 fbuf->field = (q_data->format.height < 576) == field_num
1818 ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1820 case V4L2_FIELD_INTERLACED_TB:
1821 case V4L2_FIELD_SEQ_TB:
1822 fbuf->field = field_num ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
1824 case V4L2_FIELD_INTERLACED_BT:
1825 case V4L2_FIELD_SEQ_BT:
1826 fbuf->field = field_num ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1829 fbuf->field = vbuf->field;
1833 /* Buffer is completed */
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++)
1844 (i == 0 ? q_data->stride_y : q_data->stride_c);
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);
1855 static int fdp1_buf_prepare(struct vb2_buffer *vb)
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);
1863 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1864 bool field_valid = true;
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;
1873 case V4L2_FIELD_ALTERNATE:
1874 if (vbuf->field != V4L2_FIELD_TOP &&
1875 vbuf->field != V4L2_FIELD_BOTTOM)
1876 field_valid = false;
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;
1891 "buffer field %u invalid for format field %u\n",
1892 vbuf->field, q_data->format.field);
1896 vbuf->field = V4L2_FIELD_NONE;
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;
1903 if (vb2_plane_size(vb, i) < size) {
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);
1911 /* We have known size formats all around */
1912 vb2_set_plane_payload(vb, i, size);
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);
1922 static void fdp1_buf_queue(struct vb2_buffer *vb)
1924 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1925 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1927 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1930 static int fdp1_start_streaming(struct vb2_queue *q, unsigned int count)
1932 struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1933 struct fdp1_q_data *q_data = get_q_data(ctx, q->type);
1935 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
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.
1941 if (q_data->format.field == V4L2_FIELD_NONE)
1942 ctx->deint_mode = FDP1_PROGRESSIVE;
1944 if (ctx->deint_mode == FDP1_ADAPT2D3D) {
1946 dma_addr_t smsk_base;
1947 const u32 bpp = 2; /* bytes per pixel */
1949 stride = round_up(q_data->format.width, 8);
1951 ctx->smsk_size = bpp * stride * q_data->vsize;
1953 ctx->smsk_cpu = dma_alloc_coherent(ctx->fdp1->dev,
1954 ctx->smsk_size, &smsk_base, GFP_KERNEL);
1956 if (ctx->smsk_cpu == NULL) {
1957 dprintk(ctx->fdp1, "Failed to alloc smsk\n");
1961 ctx->smsk_addr[0] = smsk_base;
1962 ctx->smsk_addr[1] = smsk_base + (ctx->smsk_size/2);
1969 static void fdp1_stop_streaming(struct vb2_queue *q)
1971 struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1972 struct vb2_v4l2_buffer *vbuf;
1973 unsigned long flags;
1976 if (V4L2_TYPE_IS_OUTPUT(q->type))
1977 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1979 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
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);
1987 /* Empty Output queues */
1988 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1989 /* Empty our internal queues */
1990 struct fdp1_field_buffer *fbuf;
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);
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;
2007 WARN(!list_empty(&ctx->fields_queue),
2008 "Buffer queue not empty");
2010 /* Empty Capture queues (Jobs) */
2011 struct fdp1_job *job;
2013 job = get_queued_job(ctx->fdp1);
2015 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
2016 fdp1_field_complete(ctx, job->previous);
2018 fdp1_field_complete(ctx, job->active);
2020 v4l2_m2m_buf_done(job->dst->vb, VB2_BUF_STATE_ERROR);
2023 job = get_queued_job(ctx->fdp1);
2026 /* Free any held buffer in the ctx */
2027 fdp1_field_complete(ctx, ctx->previous);
2029 WARN(!list_empty(&ctx->fdp1->queued_job_list),
2030 "Queued Job List not empty");
2032 WARN(!list_empty(&ctx->fdp1->hw_job_list),
2033 "HW Job list not empty");
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,
2047 static int queue_init(void *priv, struct vb2_queue *src_vq,
2048 struct vb2_queue *dst_vq)
2050 struct fdp1_ctx *ctx = priv;
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;
2063 ret = vb2_queue_init(src_vq);
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;
2077 return vb2_queue_init(dst_vq);
2083 static int fdp1_open(struct file *file)
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;
2091 if (mutex_lock_interruptible(&fdp1->dev_mutex))
2092 return -ERESTARTSYS;
2094 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2100 v4l2_fh_init(&ctx->fh, video_devdata(file));
2101 file->private_data = &ctx->fh;
2104 /* Initialise Queues */
2105 INIT_LIST_HEAD(&ctx->fields_queue);
2110 /* Initialise controls */
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);
2118 ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2119 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1);
2121 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
2123 v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2124 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
2126 if (ctx->hdl.error) {
2127 ret = ctx->hdl.error;
2128 v4l2_ctrl_handler_free(&ctx->hdl);
2132 ctx->fh.ctrl_handler = &ctx->hdl;
2133 v4l2_ctrl_handler_setup(&ctx->hdl);
2135 /* Configure default parameters. */
2136 memset(&format, 0, sizeof(format));
2137 fdp1_set_format(ctx, &format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
2139 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fdp1->m2m_dev, ctx, &queue_init);
2141 if (IS_ERR(ctx->fh.m2m_ctx)) {
2142 ret = PTR_ERR(ctx->fh.m2m_ctx);
2144 v4l2_ctrl_handler_free(&ctx->hdl);
2149 /* Perform any power management required */
2150 pm_runtime_get_sync(fdp1->dev);
2152 v4l2_fh_add(&ctx->fh);
2154 dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n",
2155 ctx, ctx->fh.m2m_ctx);
2158 mutex_unlock(&fdp1->dev_mutex);
2162 static int fdp1_release(struct file *file)
2164 struct fdp1_dev *fdp1 = video_drvdata(file);
2165 struct fdp1_ctx *ctx = fh_to_ctx(file->private_data);
2167 dprintk(fdp1, "Releasing instance %p\n", ctx);
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);
2177 pm_runtime_put(fdp1->dev);
2182 static const struct v4l2_file_operations fdp1_fops = {
2183 .owner = THIS_MODULE,
2185 .release = fdp1_release,
2186 .poll = v4l2_m2m_fop_poll,
2187 .unlocked_ioctl = video_ioctl2,
2188 .mmap = v4l2_m2m_fop_mmap,
2191 static const struct video_device fdp1_videodev = {
2192 .name = DRIVER_NAME,
2193 .vfl_dir = VFL_DIR_M2M,
2195 .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
2196 .ioctl_ops = &fdp1_ioctl_ops,
2198 .release = video_device_release_empty,
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,
2207 static irqreturn_t fdp1_irq_handler(int irq, void *dev_id)
2209 struct fdp1_dev *fdp1 = dev_id;
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;
2221 /* Clear interrupts */
2222 fdp1_write(fdp1, ~(int_status) & FD1_CTL_IRQ_MASK, FD1_CTL_IRQSTA);
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]");
2230 dprintk(fdp1, "CycleStatus = %d (%dms)\n",
2231 cycles, cycles/(fdp1->clk_rate/1000));
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");
2243 /* Spurious interrupt */
2244 if (!(FD1_CTL_IRQ_MASK & int_status))
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);
2256 static int fdp1_probe(struct platform_device *pdev)
2258 struct fdp1_dev *fdp1;
2259 struct video_device *vfd;
2260 struct device_node *fcp_node;
2261 struct resource *res;
2268 fdp1 = devm_kzalloc(&pdev->dev, sizeof(*fdp1), GFP_KERNEL);
2272 INIT_LIST_HEAD(&fdp1->free_job_list);
2273 INIT_LIST_HEAD(&fdp1->queued_job_list);
2274 INIT_LIST_HEAD(&fdp1->hw_job_list);
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);
2280 mutex_init(&fdp1->dev_mutex);
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);
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);
2293 /* Interrupt service routine registration */
2294 fdp1->irq = ret = platform_get_irq(pdev, 0);
2296 dev_err(&pdev->dev, "cannot find IRQ\n");
2300 ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0,
2301 dev_name(&pdev->dev), fdp1);
2303 dev_err(&pdev->dev, "cannot claim IRQ %d\n", fdp1->irq);
2308 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
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);
2319 /* Determine our clock rate */
2320 clk = clk_get(&pdev->dev, NULL);
2322 return PTR_ERR(clk);
2324 fdp1->clk_rate = clk_get_rate(clk);
2327 /* V4L2 device registration */
2328 ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev);
2330 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
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);
2342 /* Video registration */
2343 fdp1->vfd = fdp1_videodev;
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));
2350 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
2352 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2356 v4l2_info(&fdp1->v4l2_dev,
2357 "Device registered as /dev/video%d\n", vfd->num);
2359 /* Power up the cells to read HW */
2360 pm_runtime_enable(&pdev->dev);
2361 pm_runtime_get_sync(fdp1->dev);
2363 hw_version = fdp1_read(fdp1, FD1_IP_INTDATA);
2364 switch (hw_version) {
2366 dprintk(fdp1, "FDP1 Version R-Car H3 ES1\n");
2369 dprintk(fdp1, "FDP1 Version R-Car M3-W\n");
2372 dprintk(fdp1, "FDP1 Version R-Car H3\n");
2375 dprintk(fdp1, "FDP1 Version R-Car M3-N\n");
2378 dprintk(fdp1, "FDP1 Version R-Car E3\n");
2381 dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n",
2385 /* Allow the hw to sleep until an open call puts it to use */
2386 pm_runtime_put(fdp1->dev);
2391 v4l2_m2m_release(fdp1->m2m_dev);
2394 v4l2_device_unregister(&fdp1->v4l2_dev);
2399 static int fdp1_remove(struct platform_device *pdev)
2401 struct fdp1_dev *fdp1 = platform_get_drvdata(pdev);
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);
2411 static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev)
2413 struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2415 rcar_fcp_disable(fdp1->fcp);
2420 static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev)
2422 struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2424 /* Program in the static LUTs */
2427 return rcar_fcp_enable(fdp1->fcp);
2430 static const struct dev_pm_ops fdp1_pm_ops = {
2431 SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend,
2432 fdp1_pm_runtime_resume,
2436 static const struct of_device_id fdp1_dt_ids[] = {
2437 { .compatible = "renesas,fdp1" },
2440 MODULE_DEVICE_TABLE(of, fdp1_dt_ids);
2442 static struct platform_driver fdp1_pdrv = {
2443 .probe = fdp1_probe,
2444 .remove = fdp1_remove,
2446 .name = DRIVER_NAME,
2447 .of_match_table = fdp1_dt_ids,
2452 module_platform_driver(fdp1_pdrv);
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);