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
266 #define FD1_LUT_DIF_ADJ 0x1000
267 #define FD1_LUT_SAD_ADJ 0x1400
268 #define FD1_LUT_BLD_GAIN 0x1800
269 #define FD1_LUT_DIF_GAIN 0x1c00
270 #define FD1_LUT_MDET 0x2000
273 * struct fdp1_fmt - The FDP1 internal format data
274 * @fourcc: the fourcc code, to match the V4L2 API
275 * @bpp: bits per pixel per plane
276 * @num_planes: number of planes
277 * @hsub: horizontal subsampling factor
278 * @vsub: vertical subsampling factor
279 * @fmt: 7-bit format code for the fdp1 hardware
280 * @swap_yc: the Y and C components are swapped (Y comes before C)
281 * @swap_uv: the U and V components are swapped (V comes before U)
282 * @swap: swap register control
283 * @types: types of queue this format is applicable to
298 static const struct fdp1_fmt fdp1_formats
[] = {
299 /* RGB formats are only supported by the Write Pixel Formatter */
301 { V4L2_PIX_FMT_RGB332
, { 8, 0, 0 }, 1, 1, 1, 0x00, false, false,
302 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
303 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
305 { V4L2_PIX_FMT_XRGB444
, { 16, 0, 0 }, 1, 1, 1, 0x01, false, false,
306 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
309 { V4L2_PIX_FMT_XRGB555
, { 16, 0, 0 }, 1, 1, 1, 0x04, false, false,
310 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
313 { V4L2_PIX_FMT_RGB565
, { 16, 0, 0 }, 1, 1, 1, 0x06, false, false,
314 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
317 { V4L2_PIX_FMT_ABGR32
, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
318 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
,
320 { V4L2_PIX_FMT_XBGR32
, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
321 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
,
323 { V4L2_PIX_FMT_ARGB32
, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
324 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
325 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
327 { V4L2_PIX_FMT_XRGB32
, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false,
328 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
329 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
331 { V4L2_PIX_FMT_RGB24
, { 24, 0, 0 }, 1, 1, 1, 0x15, false, false,
332 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
333 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
335 { V4L2_PIX_FMT_BGR24
, { 24, 0, 0 }, 1, 1, 1, 0x18, false, false,
336 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
337 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
339 { V4L2_PIX_FMT_ARGB444
, { 16, 0, 0 }, 1, 1, 1, 0x19, false, false,
340 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
343 { V4L2_PIX_FMT_ARGB555
, { 16, 0, 0 }, 1, 1, 1, 0x1b, false, false,
344 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
348 /* YUV Formats are supported by Read and Write Pixel Formatters */
350 { V4L2_PIX_FMT_NV16M
, { 8, 16, 0 }, 2, 2, 1, 0x41, false, false,
351 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
352 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
353 FDP1_CAPTURE
| FDP1_OUTPUT
},
354 { V4L2_PIX_FMT_NV61M
, { 8, 16, 0 }, 2, 2, 1, 0x41, false, true,
355 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
356 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
357 FDP1_CAPTURE
| FDP1_OUTPUT
},
358 { V4L2_PIX_FMT_NV12M
, { 8, 16, 0 }, 2, 2, 2, 0x42, false, false,
359 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
360 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
361 FDP1_CAPTURE
| FDP1_OUTPUT
},
362 { V4L2_PIX_FMT_NV21M
, { 8, 16, 0 }, 2, 2, 2, 0x42, false, true,
363 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
364 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
365 FDP1_CAPTURE
| FDP1_OUTPUT
},
366 { V4L2_PIX_FMT_UYVY
, { 16, 0, 0 }, 1, 2, 1, 0x47, false, false,
367 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
368 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
369 FDP1_CAPTURE
| FDP1_OUTPUT
},
370 { V4L2_PIX_FMT_VYUY
, { 16, 0, 0 }, 1, 2, 1, 0x47, false, true,
371 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
372 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
373 FDP1_CAPTURE
| FDP1_OUTPUT
},
374 { V4L2_PIX_FMT_YUYV
, { 16, 0, 0 }, 1, 2, 1, 0x47, true, false,
375 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
376 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
377 FDP1_CAPTURE
| FDP1_OUTPUT
},
378 { V4L2_PIX_FMT_YVYU
, { 16, 0, 0 }, 1, 2, 1, 0x47, true, true,
379 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
380 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
381 FDP1_CAPTURE
| FDP1_OUTPUT
},
382 { V4L2_PIX_FMT_YUV444M
, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, false,
383 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
384 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
385 FDP1_CAPTURE
| FDP1_OUTPUT
},
386 { V4L2_PIX_FMT_YVU444M
, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, true,
387 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
388 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
389 FDP1_CAPTURE
| FDP1_OUTPUT
},
390 { V4L2_PIX_FMT_YUV422M
, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, false,
391 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
392 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
393 FDP1_CAPTURE
| FDP1_OUTPUT
},
394 { V4L2_PIX_FMT_YVU422M
, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, true,
395 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
396 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
397 FDP1_CAPTURE
| FDP1_OUTPUT
},
398 { V4L2_PIX_FMT_YUV420M
, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, false,
399 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
400 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
401 FDP1_CAPTURE
| FDP1_OUTPUT
},
402 { V4L2_PIX_FMT_YVU420M
, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, true,
403 FD1_RWPF_SWAP_LLWD
| FD1_RWPF_SWAP_LWRD
|
404 FD1_RWPF_SWAP_WORD
| FD1_RWPF_SWAP_BYTE
,
405 FDP1_CAPTURE
| FDP1_OUTPUT
},
408 static int fdp1_fmt_is_rgb(const struct fdp1_fmt
*fmt
)
410 return fmt
->fmt
<= 0x1b; /* Last RGB code */
414 * FDP1 Lookup tables range from 0...255 only
416 * Each table must be less than 256 entries, and all tables
417 * are padded out to 256 entries by duplicating the last value.
419 static const u8 fdp1_diff_adj
[] = {
420 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf,
421 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3,
422 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff,
425 static const u8 fdp1_sad_adj
[] = {
426 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf,
427 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3,
428 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff,
431 static const u8 fdp1_bld_gain
[] = {
435 static const u8 fdp1_dif_gain
[] = {
439 static const u8 fdp1_mdet
[] = {
440 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
441 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
442 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
443 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
444 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
445 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
446 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
447 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
448 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
449 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
450 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
451 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
452 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
453 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
454 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
455 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
456 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
457 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
458 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
459 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
460 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
461 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
462 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
463 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
464 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
465 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
466 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
467 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
468 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
469 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
470 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
471 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
474 /* Per-queue, driver-specific private data */
476 const struct fdp1_fmt
*fmt
;
477 struct v4l2_pix_format_mplane format
;
480 unsigned int stride_y
;
481 unsigned int stride_c
;
484 static const struct fdp1_fmt
*fdp1_find_format(u32 pixelformat
)
486 const struct fdp1_fmt
*fmt
;
489 for (i
= 0; i
< ARRAY_SIZE(fdp1_formats
); i
++) {
490 fmt
= &fdp1_formats
[i
];
491 if (fmt
->fourcc
== pixelformat
)
498 enum fdp1_deint_mode
{
499 FDP1_PROGRESSIVE
= 0, /* Must be zero when !deinterlacing */
507 #define FDP1_DEINT_MODE_USES_NEXT(mode) \
508 (mode == FDP1_ADAPT2D3D || \
509 mode == FDP1_FIXED3D || \
510 mode == FDP1_NEXTFIELD)
512 #define FDP1_DEINT_MODE_USES_PREV(mode) \
513 (mode == FDP1_ADAPT2D3D || \
514 mode == FDP1_FIXED3D || \
515 mode == FDP1_PREVFIELD)
518 * FDP1 operates on potentially 3 fields, which are tracked
519 * from the VB buffers using this context structure.
520 * Will always be a field or a full frame, never two fields.
522 struct fdp1_field_buffer
{
523 struct vb2_v4l2_buffer
*vb
;
526 /* Should be NONE:TOP:BOTTOM only */
527 enum v4l2_field field
;
529 /* Flag to indicate this is the last field in the vb */
532 /* Buffer queue lists */
533 struct list_head list
;
537 struct v4l2_m2m_buffer m2m_buf
;
538 struct fdp1_field_buffer fields
[2];
539 unsigned int num_fields
;
542 static inline struct fdp1_buffer
*to_fdp1_buffer(struct vb2_v4l2_buffer
*vb
)
544 return container_of(vb
, struct fdp1_buffer
, m2m_buf
.vb
);
548 struct fdp1_field_buffer
*previous
;
549 struct fdp1_field_buffer
*active
;
550 struct fdp1_field_buffer
*next
;
551 struct fdp1_field_buffer
*dst
;
553 /* A job can only be on one list at a time */
554 struct list_head list
;
558 struct v4l2_device v4l2_dev
;
559 struct video_device vfd
;
561 struct mutex dev_mutex
;
563 spinlock_t device_process_lock
;
570 struct fdp1_job jobs
[FDP1_NUMBER_JOBS
];
571 struct list_head free_job_list
;
572 struct list_head queued_job_list
;
573 struct list_head hw_job_list
;
575 unsigned int clk_rate
;
577 struct rcar_fcp_device
*fcp
;
578 struct v4l2_m2m_dev
*m2m_dev
;
583 struct fdp1_dev
*fdp1
;
585 struct v4l2_ctrl_handler hdl
;
586 unsigned int sequence
;
588 /* Processed buffers in this transaction */
591 /* Transaction length (i.e. how many buffers per transaction) */
594 /* Abort requested by m2m */
597 /* Deinterlace processing mode */
598 enum fdp1_deint_mode deint_mode
;
601 * Adaptive 2D/3D mode uses a shared mask
602 * This is allocated at streamon, if the ADAPT2D3D mode
605 unsigned int smsk_size
;
606 dma_addr_t smsk_addr
[2];
609 /* Capture pipeline, can specify an alpha value
610 * for supported formats. 0-255 only
614 /* Source and destination queue data */
615 struct fdp1_q_data out_q
; /* HW Source */
616 struct fdp1_q_data cap_q
; /* HW Destination */
620 * Interlaced fields are used on 3 occasions, and tracked in this list.
622 * V4L2 Buffers are tracked inside the fdp1_buffer
623 * and released when the last 'field' completes
625 struct list_head fields_queue
;
626 unsigned int buffers_queued
;
629 * For de-interlacing we need to track our previous buffer
630 * while preparing our job lists.
632 struct fdp1_field_buffer
*previous
;
635 static inline struct fdp1_ctx
*fh_to_ctx(struct v4l2_fh
*fh
)
637 return container_of(fh
, struct fdp1_ctx
, fh
);
640 static struct fdp1_q_data
*get_q_data(struct fdp1_ctx
*ctx
,
641 enum v4l2_buf_type type
)
643 if (V4L2_TYPE_IS_OUTPUT(type
))
650 * list_remove_job: Take the first item off the specified job list
652 * Returns: pointer to a job, or NULL if the list is empty.
654 static struct fdp1_job
*list_remove_job(struct fdp1_dev
*fdp1
,
655 struct list_head
*list
)
657 struct fdp1_job
*job
;
660 spin_lock_irqsave(&fdp1
->irqlock
, flags
);
661 job
= list_first_entry_or_null(list
, struct fdp1_job
, list
);
663 list_del(&job
->list
);
664 spin_unlock_irqrestore(&fdp1
->irqlock
, flags
);
670 * list_add_job: Add a job to the specified job list
672 * Returns: void - always succeeds
674 static void list_add_job(struct fdp1_dev
*fdp1
,
675 struct list_head
*list
,
676 struct fdp1_job
*job
)
680 spin_lock_irqsave(&fdp1
->irqlock
, flags
);
681 list_add_tail(&job
->list
, list
);
682 spin_unlock_irqrestore(&fdp1
->irqlock
, flags
);
685 static struct fdp1_job
*fdp1_job_alloc(struct fdp1_dev
*fdp1
)
687 return list_remove_job(fdp1
, &fdp1
->free_job_list
);
690 static void fdp1_job_free(struct fdp1_dev
*fdp1
, struct fdp1_job
*job
)
692 /* Ensure that all residue from previous jobs is gone */
693 memset(job
, 0, sizeof(struct fdp1_job
));
695 list_add_job(fdp1
, &fdp1
->free_job_list
, job
);
698 static void queue_job(struct fdp1_dev
*fdp1
, struct fdp1_job
*job
)
700 list_add_job(fdp1
, &fdp1
->queued_job_list
, job
);
703 static struct fdp1_job
*get_queued_job(struct fdp1_dev
*fdp1
)
705 return list_remove_job(fdp1
, &fdp1
->queued_job_list
);
708 static void queue_hw_job(struct fdp1_dev
*fdp1
, struct fdp1_job
*job
)
710 list_add_job(fdp1
, &fdp1
->hw_job_list
, job
);
713 static struct fdp1_job
*get_hw_queued_job(struct fdp1_dev
*fdp1
)
715 return list_remove_job(fdp1
, &fdp1
->hw_job_list
);
719 * Buffer lists handling
721 static void fdp1_field_complete(struct fdp1_ctx
*ctx
,
722 struct fdp1_field_buffer
*fbuf
)
724 /* job->previous may be on the first field */
728 if (fbuf
->last_field
)
729 v4l2_m2m_buf_done(fbuf
->vb
, VB2_BUF_STATE_DONE
);
732 static void fdp1_queue_field(struct fdp1_ctx
*ctx
,
733 struct fdp1_field_buffer
*fbuf
)
737 spin_lock_irqsave(&ctx
->fdp1
->irqlock
, flags
);
738 list_add_tail(&fbuf
->list
, &ctx
->fields_queue
);
739 spin_unlock_irqrestore(&ctx
->fdp1
->irqlock
, flags
);
741 ctx
->buffers_queued
++;
744 static struct fdp1_field_buffer
*fdp1_dequeue_field(struct fdp1_ctx
*ctx
)
746 struct fdp1_field_buffer
*fbuf
;
749 ctx
->buffers_queued
--;
751 spin_lock_irqsave(&ctx
->fdp1
->irqlock
, flags
);
752 fbuf
= list_first_entry_or_null(&ctx
->fields_queue
,
753 struct fdp1_field_buffer
, list
);
755 list_del(&fbuf
->list
);
756 spin_unlock_irqrestore(&ctx
->fdp1
->irqlock
, flags
);
762 * Return the next field in the queue - or NULL,
763 * without removing the item from the list
765 static struct fdp1_field_buffer
*fdp1_peek_queued_field(struct fdp1_ctx
*ctx
)
767 struct fdp1_field_buffer
*fbuf
;
770 spin_lock_irqsave(&ctx
->fdp1
->irqlock
, flags
);
771 fbuf
= list_first_entry_or_null(&ctx
->fields_queue
,
772 struct fdp1_field_buffer
, list
);
773 spin_unlock_irqrestore(&ctx
->fdp1
->irqlock
, flags
);
778 static u32
fdp1_read(struct fdp1_dev
*fdp1
, unsigned int reg
)
780 u32 value
= ioread32(fdp1
->regs
+ reg
);
783 dprintk(fdp1
, "Read 0x%08x from 0x%04x\n", value
, reg
);
788 static void fdp1_write(struct fdp1_dev
*fdp1
, u32 val
, unsigned int reg
)
791 dprintk(fdp1
, "Write 0x%08x to 0x%04x\n", val
, reg
);
793 iowrite32(val
, fdp1
->regs
+ reg
);
796 /* IPC registers are to be programmed with constant values */
797 static void fdp1_set_ipc_dli(struct fdp1_ctx
*ctx
)
799 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
801 fdp1_write(fdp1
, FD1_IPC_SMSK_THRESH_CONST
, FD1_IPC_SMSK_THRESH
);
802 fdp1_write(fdp1
, FD1_IPC_COMB_DET_CONST
, FD1_IPC_COMB_DET
);
803 fdp1_write(fdp1
, FD1_IPC_MOTDEC_CONST
, FD1_IPC_MOTDEC
);
805 fdp1_write(fdp1
, FD1_IPC_DLI_BLEND_CONST
, FD1_IPC_DLI_BLEND
);
806 fdp1_write(fdp1
, FD1_IPC_DLI_HGAIN_CONST
, FD1_IPC_DLI_HGAIN
);
807 fdp1_write(fdp1
, FD1_IPC_DLI_SPRS_CONST
, FD1_IPC_DLI_SPRS
);
808 fdp1_write(fdp1
, FD1_IPC_DLI_ANGLE_CONST
, FD1_IPC_DLI_ANGLE
);
809 fdp1_write(fdp1
, FD1_IPC_DLI_ISOPIX0_CONST
, FD1_IPC_DLI_ISOPIX0
);
810 fdp1_write(fdp1
, FD1_IPC_DLI_ISOPIX1_CONST
, FD1_IPC_DLI_ISOPIX1
);
814 static void fdp1_set_ipc_sensor(struct fdp1_ctx
*ctx
)
816 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
817 struct fdp1_q_data
*src_q_data
= &ctx
->out_q
;
819 unsigned int hsize
= src_q_data
->format
.width
;
820 unsigned int vsize
= src_q_data
->format
.height
;
825 fdp1_write(fdp1
, FD1_IPC_SENSOR_TH0_CONST
, FD1_IPC_SENSOR_TH0
);
826 fdp1_write(fdp1
, FD1_IPC_SENSOR_TH1_CONST
, FD1_IPC_SENSOR_TH1
);
827 fdp1_write(fdp1
, FD1_IPC_SENSOR_CTL0_CONST
, FD1_IPC_SENSOR_CTL0
);
828 fdp1_write(fdp1
, FD1_IPC_SENSOR_CTL1_CONST
, FD1_IPC_SENSOR_CTL1
);
830 fdp1_write(fdp1
, ((hsize
- 1) << FD1_IPC_SENSOR_CTL2_X_SHIFT
) |
831 ((vsize
- 1) << FD1_IPC_SENSOR_CTL2_Y_SHIFT
),
832 FD1_IPC_SENSOR_CTL2
);
834 fdp1_write(fdp1
, (x0
<< FD1_IPC_SENSOR_CTL3_0_SHIFT
) |
835 (x1
<< FD1_IPC_SENSOR_CTL3_1_SHIFT
),
836 FD1_IPC_SENSOR_CTL3
);
840 * fdp1_write_lut: Write a padded LUT to the hw
842 * FDP1 uses constant data for de-interlacing processing,
843 * with large tables. These hardware tables are all 256 bytes
844 * long, however they often contain repeated data at the end.
846 * The last byte of the table is written to all remaining entries.
848 static void fdp1_write_lut(struct fdp1_dev
*fdp1
, const u8
*lut
,
849 unsigned int len
, unsigned int base
)
854 /* Tables larger than the hw are clipped */
855 len
= min(len
, 256u);
857 for (i
= 0; i
< len
; i
++)
858 fdp1_write(fdp1
, lut
[i
], base
+ (i
*4));
860 /* Tables are padded with the last entry */
864 fdp1_write(fdp1
, pad
, base
+ (i
*4));
867 static void fdp1_set_lut(struct fdp1_dev
*fdp1
)
869 fdp1_write_lut(fdp1
, fdp1_diff_adj
, ARRAY_SIZE(fdp1_diff_adj
),
871 fdp1_write_lut(fdp1
, fdp1_sad_adj
, ARRAY_SIZE(fdp1_sad_adj
),
873 fdp1_write_lut(fdp1
, fdp1_bld_gain
, ARRAY_SIZE(fdp1_bld_gain
),
875 fdp1_write_lut(fdp1
, fdp1_dif_gain
, ARRAY_SIZE(fdp1_dif_gain
),
877 fdp1_write_lut(fdp1
, fdp1_mdet
, ARRAY_SIZE(fdp1_mdet
),
881 static void fdp1_configure_rpf(struct fdp1_ctx
*ctx
,
882 struct fdp1_job
*job
)
884 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
890 struct fdp1_q_data
*q_data
= &ctx
->out_q
;
892 /* Picture size is common to Source and Destination frames */
893 picture_size
= (q_data
->format
.width
<< FD1_RPF_SIZE_H_SHIFT
)
894 | (q_data
->vsize
<< FD1_RPF_SIZE_V_SHIFT
);
897 pstride
= q_data
->stride_y
<< FD1_RPF_PSTRIDE_Y_SHIFT
;
898 if (q_data
->format
.num_planes
> 1)
899 pstride
|= q_data
->stride_c
<< FD1_RPF_PSTRIDE_C_SHIFT
;
902 format
= q_data
->fmt
->fmt
;
903 if (q_data
->fmt
->swap_yc
)
904 format
|= FD1_RPF_FORMAT_RSPYCS
;
906 if (q_data
->fmt
->swap_uv
)
907 format
|= FD1_RPF_FORMAT_RSPUVS
;
909 if (job
->active
->field
== V4L2_FIELD_BOTTOM
) {
910 format
|= FD1_RPF_FORMAT_CF
; /* Set for Bottom field */
911 smsk_addr
= ctx
->smsk_addr
[0];
913 smsk_addr
= ctx
->smsk_addr
[1];
916 /* Deint mode is non-zero when deinterlacing */
918 format
|= FD1_RPF_FORMAT_CIPM
;
920 fdp1_write(fdp1
, format
, FD1_RPF_FORMAT
);
921 fdp1_write(fdp1
, q_data
->fmt
->swap
, FD1_RPF_SWAP
);
922 fdp1_write(fdp1
, picture_size
, FD1_RPF_SIZE
);
923 fdp1_write(fdp1
, pstride
, FD1_RPF_PSTRIDE
);
924 fdp1_write(fdp1
, smsk_addr
, FD1_RPF_SMSK_ADDR
);
926 /* Previous Field Channel (CH0) */
928 fdp1_write(fdp1
, job
->previous
->addrs
[0], FD1_RPF0_ADDR_Y
);
930 /* Current Field Channel (CH1) */
931 fdp1_write(fdp1
, job
->active
->addrs
[0], FD1_RPF1_ADDR_Y
);
932 fdp1_write(fdp1
, job
->active
->addrs
[1], FD1_RPF1_ADDR_C0
);
933 fdp1_write(fdp1
, job
->active
->addrs
[2], FD1_RPF1_ADDR_C1
);
935 /* Next Field Channel (CH2) */
937 fdp1_write(fdp1
, job
->next
->addrs
[0], FD1_RPF2_ADDR_Y
);
940 static void fdp1_configure_wpf(struct fdp1_ctx
*ctx
,
941 struct fdp1_job
*job
)
943 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
944 struct fdp1_q_data
*src_q_data
= &ctx
->out_q
;
945 struct fdp1_q_data
*q_data
= &ctx
->cap_q
;
951 pstride
= q_data
->format
.plane_fmt
[0].bytesperline
952 << FD1_WPF_PSTRIDE_Y_SHIFT
;
954 if (q_data
->format
.num_planes
> 1)
955 pstride
|= q_data
->format
.plane_fmt
[1].bytesperline
956 << FD1_WPF_PSTRIDE_C_SHIFT
;
958 format
= q_data
->fmt
->fmt
; /* Output Format Code */
960 if (q_data
->fmt
->swap_yc
)
961 format
|= FD1_WPF_FORMAT_WSPYCS
;
963 if (q_data
->fmt
->swap_uv
)
964 format
|= FD1_WPF_FORMAT_WSPUVS
;
966 if (fdp1_fmt_is_rgb(q_data
->fmt
)) {
967 /* Enable Colour Space conversion */
968 format
|= FD1_WPF_FORMAT_CSC
;
971 if (src_q_data
->format
.ycbcr_enc
== V4L2_YCBCR_ENC_709
)
972 format
|= FD1_WPF_FORMAT_WRTM_709_16
;
973 else if (src_q_data
->format
.quantization
==
974 V4L2_QUANTIZATION_FULL_RANGE
)
975 format
|= FD1_WPF_FORMAT_WRTM_601_0
;
977 format
|= FD1_WPF_FORMAT_WRTM_601_16
;
980 /* Set an alpha value into the Pad Value */
981 format
|= ctx
->alpha
<< FD1_WPF_FORMAT_PDV_SHIFT
;
983 /* Determine picture rounding and clipping */
984 rndctl
= FD1_WPF_RNDCTL_CBRM
; /* Rounding Off */
985 rndctl
|= FD1_WPF_RNDCTL_CLMD_NOCLIP
;
987 /* WPF Swap needs both ISWAP and OSWAP setting */
988 swap
= q_data
->fmt
->swap
<< FD1_WPF_SWAP_OSWAP_SHIFT
;
989 swap
|= src_q_data
->fmt
->swap
<< FD1_WPF_SWAP_SSWAP_SHIFT
;
991 fdp1_write(fdp1
, format
, FD1_WPF_FORMAT
);
992 fdp1_write(fdp1
, rndctl
, FD1_WPF_RNDCTL
);
993 fdp1_write(fdp1
, swap
, FD1_WPF_SWAP
);
994 fdp1_write(fdp1
, pstride
, FD1_WPF_PSTRIDE
);
996 fdp1_write(fdp1
, job
->dst
->addrs
[0], FD1_WPF_ADDR_Y
);
997 fdp1_write(fdp1
, job
->dst
->addrs
[1], FD1_WPF_ADDR_C0
);
998 fdp1_write(fdp1
, job
->dst
->addrs
[2], FD1_WPF_ADDR_C1
);
1001 static void fdp1_configure_deint_mode(struct fdp1_ctx
*ctx
,
1002 struct fdp1_job
*job
)
1004 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
1005 u32 opmode
= FD1_CTL_OPMODE_VIMD_NOINTERRUPT
;
1006 u32 ipcmode
= FD1_IPC_MODE_DLI
; /* Always set */
1007 u32 channels
= FD1_CTL_CHACT_WR
| FD1_CTL_CHACT_RD1
; /* Always on */
1009 /* De-interlacing Mode */
1010 switch (ctx
->deint_mode
) {
1012 case FDP1_PROGRESSIVE
:
1013 dprintk(fdp1
, "Progressive Mode\n");
1014 opmode
|= FD1_CTL_OPMODE_PRG
;
1015 ipcmode
|= FD1_IPC_MODE_DIM_FIXED2D
;
1017 case FDP1_ADAPT2D3D
:
1018 dprintk(fdp1
, "Adapt2D3D Mode\n");
1019 if (ctx
->sequence
== 0 || ctx
->aborting
)
1020 ipcmode
|= FD1_IPC_MODE_DIM_FIXED2D
;
1022 ipcmode
|= FD1_IPC_MODE_DIM_ADAPT2D3D
;
1024 if (ctx
->sequence
> 1) {
1025 channels
|= FD1_CTL_CHACT_SMW
;
1026 channels
|= FD1_CTL_CHACT_RD0
| FD1_CTL_CHACT_RD2
;
1029 if (ctx
->sequence
> 2)
1030 channels
|= FD1_CTL_CHACT_SMR
;
1034 dprintk(fdp1
, "Fixed 3D Mode\n");
1035 ipcmode
|= FD1_IPC_MODE_DIM_FIXED3D
;
1036 /* Except for first and last frame, enable all channels */
1037 if (!(ctx
->sequence
== 0 || ctx
->aborting
))
1038 channels
|= FD1_CTL_CHACT_RD0
| FD1_CTL_CHACT_RD2
;
1041 dprintk(fdp1
, "Fixed 2D Mode\n");
1042 ipcmode
|= FD1_IPC_MODE_DIM_FIXED2D
;
1043 /* No extra channels enabled */
1045 case FDP1_PREVFIELD
:
1046 dprintk(fdp1
, "Previous Field Mode\n");
1047 ipcmode
|= FD1_IPC_MODE_DIM_PREVFIELD
;
1048 channels
|= FD1_CTL_CHACT_RD0
; /* Previous */
1050 case FDP1_NEXTFIELD
:
1051 dprintk(fdp1
, "Next Field Mode\n");
1052 ipcmode
|= FD1_IPC_MODE_DIM_NEXTFIELD
;
1053 channels
|= FD1_CTL_CHACT_RD2
; /* Next */
1057 fdp1_write(fdp1
, channels
, FD1_CTL_CHACT
);
1058 fdp1_write(fdp1
, opmode
, FD1_CTL_OPMODE
);
1059 fdp1_write(fdp1
, ipcmode
, FD1_IPC_MODE
);
1063 * fdp1_device_process() - Run the hardware
1065 * Configure and start the hardware to generate a single frame
1066 * of output given our input parameters.
1068 static int fdp1_device_process(struct fdp1_ctx
*ctx
)
1071 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
1072 struct fdp1_job
*job
;
1073 unsigned long flags
;
1075 spin_lock_irqsave(&fdp1
->device_process_lock
, flags
);
1077 /* Get a job to process */
1078 job
= get_queued_job(fdp1
);
1081 * VINT can call us to see if we can queue another job.
1082 * If we have no work to do, we simply return.
1084 spin_unlock_irqrestore(&fdp1
->device_process_lock
, flags
);
1088 /* First Frame only? ... */
1089 fdp1_write(fdp1
, FD1_CTL_CLKCTRL_CSTP_N
, FD1_CTL_CLKCTRL
);
1091 /* Set the mode, and configuration */
1092 fdp1_configure_deint_mode(ctx
, job
);
1094 /* DLI Static Configuration */
1095 fdp1_set_ipc_dli(ctx
);
1097 /* Sensor Configuration */
1098 fdp1_set_ipc_sensor(ctx
);
1100 /* Setup the source picture */
1101 fdp1_configure_rpf(ctx
, job
);
1103 /* Setup the destination picture */
1104 fdp1_configure_wpf(ctx
, job
);
1106 /* Line Memory Pixel Number Register for linear access */
1107 fdp1_write(fdp1
, FD1_IPC_LMEM_LINEAR
, FD1_IPC_LMEM
);
1109 /* Enable Interrupts */
1110 fdp1_write(fdp1
, FD1_CTL_IRQ_MASK
, FD1_CTL_IRQENB
);
1112 /* Finally, the Immediate Registers */
1114 /* This job is now in the HW queue */
1115 queue_hw_job(fdp1
, job
);
1117 /* Start the command */
1118 fdp1_write(fdp1
, FD1_CTL_CMD_STRCMD
, FD1_CTL_CMD
);
1120 /* Registers will update to HW at next VINT */
1121 fdp1_write(fdp1
, FD1_CTL_REGEND_REGEND
, FD1_CTL_REGEND
);
1123 /* Enable VINT Generator */
1124 fdp1_write(fdp1
, FD1_CTL_SGCMD_SGEN
, FD1_CTL_SGCMD
);
1126 spin_unlock_irqrestore(&fdp1
->device_process_lock
, flags
);
1136 * job_ready() - check whether an instance is ready to be scheduled to run
1138 static int fdp1_m2m_job_ready(void *priv
)
1140 struct fdp1_ctx
*ctx
= priv
;
1141 struct fdp1_q_data
*src_q_data
= &ctx
->out_q
;
1145 dprintk(ctx
->fdp1
, "+ Src: %d : Dst: %d\n",
1146 v4l2_m2m_num_src_bufs_ready(ctx
->fh
.m2m_ctx
),
1147 v4l2_m2m_num_dst_bufs_ready(ctx
->fh
.m2m_ctx
));
1149 /* One output buffer is required for each field */
1150 if (V4L2_FIELD_HAS_BOTH(src_q_data
->format
.field
))
1153 if (v4l2_m2m_num_src_bufs_ready(ctx
->fh
.m2m_ctx
) < srcbufs
1154 || v4l2_m2m_num_dst_bufs_ready(ctx
->fh
.m2m_ctx
) < dstbufs
) {
1155 dprintk(ctx
->fdp1
, "Not enough buffers available\n");
1162 static void fdp1_m2m_job_abort(void *priv
)
1164 struct fdp1_ctx
*ctx
= priv
;
1166 dprintk(ctx
->fdp1
, "+\n");
1168 /* Will cancel the transaction in the next interrupt handler */
1171 /* Immediate abort sequence */
1172 fdp1_write(ctx
->fdp1
, 0, FD1_CTL_SGCMD
);
1173 fdp1_write(ctx
->fdp1
, FD1_CTL_SRESET_SRST
, FD1_CTL_SRESET
);
1177 * fdp1_prepare_job: Prepare and queue a new job for a single action of work
1179 * Prepare the next field, (or frame in progressive) and an output
1180 * buffer for the hardware to perform a single operation.
1182 static struct fdp1_job
*fdp1_prepare_job(struct fdp1_ctx
*ctx
)
1184 struct vb2_v4l2_buffer
*vbuf
;
1185 struct fdp1_buffer
*fbuf
;
1186 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
1187 struct fdp1_job
*job
;
1188 unsigned int buffers_required
= 1;
1190 dprintk(fdp1
, "+\n");
1192 if (FDP1_DEINT_MODE_USES_NEXT(ctx
->deint_mode
))
1193 buffers_required
= 2;
1195 if (ctx
->buffers_queued
< buffers_required
)
1198 job
= fdp1_job_alloc(fdp1
);
1200 dprintk(fdp1
, "No free jobs currently available\n");
1204 job
->active
= fdp1_dequeue_field(ctx
);
1206 /* Buffer check should prevent this ever happening */
1207 dprintk(fdp1
, "No input buffers currently available\n");
1209 fdp1_job_free(fdp1
, job
);
1213 dprintk(fdp1
, "+ Buffer en-route...\n");
1215 /* Source buffers have been prepared on our buffer_queue
1216 * Prepare our Output buffer
1218 vbuf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
1219 fbuf
= to_fdp1_buffer(vbuf
);
1220 job
->dst
= &fbuf
->fields
[0];
1222 job
->active
->vb
->sequence
= ctx
->sequence
;
1223 job
->dst
->vb
->sequence
= ctx
->sequence
;
1226 if (FDP1_DEINT_MODE_USES_PREV(ctx
->deint_mode
)) {
1227 job
->previous
= ctx
->previous
;
1229 /* Active buffer becomes the next job's previous buffer */
1230 ctx
->previous
= job
->active
;
1233 if (FDP1_DEINT_MODE_USES_NEXT(ctx
->deint_mode
)) {
1234 /* Must be called after 'active' is dequeued */
1235 job
->next
= fdp1_peek_queued_field(ctx
);
1238 /* Transfer timestamps and flags from src->dst */
1240 job
->dst
->vb
->vb2_buf
.timestamp
= job
->active
->vb
->vb2_buf
.timestamp
;
1242 job
->dst
->vb
->flags
= job
->active
->vb
->flags
&
1243 V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
1245 /* Ideally, the frame-end function will just 'check' to see
1246 * if there are more jobs instead
1250 /* Finally, Put this job on the processing queue */
1251 queue_job(fdp1
, job
);
1253 dprintk(fdp1
, "Job Queued translen = %d\n", ctx
->translen
);
1258 /* fdp1_m2m_device_run() - prepares and starts the device for an M2M task
1260 * A single input buffer is taken and serialised into our fdp1_buffer
1261 * queue. The queue is then processed to create as many jobs as possible
1262 * from our available input.
1264 static void fdp1_m2m_device_run(void *priv
)
1266 struct fdp1_ctx
*ctx
= priv
;
1267 struct fdp1_dev
*fdp1
= ctx
->fdp1
;
1268 struct vb2_v4l2_buffer
*src_vb
;
1269 struct fdp1_buffer
*buf
;
1272 dprintk(fdp1
, "+\n");
1276 /* Get our incoming buffer of either one or two fields, or one frame */
1277 src_vb
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
1278 buf
= to_fdp1_buffer(src_vb
);
1280 for (i
= 0; i
< buf
->num_fields
; i
++) {
1281 struct fdp1_field_buffer
*fbuf
= &buf
->fields
[i
];
1283 fdp1_queue_field(ctx
, fbuf
);
1284 dprintk(fdp1
, "Queued Buffer [%d] last_field:%d\n",
1285 i
, fbuf
->last_field
);
1288 /* Queue as many jobs as our data provides for */
1289 while (fdp1_prepare_job(ctx
))
1292 if (ctx
->translen
== 0) {
1293 dprintk(fdp1
, "No jobs were processed. M2M action complete\n");
1294 v4l2_m2m_job_finish(fdp1
->m2m_dev
, ctx
->fh
.m2m_ctx
);
1298 /* Kick the job processing action */
1299 fdp1_device_process(ctx
);
1305 * Handles the M2M level after a buffer completion event.
1307 static void device_frame_end(struct fdp1_dev
*fdp1
,
1308 enum vb2_buffer_state state
)
1310 struct fdp1_ctx
*ctx
;
1311 unsigned long flags
;
1312 struct fdp1_job
*job
= get_hw_queued_job(fdp1
);
1314 dprintk(fdp1
, "+\n");
1316 ctx
= v4l2_m2m_get_curr_priv(fdp1
->m2m_dev
);
1319 v4l2_err(&fdp1
->v4l2_dev
,
1320 "Instance released before the end of transaction\n");
1324 ctx
->num_processed
++;
1327 * fdp1_field_complete will call buf_done only when the last vb2_buffer
1328 * reference is complete
1330 if (FDP1_DEINT_MODE_USES_PREV(ctx
->deint_mode
))
1331 fdp1_field_complete(ctx
, job
->previous
);
1333 fdp1_field_complete(ctx
, job
->active
);
1335 spin_lock_irqsave(&fdp1
->irqlock
, flags
);
1336 v4l2_m2m_buf_done(job
->dst
->vb
, state
);
1338 spin_unlock_irqrestore(&fdp1
->irqlock
, flags
);
1340 /* Move this job back to the free job list */
1341 fdp1_job_free(fdp1
, job
);
1343 dprintk(fdp1
, "curr_ctx->num_processed %d curr_ctx->translen %d\n",
1344 ctx
->num_processed
, ctx
->translen
);
1346 if (ctx
->num_processed
== ctx
->translen
||
1348 dprintk(ctx
->fdp1
, "Finishing transaction\n");
1349 ctx
->num_processed
= 0;
1350 v4l2_m2m_job_finish(fdp1
->m2m_dev
, ctx
->fh
.m2m_ctx
);
1353 * For pipelined performance support, this would
1354 * be called from a VINT handler
1356 fdp1_device_process(ctx
);
1363 static int fdp1_vidioc_querycap(struct file
*file
, void *priv
,
1364 struct v4l2_capability
*cap
)
1366 strlcpy(cap
->driver
, DRIVER_NAME
, sizeof(cap
->driver
));
1367 strlcpy(cap
->card
, DRIVER_NAME
, sizeof(cap
->card
));
1368 snprintf(cap
->bus_info
, sizeof(cap
->bus_info
),
1369 "platform:%s", DRIVER_NAME
);
1373 static int fdp1_enum_fmt(struct v4l2_fmtdesc
*f
, u32 type
)
1375 unsigned int i
, num
;
1379 for (i
= 0; i
< ARRAY_SIZE(fdp1_formats
); ++i
) {
1380 if (fdp1_formats
[i
].types
& type
) {
1381 if (num
== f
->index
)
1387 /* Format not found */
1388 if (i
>= ARRAY_SIZE(fdp1_formats
))
1392 f
->pixelformat
= fdp1_formats
[i
].fourcc
;
1397 static int fdp1_enum_fmt_vid_cap(struct file
*file
, void *priv
,
1398 struct v4l2_fmtdesc
*f
)
1400 return fdp1_enum_fmt(f
, FDP1_CAPTURE
);
1403 static int fdp1_enum_fmt_vid_out(struct file
*file
, void *priv
,
1404 struct v4l2_fmtdesc
*f
)
1406 return fdp1_enum_fmt(f
, FDP1_OUTPUT
);
1409 static int fdp1_g_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
1411 struct fdp1_q_data
*q_data
;
1412 struct fdp1_ctx
*ctx
= fh_to_ctx(priv
);
1414 if (!v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
, f
->type
))
1417 q_data
= get_q_data(ctx
, f
->type
);
1418 f
->fmt
.pix_mp
= q_data
->format
;
1423 static void fdp1_compute_stride(struct v4l2_pix_format_mplane
*pix
,
1424 const struct fdp1_fmt
*fmt
)
1428 /* Compute and clamp the stride and image size. */
1429 for (i
= 0; i
< min_t(unsigned int, fmt
->num_planes
, 2U); ++i
) {
1430 unsigned int hsub
= i
> 0 ? fmt
->hsub
: 1;
1431 unsigned int vsub
= i
> 0 ? fmt
->vsub
: 1;
1432 /* From VSP : TODO: Confirm alignment limits for FDP1 */
1433 unsigned int align
= 128;
1436 bpl
= clamp_t(unsigned int, pix
->plane_fmt
[i
].bytesperline
,
1437 pix
->width
/ hsub
* fmt
->bpp
[i
] / 8,
1438 round_down(FDP1_MAX_STRIDE
, align
));
1440 pix
->plane_fmt
[i
].bytesperline
= round_up(bpl
, align
);
1441 pix
->plane_fmt
[i
].sizeimage
= pix
->plane_fmt
[i
].bytesperline
1442 * pix
->height
/ vsub
;
1444 memset(pix
->plane_fmt
[i
].reserved
, 0,
1445 sizeof(pix
->plane_fmt
[i
].reserved
));
1448 if (fmt
->num_planes
== 3) {
1449 /* The two chroma planes must have the same stride. */
1450 pix
->plane_fmt
[2].bytesperline
= pix
->plane_fmt
[1].bytesperline
;
1451 pix
->plane_fmt
[2].sizeimage
= pix
->plane_fmt
[1].sizeimage
;
1453 memset(pix
->plane_fmt
[2].reserved
, 0,
1454 sizeof(pix
->plane_fmt
[2].reserved
));
1458 static void fdp1_try_fmt_output(struct fdp1_ctx
*ctx
,
1459 const struct fdp1_fmt
**fmtinfo
,
1460 struct v4l2_pix_format_mplane
*pix
)
1462 const struct fdp1_fmt
*fmt
;
1464 unsigned int height
;
1466 /* Validate the pixel format to ensure the output queue supports it. */
1467 fmt
= fdp1_find_format(pix
->pixelformat
);
1468 if (!fmt
|| !(fmt
->types
& FDP1_OUTPUT
))
1469 fmt
= fdp1_find_format(V4L2_PIX_FMT_YUYV
);
1474 pix
->pixelformat
= fmt
->fourcc
;
1475 pix
->num_planes
= fmt
->num_planes
;
1478 * Progressive video and all interlaced field orders are acceptable.
1479 * Default to V4L2_FIELD_INTERLACED.
1481 if (pix
->field
!= V4L2_FIELD_NONE
&&
1482 pix
->field
!= V4L2_FIELD_ALTERNATE
&&
1483 !V4L2_FIELD_HAS_BOTH(pix
->field
))
1484 pix
->field
= V4L2_FIELD_INTERLACED
;
1487 * The deinterlacer doesn't care about the colorspace, accept all values
1488 * and default to V4L2_COLORSPACE_SMPTE170M. The YUV to RGB conversion
1489 * at the output of the deinterlacer supports a subset of encodings and
1490 * quantization methods and will only be available when the colorspace
1493 if (pix
->colorspace
== V4L2_COLORSPACE_DEFAULT
)
1494 pix
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
1497 * Align the width and height for YUV 4:2:2 and 4:2:0 formats and clamp
1498 * them to the supported frame size range. The height boundary are
1499 * related to the full frame, divide them by two when the format passes
1500 * fields in separate buffers.
1502 width
= round_down(pix
->width
, fmt
->hsub
);
1503 pix
->width
= clamp(width
, FDP1_MIN_W
, FDP1_MAX_W
);
1505 height
= round_down(pix
->height
, fmt
->vsub
);
1506 if (pix
->field
== V4L2_FIELD_ALTERNATE
)
1507 pix
->height
= clamp(height
, FDP1_MIN_H
/ 2, FDP1_MAX_H
/ 2);
1509 pix
->height
= clamp(height
, FDP1_MIN_H
, FDP1_MAX_H
);
1511 fdp1_compute_stride(pix
, fmt
);
1514 static void fdp1_try_fmt_capture(struct fdp1_ctx
*ctx
,
1515 const struct fdp1_fmt
**fmtinfo
,
1516 struct v4l2_pix_format_mplane
*pix
)
1518 struct fdp1_q_data
*src_data
= &ctx
->out_q
;
1519 enum v4l2_colorspace colorspace
;
1520 enum v4l2_ycbcr_encoding ycbcr_enc
;
1521 enum v4l2_quantization quantization
;
1522 const struct fdp1_fmt
*fmt
;
1526 * Validate the pixel format. We can only accept RGB output formats if
1527 * the input encoding and quantization are compatible with the format
1528 * conversions supported by the hardware. The supported combinations are
1530 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_LIM_RANGE
1531 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_FULL_RANGE
1532 * V4L2_YCBCR_ENC_709 + V4L2_QUANTIZATION_LIM_RANGE
1534 colorspace
= src_data
->format
.colorspace
;
1536 ycbcr_enc
= src_data
->format
.ycbcr_enc
;
1537 if (ycbcr_enc
== V4L2_YCBCR_ENC_DEFAULT
)
1538 ycbcr_enc
= V4L2_MAP_YCBCR_ENC_DEFAULT(colorspace
);
1540 quantization
= src_data
->format
.quantization
;
1541 if (quantization
== V4L2_QUANTIZATION_DEFAULT
)
1542 quantization
= V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace
,
1545 allow_rgb
= ycbcr_enc
== V4L2_YCBCR_ENC_601
||
1546 (ycbcr_enc
== V4L2_YCBCR_ENC_709
&&
1547 quantization
== V4L2_QUANTIZATION_LIM_RANGE
);
1549 fmt
= fdp1_find_format(pix
->pixelformat
);
1550 if (!fmt
|| (!allow_rgb
&& fdp1_fmt_is_rgb(fmt
)))
1551 fmt
= fdp1_find_format(V4L2_PIX_FMT_YUYV
);
1556 pix
->pixelformat
= fmt
->fourcc
;
1557 pix
->num_planes
= fmt
->num_planes
;
1558 pix
->field
= V4L2_FIELD_NONE
;
1561 * The colorspace on the capture queue is copied from the output queue
1562 * as the hardware can't change the colorspace. It can convert YCbCr to
1563 * RGB though, in which case the encoding and quantization are set to
1564 * default values as anything else wouldn't make sense.
1566 pix
->colorspace
= src_data
->format
.colorspace
;
1567 pix
->xfer_func
= src_data
->format
.xfer_func
;
1569 if (fdp1_fmt_is_rgb(fmt
)) {
1570 pix
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
1571 pix
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
1573 pix
->ycbcr_enc
= src_data
->format
.ycbcr_enc
;
1574 pix
->quantization
= src_data
->format
.quantization
;
1578 * The frame width is identical to the output queue, and the height is
1579 * either doubled or identical depending on whether the output queue
1580 * field order contains one or two fields per frame.
1582 pix
->width
= src_data
->format
.width
;
1583 if (src_data
->format
.field
== V4L2_FIELD_ALTERNATE
)
1584 pix
->height
= 2 * src_data
->format
.height
;
1586 pix
->height
= src_data
->format
.height
;
1588 fdp1_compute_stride(pix
, fmt
);
1591 static int fdp1_try_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
1593 struct fdp1_ctx
*ctx
= fh_to_ctx(priv
);
1595 if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
1596 fdp1_try_fmt_output(ctx
, NULL
, &f
->fmt
.pix_mp
);
1598 fdp1_try_fmt_capture(ctx
, NULL
, &f
->fmt
.pix_mp
);
1600 dprintk(ctx
->fdp1
, "Try %s format: %4.4s (0x%08x) %ux%u field %u\n",
1601 V4L2_TYPE_IS_OUTPUT(f
->type
) ? "output" : "capture",
1602 (char *)&f
->fmt
.pix_mp
.pixelformat
, f
->fmt
.pix_mp
.pixelformat
,
1603 f
->fmt
.pix_mp
.width
, f
->fmt
.pix_mp
.height
, f
->fmt
.pix_mp
.field
);
1608 static void fdp1_set_format(struct fdp1_ctx
*ctx
,
1609 struct v4l2_pix_format_mplane
*pix
,
1610 enum v4l2_buf_type type
)
1612 struct fdp1_q_data
*q_data
= get_q_data(ctx
, type
);
1613 const struct fdp1_fmt
*fmtinfo
;
1615 if (type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
1616 fdp1_try_fmt_output(ctx
, &fmtinfo
, pix
);
1618 fdp1_try_fmt_capture(ctx
, &fmtinfo
, pix
);
1620 q_data
->fmt
= fmtinfo
;
1621 q_data
->format
= *pix
;
1623 q_data
->vsize
= pix
->height
;
1624 if (pix
->field
!= V4L2_FIELD_NONE
)
1627 q_data
->stride_y
= pix
->plane_fmt
[0].bytesperline
;
1628 q_data
->stride_c
= pix
->plane_fmt
[1].bytesperline
;
1630 /* Adjust strides for interleaved buffers */
1631 if (pix
->field
== V4L2_FIELD_INTERLACED
||
1632 pix
->field
== V4L2_FIELD_INTERLACED_TB
||
1633 pix
->field
== V4L2_FIELD_INTERLACED_BT
) {
1634 q_data
->stride_y
*= 2;
1635 q_data
->stride_c
*= 2;
1638 /* Propagate the format from the output node to the capture node. */
1639 if (type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) {
1640 struct fdp1_q_data
*dst_data
= &ctx
->cap_q
;
1643 * Copy the format, clear the per-plane bytes per line and image
1644 * size, override the field and double the height if needed.
1646 dst_data
->format
= q_data
->format
;
1647 memset(dst_data
->format
.plane_fmt
, 0,
1648 sizeof(dst_data
->format
.plane_fmt
));
1650 dst_data
->format
.field
= V4L2_FIELD_NONE
;
1651 if (pix
->field
== V4L2_FIELD_ALTERNATE
)
1652 dst_data
->format
.height
*= 2;
1654 fdp1_try_fmt_capture(ctx
, &dst_data
->fmt
, &dst_data
->format
);
1656 dst_data
->vsize
= dst_data
->format
.height
;
1657 dst_data
->stride_y
= dst_data
->format
.plane_fmt
[0].bytesperline
;
1658 dst_data
->stride_c
= dst_data
->format
.plane_fmt
[1].bytesperline
;
1662 static int fdp1_s_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
1664 struct fdp1_ctx
*ctx
= fh_to_ctx(priv
);
1665 struct v4l2_m2m_ctx
*m2m_ctx
= ctx
->fh
.m2m_ctx
;
1666 struct vb2_queue
*vq
= v4l2_m2m_get_vq(m2m_ctx
, f
->type
);
1668 if (vb2_is_busy(vq
)) {
1669 v4l2_err(&ctx
->fdp1
->v4l2_dev
, "%s queue busy\n", __func__
);
1673 fdp1_set_format(ctx
, &f
->fmt
.pix_mp
, f
->type
);
1675 dprintk(ctx
->fdp1
, "Set %s format: %4.4s (0x%08x) %ux%u field %u\n",
1676 V4L2_TYPE_IS_OUTPUT(f
->type
) ? "output" : "capture",
1677 (char *)&f
->fmt
.pix_mp
.pixelformat
, f
->fmt
.pix_mp
.pixelformat
,
1678 f
->fmt
.pix_mp
.width
, f
->fmt
.pix_mp
.height
, f
->fmt
.pix_mp
.field
);
1683 static int fdp1_g_ctrl(struct v4l2_ctrl
*ctrl
)
1685 struct fdp1_ctx
*ctx
=
1686 container_of(ctrl
->handler
, struct fdp1_ctx
, hdl
);
1687 struct fdp1_q_data
*src_q_data
= &ctx
->out_q
;
1690 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE
:
1691 if (V4L2_FIELD_HAS_BOTH(src_q_data
->format
.field
))
1701 static int fdp1_s_ctrl(struct v4l2_ctrl
*ctrl
)
1703 struct fdp1_ctx
*ctx
=
1704 container_of(ctrl
->handler
, struct fdp1_ctx
, hdl
);
1707 case V4L2_CID_ALPHA_COMPONENT
:
1708 ctx
->alpha
= ctrl
->val
;
1711 case V4L2_CID_DEINTERLACING_MODE
:
1712 ctx
->deint_mode
= ctrl
->val
;
1719 static const struct v4l2_ctrl_ops fdp1_ctrl_ops
= {
1720 .s_ctrl
= fdp1_s_ctrl
,
1721 .g_volatile_ctrl
= fdp1_g_ctrl
,
1724 static const char * const fdp1_ctrl_deint_menu
[] = {
1734 static const struct v4l2_ioctl_ops fdp1_ioctl_ops
= {
1735 .vidioc_querycap
= fdp1_vidioc_querycap
,
1737 .vidioc_enum_fmt_vid_cap_mplane
= fdp1_enum_fmt_vid_cap
,
1738 .vidioc_enum_fmt_vid_out_mplane
= fdp1_enum_fmt_vid_out
,
1739 .vidioc_g_fmt_vid_cap_mplane
= fdp1_g_fmt
,
1740 .vidioc_g_fmt_vid_out_mplane
= fdp1_g_fmt
,
1741 .vidioc_try_fmt_vid_cap_mplane
= fdp1_try_fmt
,
1742 .vidioc_try_fmt_vid_out_mplane
= fdp1_try_fmt
,
1743 .vidioc_s_fmt_vid_cap_mplane
= fdp1_s_fmt
,
1744 .vidioc_s_fmt_vid_out_mplane
= fdp1_s_fmt
,
1746 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
1747 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
1748 .vidioc_qbuf
= v4l2_m2m_ioctl_qbuf
,
1749 .vidioc_dqbuf
= v4l2_m2m_ioctl_dqbuf
,
1750 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
1751 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
1752 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
1754 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
1755 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
1757 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
1758 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
1765 static int fdp1_queue_setup(struct vb2_queue
*vq
,
1766 unsigned int *nbuffers
, unsigned int *nplanes
,
1767 unsigned int sizes
[],
1768 struct device
*alloc_ctxs
[])
1770 struct fdp1_ctx
*ctx
= vb2_get_drv_priv(vq
);
1771 struct fdp1_q_data
*q_data
;
1774 q_data
= get_q_data(ctx
, vq
->type
);
1777 if (*nplanes
> FDP1_MAX_PLANES
)
1783 *nplanes
= q_data
->format
.num_planes
;
1785 for (i
= 0; i
< *nplanes
; i
++)
1786 sizes
[i
] = q_data
->format
.plane_fmt
[i
].sizeimage
;
1791 static void fdp1_buf_prepare_field(struct fdp1_q_data
*q_data
,
1792 struct vb2_v4l2_buffer
*vbuf
,
1793 unsigned int field_num
)
1795 struct fdp1_buffer
*buf
= to_fdp1_buffer(vbuf
);
1796 struct fdp1_field_buffer
*fbuf
= &buf
->fields
[field_num
];
1797 unsigned int num_fields
;
1800 num_fields
= V4L2_FIELD_HAS_BOTH(vbuf
->field
) ? 2 : 1;
1803 fbuf
->last_field
= (field_num
+ 1) == num_fields
;
1805 for (i
= 0; i
< vbuf
->vb2_buf
.num_planes
; ++i
)
1806 fbuf
->addrs
[i
] = vb2_dma_contig_plane_dma_addr(&vbuf
->vb2_buf
, i
);
1808 switch (vbuf
->field
) {
1809 case V4L2_FIELD_INTERLACED
:
1811 * Interlaced means bottom-top for 60Hz TV standards (NTSC) and
1812 * top-bottom for 50Hz. As TV standards are not applicable to
1813 * the mem-to-mem API, use the height as a heuristic.
1815 fbuf
->field
= (q_data
->format
.height
< 576) == field_num
1816 ? V4L2_FIELD_TOP
: V4L2_FIELD_BOTTOM
;
1818 case V4L2_FIELD_INTERLACED_TB
:
1819 case V4L2_FIELD_SEQ_TB
:
1820 fbuf
->field
= field_num
? V4L2_FIELD_BOTTOM
: V4L2_FIELD_TOP
;
1822 case V4L2_FIELD_INTERLACED_BT
:
1823 case V4L2_FIELD_SEQ_BT
:
1824 fbuf
->field
= field_num
? V4L2_FIELD_TOP
: V4L2_FIELD_BOTTOM
;
1827 fbuf
->field
= vbuf
->field
;
1831 /* Buffer is completed */
1835 /* Adjust buffer addresses for second field */
1836 switch (vbuf
->field
) {
1837 case V4L2_FIELD_INTERLACED
:
1838 case V4L2_FIELD_INTERLACED_TB
:
1839 case V4L2_FIELD_INTERLACED_BT
:
1840 for (i
= 0; i
< vbuf
->vb2_buf
.num_planes
; i
++)
1842 (i
== 0 ? q_data
->stride_y
: q_data
->stride_c
);
1844 case V4L2_FIELD_SEQ_TB
:
1845 case V4L2_FIELD_SEQ_BT
:
1846 for (i
= 0; i
< vbuf
->vb2_buf
.num_planes
; i
++)
1847 fbuf
->addrs
[i
] += q_data
->vsize
*
1848 (i
== 0 ? q_data
->stride_y
: q_data
->stride_c
);
1853 static int fdp1_buf_prepare(struct vb2_buffer
*vb
)
1855 struct fdp1_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
1856 struct fdp1_q_data
*q_data
= get_q_data(ctx
, vb
->vb2_queue
->type
);
1857 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
1858 struct fdp1_buffer
*buf
= to_fdp1_buffer(vbuf
);
1861 if (V4L2_TYPE_IS_OUTPUT(vb
->vb2_queue
->type
)) {
1862 bool field_valid
= true;
1864 /* Validate the buffer field. */
1865 switch (q_data
->format
.field
) {
1866 case V4L2_FIELD_NONE
:
1867 if (vbuf
->field
!= V4L2_FIELD_NONE
)
1868 field_valid
= false;
1871 case V4L2_FIELD_ALTERNATE
:
1872 if (vbuf
->field
!= V4L2_FIELD_TOP
&&
1873 vbuf
->field
!= V4L2_FIELD_BOTTOM
)
1874 field_valid
= false;
1877 case V4L2_FIELD_INTERLACED
:
1878 case V4L2_FIELD_SEQ_TB
:
1879 case V4L2_FIELD_SEQ_BT
:
1880 case V4L2_FIELD_INTERLACED_TB
:
1881 case V4L2_FIELD_INTERLACED_BT
:
1882 if (vbuf
->field
!= q_data
->format
.field
)
1883 field_valid
= false;
1889 "buffer field %u invalid for format field %u\n",
1890 vbuf
->field
, q_data
->format
.field
);
1894 vbuf
->field
= V4L2_FIELD_NONE
;
1897 /* Validate the planes sizes. */
1898 for (i
= 0; i
< q_data
->format
.num_planes
; i
++) {
1899 unsigned long size
= q_data
->format
.plane_fmt
[i
].sizeimage
;
1901 if (vb2_plane_size(vb
, i
) < size
) {
1903 "data will not fit into plane [%u/%u] (%lu < %lu)\n",
1904 i
, q_data
->format
.num_planes
,
1905 vb2_plane_size(vb
, i
), size
);
1909 /* We have known size formats all around */
1910 vb2_set_plane_payload(vb
, i
, size
);
1913 buf
->num_fields
= V4L2_FIELD_HAS_BOTH(vbuf
->field
) ? 2 : 1;
1914 for (i
= 0; i
< buf
->num_fields
; ++i
)
1915 fdp1_buf_prepare_field(q_data
, vbuf
, i
);
1920 static void fdp1_buf_queue(struct vb2_buffer
*vb
)
1922 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
1923 struct fdp1_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
1925 v4l2_m2m_buf_queue(ctx
->fh
.m2m_ctx
, vbuf
);
1928 static int fdp1_start_streaming(struct vb2_queue
*q
, unsigned int count
)
1930 struct fdp1_ctx
*ctx
= vb2_get_drv_priv(q
);
1931 struct fdp1_q_data
*q_data
= get_q_data(ctx
, q
->type
);
1933 if (V4L2_TYPE_IS_OUTPUT(q
->type
)) {
1935 * Force our deint_mode when we are progressive,
1936 * ignoring any setting on the device from the user,
1937 * Otherwise, lock in the requested de-interlace mode.
1939 if (q_data
->format
.field
== V4L2_FIELD_NONE
)
1940 ctx
->deint_mode
= FDP1_PROGRESSIVE
;
1942 if (ctx
->deint_mode
== FDP1_ADAPT2D3D
) {
1944 dma_addr_t smsk_base
;
1945 const u32 bpp
= 2; /* bytes per pixel */
1947 stride
= round_up(q_data
->format
.width
, 8);
1949 ctx
->smsk_size
= bpp
* stride
* q_data
->vsize
;
1951 ctx
->smsk_cpu
= dma_alloc_coherent(ctx
->fdp1
->dev
,
1952 ctx
->smsk_size
, &smsk_base
, GFP_KERNEL
);
1954 if (ctx
->smsk_cpu
== NULL
) {
1955 dprintk(ctx
->fdp1
, "Failed to alloc smsk\n");
1959 ctx
->smsk_addr
[0] = smsk_base
;
1960 ctx
->smsk_addr
[1] = smsk_base
+ (ctx
->smsk_size
/2);
1967 static void fdp1_stop_streaming(struct vb2_queue
*q
)
1969 struct fdp1_ctx
*ctx
= vb2_get_drv_priv(q
);
1970 struct vb2_v4l2_buffer
*vbuf
;
1971 unsigned long flags
;
1974 if (V4L2_TYPE_IS_OUTPUT(q
->type
))
1975 vbuf
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
1977 vbuf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
1980 spin_lock_irqsave(&ctx
->fdp1
->irqlock
, flags
);
1981 v4l2_m2m_buf_done(vbuf
, VB2_BUF_STATE_ERROR
);
1982 spin_unlock_irqrestore(&ctx
->fdp1
->irqlock
, flags
);
1985 /* Empty Output queues */
1986 if (V4L2_TYPE_IS_OUTPUT(q
->type
)) {
1987 /* Empty our internal queues */
1988 struct fdp1_field_buffer
*fbuf
;
1990 /* Free any queued buffers */
1991 fbuf
= fdp1_dequeue_field(ctx
);
1992 while (fbuf
!= NULL
) {
1993 fdp1_field_complete(ctx
, fbuf
);
1994 fbuf
= fdp1_dequeue_field(ctx
);
1997 /* Free smsk_data */
1998 if (ctx
->smsk_cpu
) {
1999 dma_free_coherent(ctx
->fdp1
->dev
, ctx
->smsk_size
,
2000 ctx
->smsk_cpu
, ctx
->smsk_addr
[0]);
2001 ctx
->smsk_addr
[0] = ctx
->smsk_addr
[1] = 0;
2002 ctx
->smsk_cpu
= NULL
;
2005 WARN(!list_empty(&ctx
->fields_queue
),
2006 "Buffer queue not empty");
2008 /* Empty Capture queues (Jobs) */
2009 struct fdp1_job
*job
;
2011 job
= get_queued_job(ctx
->fdp1
);
2013 if (FDP1_DEINT_MODE_USES_PREV(ctx
->deint_mode
))
2014 fdp1_field_complete(ctx
, job
->previous
);
2016 fdp1_field_complete(ctx
, job
->active
);
2018 v4l2_m2m_buf_done(job
->dst
->vb
, VB2_BUF_STATE_ERROR
);
2021 job
= get_queued_job(ctx
->fdp1
);
2024 /* Free any held buffer in the ctx */
2025 fdp1_field_complete(ctx
, ctx
->previous
);
2027 WARN(!list_empty(&ctx
->fdp1
->queued_job_list
),
2028 "Queued Job List not empty");
2030 WARN(!list_empty(&ctx
->fdp1
->hw_job_list
),
2031 "HW Job list not empty");
2035 static const struct vb2_ops fdp1_qops
= {
2036 .queue_setup
= fdp1_queue_setup
,
2037 .buf_prepare
= fdp1_buf_prepare
,
2038 .buf_queue
= fdp1_buf_queue
,
2039 .start_streaming
= fdp1_start_streaming
,
2040 .stop_streaming
= fdp1_stop_streaming
,
2041 .wait_prepare
= vb2_ops_wait_prepare
,
2042 .wait_finish
= vb2_ops_wait_finish
,
2045 static int queue_init(void *priv
, struct vb2_queue
*src_vq
,
2046 struct vb2_queue
*dst_vq
)
2048 struct fdp1_ctx
*ctx
= priv
;
2051 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
2052 src_vq
->io_modes
= VB2_MMAP
| VB2_USERPTR
| VB2_DMABUF
;
2053 src_vq
->drv_priv
= ctx
;
2054 src_vq
->buf_struct_size
= sizeof(struct fdp1_buffer
);
2055 src_vq
->ops
= &fdp1_qops
;
2056 src_vq
->mem_ops
= &vb2_dma_contig_memops
;
2057 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
2058 src_vq
->lock
= &ctx
->fdp1
->dev_mutex
;
2059 src_vq
->dev
= ctx
->fdp1
->dev
;
2061 ret
= vb2_queue_init(src_vq
);
2065 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
2066 dst_vq
->io_modes
= VB2_MMAP
| VB2_USERPTR
| VB2_DMABUF
;
2067 dst_vq
->drv_priv
= ctx
;
2068 dst_vq
->buf_struct_size
= sizeof(struct fdp1_buffer
);
2069 dst_vq
->ops
= &fdp1_qops
;
2070 dst_vq
->mem_ops
= &vb2_dma_contig_memops
;
2071 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
2072 dst_vq
->lock
= &ctx
->fdp1
->dev_mutex
;
2073 dst_vq
->dev
= ctx
->fdp1
->dev
;
2075 return vb2_queue_init(dst_vq
);
2081 static int fdp1_open(struct file
*file
)
2083 struct fdp1_dev
*fdp1
= video_drvdata(file
);
2084 struct v4l2_pix_format_mplane format
;
2085 struct fdp1_ctx
*ctx
= NULL
;
2086 struct v4l2_ctrl
*ctrl
;
2089 if (mutex_lock_interruptible(&fdp1
->dev_mutex
))
2090 return -ERESTARTSYS
;
2092 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
2098 v4l2_fh_init(&ctx
->fh
, video_devdata(file
));
2099 file
->private_data
= &ctx
->fh
;
2102 /* Initialise Queues */
2103 INIT_LIST_HEAD(&ctx
->fields_queue
);
2108 /* Initialise controls */
2110 v4l2_ctrl_handler_init(&ctx
->hdl
, 3);
2111 v4l2_ctrl_new_std_menu_items(&ctx
->hdl
, &fdp1_ctrl_ops
,
2112 V4L2_CID_DEINTERLACING_MODE
,
2113 FDP1_NEXTFIELD
, BIT(0), FDP1_FIXED3D
,
2114 fdp1_ctrl_deint_menu
);
2116 ctrl
= v4l2_ctrl_new_std(&ctx
->hdl
, &fdp1_ctrl_ops
,
2117 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE
, 1, 2, 1, 1);
2119 ctrl
->flags
|= V4L2_CTRL_FLAG_VOLATILE
;
2121 v4l2_ctrl_new_std(&ctx
->hdl
, &fdp1_ctrl_ops
,
2122 V4L2_CID_ALPHA_COMPONENT
, 0, 255, 1, 255);
2124 if (ctx
->hdl
.error
) {
2125 ret
= ctx
->hdl
.error
;
2126 v4l2_ctrl_handler_free(&ctx
->hdl
);
2130 ctx
->fh
.ctrl_handler
= &ctx
->hdl
;
2131 v4l2_ctrl_handler_setup(&ctx
->hdl
);
2133 /* Configure default parameters. */
2134 memset(&format
, 0, sizeof(format
));
2135 fdp1_set_format(ctx
, &format
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
);
2137 ctx
->fh
.m2m_ctx
= v4l2_m2m_ctx_init(fdp1
->m2m_dev
, ctx
, &queue_init
);
2139 if (IS_ERR(ctx
->fh
.m2m_ctx
)) {
2140 ret
= PTR_ERR(ctx
->fh
.m2m_ctx
);
2142 v4l2_ctrl_handler_free(&ctx
->hdl
);
2147 /* Perform any power management required */
2148 pm_runtime_get_sync(fdp1
->dev
);
2150 v4l2_fh_add(&ctx
->fh
);
2152 dprintk(fdp1
, "Created instance: %p, m2m_ctx: %p\n",
2153 ctx
, ctx
->fh
.m2m_ctx
);
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
;
2259 struct resource
*res
;
2266 fdp1
= devm_kzalloc(&pdev
->dev
, sizeof(*fdp1
), GFP_KERNEL
);
2270 INIT_LIST_HEAD(&fdp1
->free_job_list
);
2271 INIT_LIST_HEAD(&fdp1
->queued_job_list
);
2272 INIT_LIST_HEAD(&fdp1
->hw_job_list
);
2274 /* Initialise the jobs on the free list */
2275 for (i
= 0; i
< ARRAY_SIZE(fdp1
->jobs
); i
++)
2276 list_add(&fdp1
->jobs
[i
].list
, &fdp1
->free_job_list
);
2278 mutex_init(&fdp1
->dev_mutex
);
2280 spin_lock_init(&fdp1
->irqlock
);
2281 spin_lock_init(&fdp1
->device_process_lock
);
2282 fdp1
->dev
= &pdev
->dev
;
2283 platform_set_drvdata(pdev
, fdp1
);
2285 /* Memory-mapped registers */
2286 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
2287 fdp1
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
2288 if (IS_ERR(fdp1
->regs
))
2289 return PTR_ERR(fdp1
->regs
);
2291 /* Interrupt service routine registration */
2292 fdp1
->irq
= ret
= platform_get_irq(pdev
, 0);
2294 dev_err(&pdev
->dev
, "cannot find IRQ\n");
2298 ret
= devm_request_irq(&pdev
->dev
, fdp1
->irq
, fdp1_irq_handler
, 0,
2299 dev_name(&pdev
->dev
), fdp1
);
2301 dev_err(&pdev
->dev
, "cannot claim IRQ %d\n", fdp1
->irq
);
2306 fcp_node
= of_parse_phandle(pdev
->dev
.of_node
, "renesas,fcp", 0);
2308 fdp1
->fcp
= rcar_fcp_get(fcp_node
);
2309 of_node_put(fcp_node
);
2310 if (IS_ERR(fdp1
->fcp
)) {
2311 dev_err(&pdev
->dev
, "FCP not found (%ld)\n",
2312 PTR_ERR(fdp1
->fcp
));
2313 return PTR_ERR(fdp1
->fcp
);
2317 /* Determine our clock rate */
2318 clk
= clk_get(&pdev
->dev
, NULL
);
2320 return PTR_ERR(clk
);
2322 fdp1
->clk_rate
= clk_get_rate(clk
);
2325 /* V4L2 device registration */
2326 ret
= v4l2_device_register(&pdev
->dev
, &fdp1
->v4l2_dev
);
2328 v4l2_err(&fdp1
->v4l2_dev
, "Failed to register video device\n");
2332 /* M2M registration */
2333 fdp1
->m2m_dev
= v4l2_m2m_init(&m2m_ops
);
2334 if (IS_ERR(fdp1
->m2m_dev
)) {
2335 v4l2_err(&fdp1
->v4l2_dev
, "Failed to init mem2mem device\n");
2336 ret
= PTR_ERR(fdp1
->m2m_dev
);
2340 /* Video registration */
2341 fdp1
->vfd
= fdp1_videodev
;
2343 vfd
->lock
= &fdp1
->dev_mutex
;
2344 vfd
->v4l2_dev
= &fdp1
->v4l2_dev
;
2345 video_set_drvdata(vfd
, fdp1
);
2346 strlcpy(vfd
->name
, fdp1_videodev
.name
, sizeof(vfd
->name
));
2348 ret
= video_register_device(vfd
, VFL_TYPE_GRABBER
, 0);
2350 v4l2_err(&fdp1
->v4l2_dev
, "Failed to register video device\n");
2354 v4l2_info(&fdp1
->v4l2_dev
,
2355 "Device registered as /dev/video%d\n", vfd
->num
);
2357 /* Power up the cells to read HW */
2358 pm_runtime_enable(&pdev
->dev
);
2359 pm_runtime_get_sync(fdp1
->dev
);
2361 hw_version
= fdp1_read(fdp1
, FD1_IP_INTDATA
);
2362 switch (hw_version
) {
2364 dprintk(fdp1
, "FDP1 Version R-Car H3 ES1\n");
2367 dprintk(fdp1
, "FDP1 Version R-Car M3-W\n");
2370 dprintk(fdp1
, "FDP1 Version R-Car H3\n");
2373 dev_err(fdp1
->dev
, "FDP1 Unidentifiable (0x%08x)\n",
2377 /* Allow the hw to sleep until an open call puts it to use */
2378 pm_runtime_put(fdp1
->dev
);
2383 v4l2_m2m_release(fdp1
->m2m_dev
);
2386 v4l2_device_unregister(&fdp1
->v4l2_dev
);
2391 static int fdp1_remove(struct platform_device
*pdev
)
2393 struct fdp1_dev
*fdp1
= platform_get_drvdata(pdev
);
2395 v4l2_m2m_release(fdp1
->m2m_dev
);
2396 video_unregister_device(&fdp1
->vfd
);
2397 v4l2_device_unregister(&fdp1
->v4l2_dev
);
2398 pm_runtime_disable(&pdev
->dev
);
2403 static int __maybe_unused
fdp1_pm_runtime_suspend(struct device
*dev
)
2405 struct fdp1_dev
*fdp1
= dev_get_drvdata(dev
);
2407 rcar_fcp_disable(fdp1
->fcp
);
2412 static int __maybe_unused
fdp1_pm_runtime_resume(struct device
*dev
)
2414 struct fdp1_dev
*fdp1
= dev_get_drvdata(dev
);
2416 /* Program in the static LUTs */
2419 return rcar_fcp_enable(fdp1
->fcp
);
2422 static const struct dev_pm_ops fdp1_pm_ops
= {
2423 SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend
,
2424 fdp1_pm_runtime_resume
,
2428 static const struct of_device_id fdp1_dt_ids
[] = {
2429 { .compatible
= "renesas,fdp1" },
2432 MODULE_DEVICE_TABLE(of
, fdp1_dt_ids
);
2434 static struct platform_driver fdp1_pdrv
= {
2435 .probe
= fdp1_probe
,
2436 .remove
= fdp1_remove
,
2438 .name
= DRIVER_NAME
,
2439 .of_match_table
= fdp1_dt_ids
,
2444 module_platform_driver(fdp1_pdrv
);
2446 MODULE_DESCRIPTION("Renesas R-Car Fine Display Processor Driver");
2447 MODULE_AUTHOR("Kieran Bingham <kieran@bingham.xyz>");
2448 MODULE_LICENSE("GPL");
2449 MODULE_ALIAS("platform:" DRIVER_NAME
);