1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for Renesas R-Car VIN
4  *
5  * Copyright (C) 2016 Renesas Electronics Corp.
6  * Copyright (C) 2011-2013 Renesas Solutions Corp.
7  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8  * Copyright (C) 2008 Magnus Damm
9  *
10  * Based on the soc-camera rcar_vin driver
11  */
12 
13 #include <linux/delay.h>
14 #include <linux/interrupt.h>
15 #include <linux/pm_runtime.h>
16 
17 #include <media/videobuf2-dma-contig.h>
18 
19 #include "rcar-vin.h"
20 
21 /* -----------------------------------------------------------------------------
22  * HW Functions
23  */
24 
25 /* Register offsets for R-Car VIN */
26 #define VNMC_REG	0x00	/* Video n Main Control Register */
27 #define VNMS_REG	0x04	/* Video n Module Status Register */
28 #define VNFC_REG	0x08	/* Video n Frame Capture Register */
29 #define VNSLPRC_REG	0x0C	/* Video n Start Line Pre-Clip Register */
30 #define VNELPRC_REG	0x10	/* Video n End Line Pre-Clip Register */
31 #define VNSPPRC_REG	0x14	/* Video n Start Pixel Pre-Clip Register */
32 #define VNEPPRC_REG	0x18	/* Video n End Pixel Pre-Clip Register */
33 #define VNIS_REG	0x2C	/* Video n Image Stride Register */
34 #define VNMB_REG(m)	(0x30 + ((m) << 2)) /* Video n Memory Base m Register */
35 #define VNIE_REG	0x40	/* Video n Interrupt Enable Register */
36 #define VNINTS_REG	0x44	/* Video n Interrupt Status Register */
37 #define VNSI_REG	0x48	/* Video n Scanline Interrupt Register */
38 #define VNMTC_REG	0x4C	/* Video n Memory Transfer Control Register */
39 #define VNDMR_REG	0x58	/* Video n Data Mode Register */
40 #define VNDMR2_REG	0x5C	/* Video n Data Mode Register 2 */
41 #define VNUVAOF_REG	0x60	/* Video n UV Address Offset Register */
42 
43 /* Register offsets specific for Gen2 */
44 #define VNSLPOC_REG	0x1C	/* Video n Start Line Post-Clip Register */
45 #define VNELPOC_REG	0x20	/* Video n End Line Post-Clip Register */
46 #define VNSPPOC_REG	0x24	/* Video n Start Pixel Post-Clip Register */
47 #define VNEPPOC_REG	0x28	/* Video n End Pixel Post-Clip Register */
48 #define VNYS_REG	0x50	/* Video n Y Scale Register */
49 #define VNXS_REG	0x54	/* Video n X Scale Register */
50 #define VNC1A_REG	0x80	/* Video n Coefficient Set C1A Register */
51 #define VNC1B_REG	0x84	/* Video n Coefficient Set C1B Register */
52 #define VNC1C_REG	0x88	/* Video n Coefficient Set C1C Register */
53 #define VNC2A_REG	0x90	/* Video n Coefficient Set C2A Register */
54 #define VNC2B_REG	0x94	/* Video n Coefficient Set C2B Register */
55 #define VNC2C_REG	0x98	/* Video n Coefficient Set C2C Register */
56 #define VNC3A_REG	0xA0	/* Video n Coefficient Set C3A Register */
57 #define VNC3B_REG	0xA4	/* Video n Coefficient Set C3B Register */
58 #define VNC3C_REG	0xA8	/* Video n Coefficient Set C3C Register */
59 #define VNC4A_REG	0xB0	/* Video n Coefficient Set C4A Register */
60 #define VNC4B_REG	0xB4	/* Video n Coefficient Set C4B Register */
61 #define VNC4C_REG	0xB8	/* Video n Coefficient Set C4C Register */
62 #define VNC5A_REG	0xC0	/* Video n Coefficient Set C5A Register */
63 #define VNC5B_REG	0xC4	/* Video n Coefficient Set C5B Register */
64 #define VNC5C_REG	0xC8	/* Video n Coefficient Set C5C Register */
65 #define VNC6A_REG	0xD0	/* Video n Coefficient Set C6A Register */
66 #define VNC6B_REG	0xD4	/* Video n Coefficient Set C6B Register */
67 #define VNC6C_REG	0xD8	/* Video n Coefficient Set C6C Register */
68 #define VNC7A_REG	0xE0	/* Video n Coefficient Set C7A Register */
69 #define VNC7B_REG	0xE4	/* Video n Coefficient Set C7B Register */
70 #define VNC7C_REG	0xE8	/* Video n Coefficient Set C7C Register */
71 #define VNC8A_REG	0xF0	/* Video n Coefficient Set C8A Register */
72 #define VNC8B_REG	0xF4	/* Video n Coefficient Set C8B Register */
73 #define VNC8C_REG	0xF8	/* Video n Coefficient Set C8C Register */
74 
75 /* Register offsets specific for Gen3 */
76 #define VNCSI_IFMD_REG		0x20 /* Video n CSI2 Interface Mode Register */
77 
78 /* Register bit fields for R-Car VIN */
79 /* Video n Main Control Register bits */
80 #define VNMC_DPINE		(1 << 27) /* Gen3 specific */
81 #define VNMC_SCLE		(1 << 26) /* Gen3 specific */
82 #define VNMC_FOC		(1 << 21)
83 #define VNMC_YCAL		(1 << 19)
84 #define VNMC_INF_YUV8_BT656	(0 << 16)
85 #define VNMC_INF_YUV8_BT601	(1 << 16)
86 #define VNMC_INF_YUV10_BT656	(2 << 16)
87 #define VNMC_INF_YUV10_BT601	(3 << 16)
88 #define VNMC_INF_RAW8		(4 << 16)
89 #define VNMC_INF_YUV16		(5 << 16)
90 #define VNMC_INF_RGB888		(6 << 16)
91 #define VNMC_VUP		(1 << 10)
92 #define VNMC_IM_ODD		(0 << 3)
93 #define VNMC_IM_ODD_EVEN	(1 << 3)
94 #define VNMC_IM_EVEN		(2 << 3)
95 #define VNMC_IM_FULL		(3 << 3)
96 #define VNMC_BPS		(1 << 1)
97 #define VNMC_ME			(1 << 0)
98 
99 /* Video n Module Status Register bits */
100 #define VNMS_FBS_MASK		(3 << 3)
101 #define VNMS_FBS_SHIFT		3
102 #define VNMS_FS			(1 << 2)
103 #define VNMS_AV			(1 << 1)
104 #define VNMS_CA			(1 << 0)
105 
106 /* Video n Frame Capture Register bits */
107 #define VNFC_C_FRAME		(1 << 1)
108 #define VNFC_S_FRAME		(1 << 0)
109 
110 /* Video n Interrupt Enable Register bits */
111 #define VNIE_FIE		(1 << 4)
112 #define VNIE_EFE		(1 << 1)
113 
114 /* Video n Data Mode Register bits */
115 #define VNDMR_A8BIT(n)		(((n) & 0xff) << 24)
116 #define VNDMR_A8BIT_MASK	(0xff << 24)
117 #define VNDMR_EXRGB		(1 << 8)
118 #define VNDMR_BPSM		(1 << 4)
119 #define VNDMR_ABIT		(1 << 2)
120 #define VNDMR_DTMD_YCSEP	(1 << 1)
121 #define VNDMR_DTMD_ARGB		(1 << 0)
122 #define VNDMR_DTMD_YCSEP_420	(3 << 0)
123 
124 /* Video n Data Mode Register 2 bits */
125 #define VNDMR2_VPS		(1 << 30)
126 #define VNDMR2_HPS		(1 << 29)
127 #define VNDMR2_CES		(1 << 28)
128 #define VNDMR2_YDS		(1 << 22)
129 #define VNDMR2_FTEV		(1 << 17)
130 #define VNDMR2_VLV(n)		((n & 0xf) << 12)
131 
132 /* Video n CSI2 Interface Mode Register (Gen3) */
133 #define VNCSI_IFMD_DES1		(1 << 26)
134 #define VNCSI_IFMD_DES0		(1 << 25)
135 #define VNCSI_IFMD_CSI_CHSEL(n) (((n) & 0xf) << 0)
136 
137 struct rvin_buffer {
138 	struct vb2_v4l2_buffer vb;
139 	struct list_head list;
140 };
141 
142 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
143 					       struct rvin_buffer, \
144 					       vb)->list)
145 
rvin_write(struct rvin_dev * vin,u32 value,u32 offset)146 static void rvin_write(struct rvin_dev *vin, u32 value, u32 offset)
147 {
148 	iowrite32(value, vin->base + offset);
149 }
150 
rvin_read(struct rvin_dev * vin,u32 offset)151 static u32 rvin_read(struct rvin_dev *vin, u32 offset)
152 {
153 	return ioread32(vin->base + offset);
154 }
155 
156 /* -----------------------------------------------------------------------------
157  * Crop and Scaling Gen2
158  */
159 
160 struct vin_coeff {
161 	unsigned short xs_value;
162 	u32 coeff_set[24];
163 };
164 
165 static const struct vin_coeff vin_coeff_set[] = {
166 	{ 0x0000, {
167 			  0x00000000, 0x00000000, 0x00000000,
168 			  0x00000000, 0x00000000, 0x00000000,
169 			  0x00000000, 0x00000000, 0x00000000,
170 			  0x00000000, 0x00000000, 0x00000000,
171 			  0x00000000, 0x00000000, 0x00000000,
172 			  0x00000000, 0x00000000, 0x00000000,
173 			  0x00000000, 0x00000000, 0x00000000,
174 			  0x00000000, 0x00000000, 0x00000000 },
175 	},
176 	{ 0x1000, {
177 			  0x000fa400, 0x000fa400, 0x09625902,
178 			  0x000003f8, 0x00000403, 0x3de0d9f0,
179 			  0x001fffed, 0x00000804, 0x3cc1f9c3,
180 			  0x001003de, 0x00000c01, 0x3cb34d7f,
181 			  0x002003d2, 0x00000c00, 0x3d24a92d,
182 			  0x00200bca, 0x00000bff, 0x3df600d2,
183 			  0x002013cc, 0x000007ff, 0x3ed70c7e,
184 			  0x00100fde, 0x00000000, 0x3f87c036 },
185 	},
186 	{ 0x1200, {
187 			  0x002ffff1, 0x002ffff1, 0x02a0a9c8,
188 			  0x002003e7, 0x001ffffa, 0x000185bc,
189 			  0x002007dc, 0x000003ff, 0x3e52859c,
190 			  0x00200bd4, 0x00000002, 0x3d53996b,
191 			  0x00100fd0, 0x00000403, 0x3d04ad2d,
192 			  0x00000bd5, 0x00000403, 0x3d35ace7,
193 			  0x3ff003e4, 0x00000801, 0x3dc674a1,
194 			  0x3fffe800, 0x00000800, 0x3e76f461 },
195 	},
196 	{ 0x1400, {
197 			  0x00100be3, 0x00100be3, 0x04d1359a,
198 			  0x00000fdb, 0x002003ed, 0x0211fd93,
199 			  0x00000fd6, 0x002003f4, 0x0002d97b,
200 			  0x000007d6, 0x002ffffb, 0x3e93b956,
201 			  0x3ff003da, 0x001003ff, 0x3db49926,
202 			  0x3fffefe9, 0x00100001, 0x3d655cee,
203 			  0x3fffd400, 0x00000003, 0x3d65f4b6,
204 			  0x000fb421, 0x00000402, 0x3dc6547e },
205 	},
206 	{ 0x1600, {
207 			  0x00000bdd, 0x00000bdd, 0x06519578,
208 			  0x3ff007da, 0x00000be3, 0x03c24973,
209 			  0x3ff003d9, 0x00000be9, 0x01b30d5f,
210 			  0x3ffff7df, 0x001003f1, 0x0003c542,
211 			  0x000fdfec, 0x001003f7, 0x3ec4711d,
212 			  0x000fc400, 0x002ffffd, 0x3df504f1,
213 			  0x001fa81a, 0x002ffc00, 0x3d957cc2,
214 			  0x002f8c3c, 0x00100000, 0x3db5c891 },
215 	},
216 	{ 0x1800, {
217 			  0x3ff003dc, 0x3ff003dc, 0x0791e558,
218 			  0x000ff7dd, 0x3ff007de, 0x05328554,
219 			  0x000fe7e3, 0x3ff00be2, 0x03232546,
220 			  0x000fd7ee, 0x000007e9, 0x0143bd30,
221 			  0x001fb800, 0x000007ee, 0x00044511,
222 			  0x002fa015, 0x000007f4, 0x3ef4bcee,
223 			  0x002f8832, 0x001003f9, 0x3e4514c7,
224 			  0x001f7853, 0x001003fd, 0x3de54c9f },
225 	},
226 	{ 0x1a00, {
227 			  0x000fefe0, 0x000fefe0, 0x08721d3c,
228 			  0x001fdbe7, 0x000ffbde, 0x0652a139,
229 			  0x001fcbf0, 0x000003df, 0x0463292e,
230 			  0x002fb3ff, 0x3ff007e3, 0x0293a91d,
231 			  0x002f9c12, 0x3ff00be7, 0x01241905,
232 			  0x001f8c29, 0x000007ed, 0x3fe470eb,
233 			  0x000f7c46, 0x000007f2, 0x3f04b8ca,
234 			  0x3fef7865, 0x000007f6, 0x3e74e4a8 },
235 	},
236 	{ 0x1c00, {
237 			  0x001fd3e9, 0x001fd3e9, 0x08f23d26,
238 			  0x002fbff3, 0x001fe3e4, 0x0712ad23,
239 			  0x002fa800, 0x000ff3e0, 0x05631d1b,
240 			  0x001f9810, 0x000ffbe1, 0x03b3890d,
241 			  0x000f8c23, 0x000003e3, 0x0233e8fa,
242 			  0x3fef843b, 0x000003e7, 0x00f430e4,
243 			  0x3fbf8456, 0x3ff00bea, 0x00046cc8,
244 			  0x3f8f8c72, 0x3ff00bef, 0x3f3490ac },
245 	},
246 	{ 0x1e00, {
247 			  0x001fbbf4, 0x001fbbf4, 0x09425112,
248 			  0x001fa800, 0x002fc7ed, 0x0792b110,
249 			  0x000f980e, 0x001fdbe6, 0x0613110a,
250 			  0x3fff8c20, 0x001fe7e3, 0x04a368fd,
251 			  0x3fcf8c33, 0x000ff7e2, 0x0343b8ed,
252 			  0x3f9f8c4a, 0x000fffe3, 0x0203f8da,
253 			  0x3f5f9c61, 0x000003e6, 0x00e428c5,
254 			  0x3f1fb07b, 0x000003eb, 0x3fe440af },
255 	},
256 	{ 0x2000, {
257 			  0x000fa400, 0x000fa400, 0x09625902,
258 			  0x3fff980c, 0x001fb7f5, 0x0812b0ff,
259 			  0x3fdf901c, 0x001fc7ed, 0x06b2fcfa,
260 			  0x3faf902d, 0x001fd3e8, 0x055348f1,
261 			  0x3f7f983f, 0x001fe3e5, 0x04038ce3,
262 			  0x3f3fa454, 0x001fefe3, 0x02e3c8d1,
263 			  0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0,
264 			  0x3ecfd880, 0x000fffe6, 0x00c404ac },
265 	},
266 	{ 0x2200, {
267 			  0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4,
268 			  0x3fbf9818, 0x3fffa400, 0x0842a8f1,
269 			  0x3f8f9827, 0x000fb3f7, 0x0702f0ec,
270 			  0x3f5fa037, 0x000fc3ef, 0x05d330e4,
271 			  0x3f2fac49, 0x001fcfea, 0x04a364d9,
272 			  0x3effc05c, 0x001fdbe7, 0x038394ca,
273 			  0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb,
274 			  0x3ea00083, 0x001fefe6, 0x0183c0a9 },
275 	},
276 	{ 0x2400, {
277 			  0x3f9fa014, 0x3f9fa014, 0x098260e6,
278 			  0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5,
279 			  0x3f4fa431, 0x3fefa400, 0x0742d8e1,
280 			  0x3f1fb440, 0x3fffb3f8, 0x062310d9,
281 			  0x3eefc850, 0x000fbbf2, 0x050340d0,
282 			  0x3ecfe062, 0x000fcbec, 0x041364c2,
283 			  0x3ea00073, 0x001fd3ea, 0x03037cb5,
284 			  0x3e902086, 0x001fdfe8, 0x022388a5 },
285 	},
286 	{ 0x2600, {
287 			  0x3f5fa81e, 0x3f5fa81e, 0x096258da,
288 			  0x3f3fac2b, 0x3f8fa412, 0x088290d8,
289 			  0x3f0fbc38, 0x3fafa408, 0x0772c8d5,
290 			  0x3eefcc47, 0x3fcfa800, 0x0672f4ce,
291 			  0x3ecfe456, 0x3fefaffa, 0x05531cc6,
292 			  0x3eb00066, 0x3fffbbf3, 0x047334bb,
293 			  0x3ea01c77, 0x000fc7ee, 0x039348ae,
294 			  0x3ea04486, 0x000fd3eb, 0x02b350a1 },
295 	},
296 	{ 0x2800, {
297 			  0x3f2fb426, 0x3f2fb426, 0x094250ce,
298 			  0x3f0fc032, 0x3f4fac1b, 0x086284cd,
299 			  0x3eefd040, 0x3f7fa811, 0x0782acc9,
300 			  0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4,
301 			  0x3eb0005b, 0x3fbfac00, 0x05b2f4bc,
302 			  0x3eb0186a, 0x3fdfb3fa, 0x04c308b4,
303 			  0x3eb04077, 0x3fefbbf4, 0x03f31ca8,
304 			  0x3ec06884, 0x000fbff2, 0x03031c9e },
305 	},
306 	{ 0x2a00, {
307 			  0x3f0fc42d, 0x3f0fc42d, 0x090240c4,
308 			  0x3eefd439, 0x3f2fb822, 0x08526cc2,
309 			  0x3edfe845, 0x3f4fb018, 0x078294bf,
310 			  0x3ec00051, 0x3f6fac0f, 0x06b2b4bb,
311 			  0x3ec0185f, 0x3f8fac07, 0x05e2ccb4,
312 			  0x3ec0386b, 0x3fafac00, 0x0502e8ac,
313 			  0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3,
314 			  0x3ef08482, 0x3fdfbbf6, 0x0372f898 },
315 	},
316 	{ 0x2c00, {
317 			  0x3eefdc31, 0x3eefdc31, 0x08e238b8,
318 			  0x3edfec3d, 0x3f0fc828, 0x082258b9,
319 			  0x3ed00049, 0x3f1fc01e, 0x077278b6,
320 			  0x3ed01455, 0x3f3fb815, 0x06c294b2,
321 			  0x3ed03460, 0x3f5fb40d, 0x0602acac,
322 			  0x3ef0506c, 0x3f7fb006, 0x0542c0a4,
323 			  0x3f107476, 0x3f9fb400, 0x0472c89d,
324 			  0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 },
325 	},
326 	{ 0x2e00, {
327 			  0x3eefec37, 0x3eefec37, 0x088220b0,
328 			  0x3ee00041, 0x3effdc2d, 0x07f244ae,
329 			  0x3ee0144c, 0x3f0fd023, 0x07625cad,
330 			  0x3ef02c57, 0x3f1fc81a, 0x06c274a9,
331 			  0x3f004861, 0x3f3fbc13, 0x060288a6,
332 			  0x3f20686b, 0x3f5fb80c, 0x05529c9e,
333 			  0x3f408c74, 0x3f6fb805, 0x04b2ac96,
334 			  0x3f80ac7e, 0x3f8fb800, 0x0402ac8e },
335 	},
336 	{ 0x3000, {
337 			  0x3ef0003a, 0x3ef0003a, 0x084210a6,
338 			  0x3ef01045, 0x3effec32, 0x07b228a7,
339 			  0x3f00284e, 0x3f0fdc29, 0x073244a4,
340 			  0x3f104058, 0x3f0fd420, 0x06a258a2,
341 			  0x3f305c62, 0x3f2fc818, 0x0612689d,
342 			  0x3f508069, 0x3f3fc011, 0x05728496,
343 			  0x3f80a072, 0x3f4fc00a, 0x04d28c90,
344 			  0x3fc0c07b, 0x3f6fbc04, 0x04429088 },
345 	},
346 	{ 0x3200, {
347 			  0x3f00103e, 0x3f00103e, 0x07f1fc9e,
348 			  0x3f102447, 0x3f000035, 0x0782149d,
349 			  0x3f203c4f, 0x3f0ff02c, 0x07122c9c,
350 			  0x3f405458, 0x3f0fe424, 0x06924099,
351 			  0x3f607061, 0x3f1fd41d, 0x06024c97,
352 			  0x3f909068, 0x3f2fcc16, 0x05726490,
353 			  0x3fc0b070, 0x3f3fc80f, 0x04f26c8a,
354 			  0x0000d077, 0x3f4fc409, 0x04627484 },
355 	},
356 	{ 0x3400, {
357 			  0x3f202040, 0x3f202040, 0x07a1e898,
358 			  0x3f303449, 0x3f100c38, 0x0741fc98,
359 			  0x3f504c50, 0x3f10002f, 0x06e21495,
360 			  0x3f706459, 0x3f1ff028, 0x06722492,
361 			  0x3fa08060, 0x3f1fe421, 0x05f2348f,
362 			  0x3fd09c67, 0x3f1fdc19, 0x05824c89,
363 			  0x0000bc6e, 0x3f2fd014, 0x04f25086,
364 			  0x0040dc74, 0x3f3fcc0d, 0x04825c7f },
365 	},
366 	{ 0x3600, {
367 			  0x3f403042, 0x3f403042, 0x0761d890,
368 			  0x3f504848, 0x3f301c3b, 0x0701f090,
369 			  0x3f805c50, 0x3f200c33, 0x06a2008f,
370 			  0x3fa07458, 0x3f10002b, 0x06520c8d,
371 			  0x3fd0905e, 0x3f1ff424, 0x05e22089,
372 			  0x0000ac65, 0x3f1fe81d, 0x05823483,
373 			  0x0030cc6a, 0x3f2fdc18, 0x04f23c81,
374 			  0x0080e871, 0x3f2fd412, 0x0482407c },
375 	},
376 	{ 0x3800, {
377 			  0x3f604043, 0x3f604043, 0x0721c88a,
378 			  0x3f80544a, 0x3f502c3c, 0x06d1d88a,
379 			  0x3fb06851, 0x3f301c35, 0x0681e889,
380 			  0x3fd08456, 0x3f30082f, 0x0611fc88,
381 			  0x00009c5d, 0x3f200027, 0x05d20884,
382 			  0x0030b863, 0x3f2ff421, 0x05621880,
383 			  0x0070d468, 0x3f2fe81b, 0x0502247c,
384 			  0x00c0ec6f, 0x3f2fe015, 0x04a22877 },
385 	},
386 	{ 0x3a00, {
387 			  0x3f904c44, 0x3f904c44, 0x06e1b884,
388 			  0x3fb0604a, 0x3f70383e, 0x0691c885,
389 			  0x3fe07451, 0x3f502c36, 0x0661d483,
390 			  0x00009055, 0x3f401831, 0x0601ec81,
391 			  0x0030a85b, 0x3f300c2a, 0x05b1f480,
392 			  0x0070c061, 0x3f300024, 0x0562047a,
393 			  0x00b0d867, 0x3f3ff41e, 0x05020c77,
394 			  0x00f0f46b, 0x3f2fec19, 0x04a21474 },
395 	},
396 	{ 0x3c00, {
397 			  0x3fb05c43, 0x3fb05c43, 0x06c1b07e,
398 			  0x3fe06c4b, 0x3f902c3f, 0x0681c081,
399 			  0x0000844f, 0x3f703838, 0x0631cc7d,
400 			  0x00309855, 0x3f602433, 0x05d1d47e,
401 			  0x0060b459, 0x3f50142e, 0x0581e47b,
402 			  0x00a0c85f, 0x3f400828, 0x0531f078,
403 			  0x00e0e064, 0x3f300021, 0x0501fc73,
404 			  0x00b0fc6a, 0x3f3ff41d, 0x04a20873 },
405 	},
406 	{ 0x3e00, {
407 			  0x3fe06444, 0x3fe06444, 0x0681a07a,
408 			  0x00007849, 0x3fc0503f, 0x0641b07a,
409 			  0x0020904d, 0x3fa0403a, 0x05f1c07a,
410 			  0x0060a453, 0x3f803034, 0x05c1c878,
411 			  0x0090b858, 0x3f70202f, 0x0571d477,
412 			  0x00d0d05d, 0x3f501829, 0x0531e073,
413 			  0x0110e462, 0x3f500825, 0x04e1e471,
414 			  0x01510065, 0x3f40001f, 0x04a1f06d },
415 	},
416 	{ 0x4000, {
417 			  0x00007044, 0x00007044, 0x06519476,
418 			  0x00208448, 0x3fe05c3f, 0x0621a476,
419 			  0x0050984d, 0x3fc04c3a, 0x05e1b075,
420 			  0x0080ac52, 0x3fa03c35, 0x05a1b875,
421 			  0x00c0c056, 0x3f803030, 0x0561c473,
422 			  0x0100d45b, 0x3f70202b, 0x0521d46f,
423 			  0x0140e860, 0x3f601427, 0x04d1d46e,
424 			  0x01810064, 0x3f500822, 0x0491dc6b },
425 	},
426 	{ 0x5000, {
427 			  0x0110a442, 0x0110a442, 0x0551545e,
428 			  0x0140b045, 0x00e0983f, 0x0531585f,
429 			  0x0160c047, 0x00c08c3c, 0x0511645e,
430 			  0x0190cc4a, 0x00908039, 0x04f1685f,
431 			  0x01c0dc4c, 0x00707436, 0x04d1705e,
432 			  0x0200e850, 0x00506833, 0x04b1785b,
433 			  0x0230f453, 0x00305c30, 0x0491805a,
434 			  0x02710056, 0x0010542d, 0x04718059 },
435 	},
436 	{ 0x6000, {
437 			  0x01c0bc40, 0x01c0bc40, 0x04c13052,
438 			  0x01e0c841, 0x01a0b43d, 0x04c13851,
439 			  0x0210cc44, 0x0180a83c, 0x04a13453,
440 			  0x0230d845, 0x0160a03a, 0x04913c52,
441 			  0x0260e047, 0x01409838, 0x04714052,
442 			  0x0280ec49, 0x01208c37, 0x04514c50,
443 			  0x02b0f44b, 0x01008435, 0x04414c50,
444 			  0x02d1004c, 0x00e07c33, 0x0431544f },
445 	},
446 	{ 0x7000, {
447 			  0x0230c83e, 0x0230c83e, 0x04711c4c,
448 			  0x0250d03f, 0x0210c43c, 0x0471204b,
449 			  0x0270d840, 0x0200b83c, 0x0451244b,
450 			  0x0290dc42, 0x01e0b43a, 0x0441244c,
451 			  0x02b0e443, 0x01c0b038, 0x0441284b,
452 			  0x02d0ec44, 0x01b0a438, 0x0421304a,
453 			  0x02f0f445, 0x0190a036, 0x04213449,
454 			  0x0310f847, 0x01709c34, 0x04213848 },
455 	},
456 	{ 0x8000, {
457 			  0x0280d03d, 0x0280d03d, 0x04310c48,
458 			  0x02a0d43e, 0x0270c83c, 0x04311047,
459 			  0x02b0dc3e, 0x0250c83a, 0x04311447,
460 			  0x02d0e040, 0x0240c03a, 0x04211446,
461 			  0x02e0e840, 0x0220bc39, 0x04111847,
462 			  0x0300e842, 0x0210b438, 0x04012445,
463 			  0x0310f043, 0x0200b037, 0x04012045,
464 			  0x0330f444, 0x01e0ac36, 0x03f12445 },
465 	},
466 	{ 0xefff, {
467 			  0x0340dc3a, 0x0340dc3a, 0x03b0ec40,
468 			  0x0340e03a, 0x0330e039, 0x03c0f03e,
469 			  0x0350e03b, 0x0330dc39, 0x03c0ec3e,
470 			  0x0350e43a, 0x0320dc38, 0x03c0f43e,
471 			  0x0360e43b, 0x0320d839, 0x03b0f03e,
472 			  0x0360e83b, 0x0310d838, 0x03c0fc3b,
473 			  0x0370e83b, 0x0310d439, 0x03a0f83d,
474 			  0x0370e83c, 0x0300d438, 0x03b0fc3c },
475 	}
476 };
477 
rvin_set_coeff(struct rvin_dev * vin,unsigned short xs)478 static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs)
479 {
480 	int i;
481 	const struct vin_coeff *p_prev_set = NULL;
482 	const struct vin_coeff *p_set = NULL;
483 
484 	/* Look for suitable coefficient values */
485 	for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
486 		p_prev_set = p_set;
487 		p_set = &vin_coeff_set[i];
488 
489 		if (xs < p_set->xs_value)
490 			break;
491 	}
492 
493 	/* Use previous value if its XS value is closer */
494 	if (p_prev_set &&
495 	    xs - p_prev_set->xs_value < p_set->xs_value - xs)
496 		p_set = p_prev_set;
497 
498 	/* Set coefficient registers */
499 	rvin_write(vin, p_set->coeff_set[0], VNC1A_REG);
500 	rvin_write(vin, p_set->coeff_set[1], VNC1B_REG);
501 	rvin_write(vin, p_set->coeff_set[2], VNC1C_REG);
502 
503 	rvin_write(vin, p_set->coeff_set[3], VNC2A_REG);
504 	rvin_write(vin, p_set->coeff_set[4], VNC2B_REG);
505 	rvin_write(vin, p_set->coeff_set[5], VNC2C_REG);
506 
507 	rvin_write(vin, p_set->coeff_set[6], VNC3A_REG);
508 	rvin_write(vin, p_set->coeff_set[7], VNC3B_REG);
509 	rvin_write(vin, p_set->coeff_set[8], VNC3C_REG);
510 
511 	rvin_write(vin, p_set->coeff_set[9], VNC4A_REG);
512 	rvin_write(vin, p_set->coeff_set[10], VNC4B_REG);
513 	rvin_write(vin, p_set->coeff_set[11], VNC4C_REG);
514 
515 	rvin_write(vin, p_set->coeff_set[12], VNC5A_REG);
516 	rvin_write(vin, p_set->coeff_set[13], VNC5B_REG);
517 	rvin_write(vin, p_set->coeff_set[14], VNC5C_REG);
518 
519 	rvin_write(vin, p_set->coeff_set[15], VNC6A_REG);
520 	rvin_write(vin, p_set->coeff_set[16], VNC6B_REG);
521 	rvin_write(vin, p_set->coeff_set[17], VNC6C_REG);
522 
523 	rvin_write(vin, p_set->coeff_set[18], VNC7A_REG);
524 	rvin_write(vin, p_set->coeff_set[19], VNC7B_REG);
525 	rvin_write(vin, p_set->coeff_set[20], VNC7C_REG);
526 
527 	rvin_write(vin, p_set->coeff_set[21], VNC8A_REG);
528 	rvin_write(vin, p_set->coeff_set[22], VNC8B_REG);
529 	rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
530 }
531 
rvin_crop_scale_comp_gen2(struct rvin_dev * vin)532 static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
533 {
534 	unsigned int crop_height;
535 	u32 xs, ys;
536 
537 	/* Set scaling coefficient */
538 	crop_height = vin->crop.height;
539 	if (V4L2_FIELD_HAS_BOTH(vin->format.field))
540 		crop_height *= 2;
541 
542 	ys = 0;
543 	if (crop_height != vin->compose.height)
544 		ys = (4096 * crop_height) / vin->compose.height;
545 	rvin_write(vin, ys, VNYS_REG);
546 
547 	xs = 0;
548 	if (vin->crop.width != vin->compose.width)
549 		xs = (4096 * vin->crop.width) / vin->compose.width;
550 
551 	/* Horizontal upscaling is up to double size */
552 	if (xs > 0 && xs < 2048)
553 		xs = 2048;
554 
555 	rvin_write(vin, xs, VNXS_REG);
556 
557 	/* Horizontal upscaling is done out by scaling down from double size */
558 	if (xs < 4096)
559 		xs *= 2;
560 
561 	rvin_set_coeff(vin, xs);
562 
563 	/* Set Start/End Pixel/Line Post-Clip */
564 	rvin_write(vin, 0, VNSPPOC_REG);
565 	rvin_write(vin, 0, VNSLPOC_REG);
566 	rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);
567 
568 	if (V4L2_FIELD_HAS_BOTH(vin->format.field))
569 		rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);
570 	else
571 		rvin_write(vin, vin->format.height - 1, VNELPOC_REG);
572 
573 	vin_dbg(vin,
574 		"Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n",
575 		vin->crop.width, vin->crop.height, vin->crop.left,
576 		vin->crop.top, ys, xs, vin->format.width, vin->format.height,
577 		0, 0);
578 }
579 
rvin_crop_scale_comp(struct rvin_dev * vin)580 void rvin_crop_scale_comp(struct rvin_dev *vin)
581 {
582 	const struct rvin_video_format *fmt;
583 	u32 stride;
584 
585 	/* Set Start/End Pixel/Line Pre-Clip */
586 	rvin_write(vin, vin->crop.left, VNSPPRC_REG);
587 	rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
588 	rvin_write(vin, vin->crop.top, VNSLPRC_REG);
589 	rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);
590 
591 	/* TODO: Add support for the UDS scaler. */
592 	if (vin->info->model != RCAR_GEN3)
593 		rvin_crop_scale_comp_gen2(vin);
594 
595 	fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
596 	stride = vin->format.bytesperline / fmt->bpp;
597 
598 	/* For RAW8 format bpp is 1, but the hardware process RAW8
599 	 * format in 2 pixel unit hence configure VNIS_REG as stride / 2.
600 	 */
601 	switch (vin->format.pixelformat) {
602 	case V4L2_PIX_FMT_SBGGR8:
603 	case V4L2_PIX_FMT_SGBRG8:
604 	case V4L2_PIX_FMT_SGRBG8:
605 	case V4L2_PIX_FMT_SRGGB8:
606 		stride /= 2;
607 		break;
608 	default:
609 		break;
610 	}
611 
612 	rvin_write(vin, stride, VNIS_REG);
613 }
614 
615 /* -----------------------------------------------------------------------------
616  * Hardware setup
617  */
618 
rvin_setup(struct rvin_dev * vin)619 static int rvin_setup(struct rvin_dev *vin)
620 {
621 	u32 vnmc, dmr, dmr2, interrupts;
622 	bool progressive = false, output_is_yuv = false, input_is_yuv = false;
623 
624 	switch (vin->format.field) {
625 	case V4L2_FIELD_TOP:
626 		vnmc = VNMC_IM_ODD;
627 		break;
628 	case V4L2_FIELD_BOTTOM:
629 		vnmc = VNMC_IM_EVEN;
630 		break;
631 	case V4L2_FIELD_INTERLACED:
632 		/* Default to TB */
633 		vnmc = VNMC_IM_FULL;
634 		/* Use BT if video standard can be read and is 60 Hz format */
635 		if (!vin->info->use_mc && vin->std & V4L2_STD_525_60)
636 			vnmc = VNMC_IM_FULL | VNMC_FOC;
637 		break;
638 	case V4L2_FIELD_INTERLACED_TB:
639 		vnmc = VNMC_IM_FULL;
640 		break;
641 	case V4L2_FIELD_INTERLACED_BT:
642 		vnmc = VNMC_IM_FULL | VNMC_FOC;
643 		break;
644 	case V4L2_FIELD_SEQ_TB:
645 	case V4L2_FIELD_SEQ_BT:
646 	case V4L2_FIELD_NONE:
647 		vnmc = VNMC_IM_ODD_EVEN;
648 		progressive = true;
649 		break;
650 	case V4L2_FIELD_ALTERNATE:
651 		vnmc = VNMC_IM_ODD_EVEN;
652 		break;
653 	default:
654 		vnmc = VNMC_IM_ODD;
655 		break;
656 	}
657 
658 	/*
659 	 * Input interface
660 	 */
661 	switch (vin->mbus_code) {
662 	case MEDIA_BUS_FMT_YUYV8_1X16:
663 		/* BT.601/BT.1358 16bit YCbCr422 */
664 		vnmc |= VNMC_INF_YUV16;
665 		input_is_yuv = true;
666 		break;
667 	case MEDIA_BUS_FMT_UYVY8_1X16:
668 		vnmc |= VNMC_INF_YUV16 | VNMC_YCAL;
669 		input_is_yuv = true;
670 		break;
671 	case MEDIA_BUS_FMT_UYVY8_2X8:
672 		/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
673 		if (!vin->is_csi &&
674 		    vin->parallel.mbus_type == V4L2_MBUS_BT656)
675 			vnmc |= VNMC_INF_YUV8_BT656;
676 		else
677 			vnmc |= VNMC_INF_YUV8_BT601;
678 
679 		input_is_yuv = true;
680 		break;
681 	case MEDIA_BUS_FMT_RGB888_1X24:
682 		vnmc |= VNMC_INF_RGB888;
683 		break;
684 	case MEDIA_BUS_FMT_UYVY10_2X10:
685 		/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
686 		if (!vin->is_csi &&
687 		    vin->parallel.mbus_type == V4L2_MBUS_BT656)
688 			vnmc |= VNMC_INF_YUV10_BT656;
689 		else
690 			vnmc |= VNMC_INF_YUV10_BT601;
691 
692 		input_is_yuv = true;
693 		break;
694 	case MEDIA_BUS_FMT_SBGGR8_1X8:
695 	case MEDIA_BUS_FMT_SGBRG8_1X8:
696 	case MEDIA_BUS_FMT_SGRBG8_1X8:
697 	case MEDIA_BUS_FMT_SRGGB8_1X8:
698 		vnmc |= VNMC_INF_RAW8;
699 		break;
700 	default:
701 		break;
702 	}
703 
704 	/* Enable VSYNC Field Toggle mode after one VSYNC input */
705 	if (vin->info->model == RCAR_GEN3)
706 		dmr2 = VNDMR2_FTEV;
707 	else
708 		dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
709 
710 	if (!vin->is_csi) {
711 		/* Hsync Signal Polarity Select */
712 		if (!(vin->parallel.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
713 			dmr2 |= VNDMR2_HPS;
714 
715 		/* Vsync Signal Polarity Select */
716 		if (!(vin->parallel.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
717 			dmr2 |= VNDMR2_VPS;
718 
719 		/* Data Enable Polarity Select */
720 		if (vin->parallel.bus.flags & V4L2_MBUS_DATA_ENABLE_LOW)
721 			dmr2 |= VNDMR2_CES;
722 
723 		switch (vin->mbus_code) {
724 		case MEDIA_BUS_FMT_UYVY8_2X8:
725 			if (vin->parallel.bus.bus_width == 8 &&
726 			    vin->parallel.bus.data_shift == 8)
727 				dmr2 |= VNDMR2_YDS;
728 			break;
729 		default:
730 			break;
731 		}
732 	}
733 
734 	/*
735 	 * Output format
736 	 */
737 	switch (vin->format.pixelformat) {
738 	case V4L2_PIX_FMT_NV12:
739 	case V4L2_PIX_FMT_NV16:
740 		rvin_write(vin,
741 			   ALIGN(vin->format.bytesperline * vin->format.height,
742 				 0x80), VNUVAOF_REG);
743 		dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ?
744 			VNDMR_DTMD_YCSEP_420 : VNDMR_DTMD_YCSEP;
745 		output_is_yuv = true;
746 		break;
747 	case V4L2_PIX_FMT_YUYV:
748 		dmr = VNDMR_BPSM;
749 		output_is_yuv = true;
750 		break;
751 	case V4L2_PIX_FMT_UYVY:
752 		dmr = 0;
753 		output_is_yuv = true;
754 		break;
755 	case V4L2_PIX_FMT_XRGB555:
756 		dmr = VNDMR_DTMD_ARGB;
757 		break;
758 	case V4L2_PIX_FMT_RGB565:
759 		dmr = 0;
760 		break;
761 	case V4L2_PIX_FMT_XBGR32:
762 		/* Note: not supported on M1 */
763 		dmr = VNDMR_EXRGB;
764 		break;
765 	case V4L2_PIX_FMT_ARGB555:
766 		dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
767 		break;
768 	case V4L2_PIX_FMT_ABGR32:
769 		dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
770 		break;
771 	case V4L2_PIX_FMT_SBGGR8:
772 	case V4L2_PIX_FMT_SGBRG8:
773 	case V4L2_PIX_FMT_SGRBG8:
774 	case V4L2_PIX_FMT_SRGGB8:
775 		dmr = 0;
776 		break;
777 	default:
778 		vin_err(vin, "Invalid pixelformat (0x%x)\n",
779 			vin->format.pixelformat);
780 		return -EINVAL;
781 	}
782 
783 	/* Always update on field change */
784 	vnmc |= VNMC_VUP;
785 
786 	/* If input and output use the same colorspace, use bypass mode */
787 	if (input_is_yuv == output_is_yuv)
788 		vnmc |= VNMC_BPS;
789 
790 	if (vin->info->model == RCAR_GEN3) {
791 		/* Select between CSI-2 and parallel input */
792 		if (vin->is_csi)
793 			vnmc &= ~VNMC_DPINE;
794 		else
795 			vnmc |= VNMC_DPINE;
796 	}
797 
798 	/* Progressive or interlaced mode */
799 	interrupts = progressive ? VNIE_FIE : VNIE_EFE;
800 
801 	/* Ack interrupts */
802 	rvin_write(vin, interrupts, VNINTS_REG);
803 	/* Enable interrupts */
804 	rvin_write(vin, interrupts, VNIE_REG);
805 	/* Start capturing */
806 	rvin_write(vin, dmr, VNDMR_REG);
807 	rvin_write(vin, dmr2, VNDMR2_REG);
808 
809 	/* Enable module */
810 	rvin_write(vin, vnmc | VNMC_ME, VNMC_REG);
811 
812 	return 0;
813 }
814 
rvin_disable_interrupts(struct rvin_dev * vin)815 static void rvin_disable_interrupts(struct rvin_dev *vin)
816 {
817 	rvin_write(vin, 0, VNIE_REG);
818 }
819 
rvin_get_interrupt_status(struct rvin_dev * vin)820 static u32 rvin_get_interrupt_status(struct rvin_dev *vin)
821 {
822 	return rvin_read(vin, VNINTS_REG);
823 }
824 
rvin_ack_interrupt(struct rvin_dev * vin)825 static void rvin_ack_interrupt(struct rvin_dev *vin)
826 {
827 	rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG);
828 }
829 
rvin_capture_active(struct rvin_dev * vin)830 static bool rvin_capture_active(struct rvin_dev *vin)
831 {
832 	return rvin_read(vin, VNMS_REG) & VNMS_CA;
833 }
834 
rvin_get_active_field(struct rvin_dev * vin,u32 vnms)835 static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
836 {
837 	if (vin->format.field == V4L2_FIELD_ALTERNATE) {
838 		/* If FS is set it is an Even field. */
839 		if (vnms & VNMS_FS)
840 			return V4L2_FIELD_BOTTOM;
841 		return V4L2_FIELD_TOP;
842 	}
843 
844 	return vin->format.field;
845 }
846 
rvin_set_slot_addr(struct rvin_dev * vin,int slot,dma_addr_t addr)847 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
848 {
849 	const struct rvin_video_format *fmt;
850 	int offsetx, offsety;
851 	dma_addr_t offset;
852 
853 	fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
854 
855 	/*
856 	 * There is no HW support for composition do the beast we can
857 	 * by modifying the buffer offset
858 	 */
859 	offsetx = vin->compose.left * fmt->bpp;
860 	offsety = vin->compose.top * vin->format.bytesperline;
861 	offset = addr + offsetx + offsety;
862 
863 	/*
864 	 * The address needs to be 128 bytes aligned. Driver should never accept
865 	 * settings that do not satisfy this in the first place...
866 	 */
867 	if (WARN_ON((offsetx | offsety | offset) & HW_BUFFER_MASK))
868 		return;
869 
870 	rvin_write(vin, offset, VNMB_REG(slot));
871 }
872 
873 /*
874  * Moves a buffer from the queue to the HW slot. If no buffer is
875  * available use the scratch buffer. The scratch buffer is never
876  * returned to userspace, its only function is to enable the capture
877  * loop to keep running.
878  */
rvin_fill_hw_slot(struct rvin_dev * vin,int slot)879 static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
880 {
881 	struct rvin_buffer *buf;
882 	struct vb2_v4l2_buffer *vbuf;
883 	dma_addr_t phys_addr;
884 	int prev;
885 
886 	/* A already populated slot shall never be overwritten. */
887 	if (WARN_ON(vin->buf_hw[slot].buffer))
888 		return;
889 
890 	prev = (slot == 0 ? HW_BUFFER_NUM : slot) - 1;
891 
892 	if (vin->buf_hw[prev].type == HALF_TOP) {
893 		vbuf = vin->buf_hw[prev].buffer;
894 		vin->buf_hw[slot].buffer = vbuf;
895 		vin->buf_hw[slot].type = HALF_BOTTOM;
896 		switch (vin->format.pixelformat) {
897 		case V4L2_PIX_FMT_NV12:
898 		case V4L2_PIX_FMT_NV16:
899 			phys_addr = vin->buf_hw[prev].phys +
900 				vin->format.sizeimage / 4;
901 			break;
902 		default:
903 			phys_addr = vin->buf_hw[prev].phys +
904 				vin->format.sizeimage / 2;
905 			break;
906 		}
907 	} else if (vin->state != RUNNING || list_empty(&vin->buf_list)) {
908 		vin->buf_hw[slot].buffer = NULL;
909 		vin->buf_hw[slot].type = FULL;
910 		phys_addr = vin->scratch_phys;
911 	} else {
912 		/* Keep track of buffer we give to HW */
913 		buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
914 		vbuf = &buf->vb;
915 		list_del_init(to_buf_list(vbuf));
916 		vin->buf_hw[slot].buffer = vbuf;
917 
918 		vin->buf_hw[slot].type =
919 			V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ?
920 			HALF_TOP : FULL;
921 
922 		/* Setup DMA */
923 		phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
924 	}
925 
926 	vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n",
927 		slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer);
928 
929 	vin->buf_hw[slot].phys = phys_addr;
930 	rvin_set_slot_addr(vin, slot, phys_addr);
931 }
932 
rvin_capture_start(struct rvin_dev * vin)933 static int rvin_capture_start(struct rvin_dev *vin)
934 {
935 	int slot, ret;
936 
937 	for (slot = 0; slot < HW_BUFFER_NUM; slot++) {
938 		vin->buf_hw[slot].buffer = NULL;
939 		vin->buf_hw[slot].type = FULL;
940 	}
941 
942 	for (slot = 0; slot < HW_BUFFER_NUM; slot++)
943 		rvin_fill_hw_slot(vin, slot);
944 
945 	rvin_crop_scale_comp(vin);
946 
947 	ret = rvin_setup(vin);
948 	if (ret)
949 		return ret;
950 
951 	vin_dbg(vin, "Starting to capture\n");
952 
953 	/* Continuous Frame Capture Mode */
954 	rvin_write(vin, VNFC_C_FRAME, VNFC_REG);
955 
956 	vin->state = STARTING;
957 
958 	return 0;
959 }
960 
rvin_capture_stop(struct rvin_dev * vin)961 static void rvin_capture_stop(struct rvin_dev *vin)
962 {
963 	/* Set continuous & single transfer off */
964 	rvin_write(vin, 0, VNFC_REG);
965 
966 	/* Disable module */
967 	rvin_write(vin, rvin_read(vin, VNMC_REG) & ~VNMC_ME, VNMC_REG);
968 }
969 
970 /* -----------------------------------------------------------------------------
971  * DMA Functions
972  */
973 
974 #define RVIN_TIMEOUT_MS 100
975 #define RVIN_RETRIES 10
976 
rvin_irq(int irq,void * data)977 static irqreturn_t rvin_irq(int irq, void *data)
978 {
979 	struct rvin_dev *vin = data;
980 	u32 int_status, vnms;
981 	int slot;
982 	unsigned int handled = 0;
983 	unsigned long flags;
984 
985 	spin_lock_irqsave(&vin->qlock, flags);
986 
987 	int_status = rvin_get_interrupt_status(vin);
988 	if (!int_status)
989 		goto done;
990 
991 	rvin_ack_interrupt(vin);
992 	handled = 1;
993 
994 	/* Nothing to do if capture status is 'STOPPED' */
995 	if (vin->state == STOPPED) {
996 		vin_dbg(vin, "IRQ while state stopped\n");
997 		goto done;
998 	}
999 
1000 	/* Prepare for capture and update state */
1001 	vnms = rvin_read(vin, VNMS_REG);
1002 	slot = (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
1003 
1004 	/*
1005 	 * To hand buffers back in a known order to userspace start
1006 	 * to capture first from slot 0.
1007 	 */
1008 	if (vin->state == STARTING) {
1009 		if (slot != 0) {
1010 			vin_dbg(vin, "Starting sync slot: %d\n", slot);
1011 			goto done;
1012 		}
1013 
1014 		vin_dbg(vin, "Capture start synced!\n");
1015 		vin->state = RUNNING;
1016 	}
1017 
1018 	/* Capture frame */
1019 	if (vin->buf_hw[slot].buffer) {
1020 		/*
1021 		 * Nothing to do but refill the hardware slot if
1022 		 * capture only filled first half of vb2 buffer.
1023 		 */
1024 		if (vin->buf_hw[slot].type == HALF_TOP) {
1025 			vin->buf_hw[slot].buffer = NULL;
1026 			rvin_fill_hw_slot(vin, slot);
1027 			goto done;
1028 		}
1029 
1030 		vin->buf_hw[slot].buffer->field =
1031 			rvin_get_active_field(vin, vnms);
1032 		vin->buf_hw[slot].buffer->sequence = vin->sequence;
1033 		vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns();
1034 		vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf,
1035 				VB2_BUF_STATE_DONE);
1036 		vin->buf_hw[slot].buffer = NULL;
1037 	} else {
1038 		/* Scratch buffer was used, dropping frame. */
1039 		vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
1040 	}
1041 
1042 	vin->sequence++;
1043 
1044 	/* Prepare for next frame */
1045 	rvin_fill_hw_slot(vin, slot);
1046 done:
1047 	spin_unlock_irqrestore(&vin->qlock, flags);
1048 
1049 	return IRQ_RETVAL(handled);
1050 }
1051 
return_unused_buffers(struct rvin_dev * vin,enum vb2_buffer_state state)1052 static void return_unused_buffers(struct rvin_dev *vin,
1053 				  enum vb2_buffer_state state)
1054 {
1055 	struct rvin_buffer *buf, *node;
1056 	unsigned long flags;
1057 
1058 	spin_lock_irqsave(&vin->qlock, flags);
1059 
1060 	list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
1061 		vb2_buffer_done(&buf->vb.vb2_buf, state);
1062 		list_del(&buf->list);
1063 	}
1064 
1065 	spin_unlock_irqrestore(&vin->qlock, flags);
1066 }
1067 
rvin_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])1068 static int rvin_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
1069 			    unsigned int *nplanes, unsigned int sizes[],
1070 			    struct device *alloc_devs[])
1071 
1072 {
1073 	struct rvin_dev *vin = vb2_get_drv_priv(vq);
1074 
1075 	/* Make sure the image size is large enough. */
1076 	if (*nplanes)
1077 		return sizes[0] < vin->format.sizeimage ? -EINVAL : 0;
1078 
1079 	*nplanes = 1;
1080 	sizes[0] = vin->format.sizeimage;
1081 
1082 	return 0;
1083 };
1084 
rvin_buffer_prepare(struct vb2_buffer * vb)1085 static int rvin_buffer_prepare(struct vb2_buffer *vb)
1086 {
1087 	struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1088 	unsigned long size = vin->format.sizeimage;
1089 
1090 	if (vb2_plane_size(vb, 0) < size) {
1091 		vin_err(vin, "buffer too small (%lu < %lu)\n",
1092 			vb2_plane_size(vb, 0), size);
1093 		return -EINVAL;
1094 	}
1095 
1096 	vb2_set_plane_payload(vb, 0, size);
1097 
1098 	return 0;
1099 }
1100 
rvin_buffer_queue(struct vb2_buffer * vb)1101 static void rvin_buffer_queue(struct vb2_buffer *vb)
1102 {
1103 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1104 	struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1105 	unsigned long flags;
1106 
1107 	spin_lock_irqsave(&vin->qlock, flags);
1108 
1109 	list_add_tail(to_buf_list(vbuf), &vin->buf_list);
1110 
1111 	spin_unlock_irqrestore(&vin->qlock, flags);
1112 }
1113 
rvin_mc_validate_format(struct rvin_dev * vin,struct v4l2_subdev * sd,struct media_pad * pad)1114 static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
1115 				   struct media_pad *pad)
1116 {
1117 	struct v4l2_subdev_format fmt = {
1118 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
1119 	};
1120 
1121 	fmt.pad = pad->index;
1122 	if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt))
1123 		return -EPIPE;
1124 
1125 	switch (fmt.format.code) {
1126 	case MEDIA_BUS_FMT_YUYV8_1X16:
1127 	case MEDIA_BUS_FMT_UYVY8_1X16:
1128 	case MEDIA_BUS_FMT_UYVY8_2X8:
1129 	case MEDIA_BUS_FMT_UYVY10_2X10:
1130 	case MEDIA_BUS_FMT_RGB888_1X24:
1131 		break;
1132 	case MEDIA_BUS_FMT_SBGGR8_1X8:
1133 		if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8)
1134 			return -EPIPE;
1135 		break;
1136 	case MEDIA_BUS_FMT_SGBRG8_1X8:
1137 		if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8)
1138 			return -EPIPE;
1139 		break;
1140 	case MEDIA_BUS_FMT_SGRBG8_1X8:
1141 		if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8)
1142 			return -EPIPE;
1143 		break;
1144 	case MEDIA_BUS_FMT_SRGGB8_1X8:
1145 		if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8)
1146 			return -EPIPE;
1147 		break;
1148 	default:
1149 		return -EPIPE;
1150 	}
1151 	vin->mbus_code = fmt.format.code;
1152 
1153 	switch (fmt.format.field) {
1154 	case V4L2_FIELD_TOP:
1155 	case V4L2_FIELD_BOTTOM:
1156 	case V4L2_FIELD_NONE:
1157 	case V4L2_FIELD_INTERLACED_TB:
1158 	case V4L2_FIELD_INTERLACED_BT:
1159 	case V4L2_FIELD_INTERLACED:
1160 	case V4L2_FIELD_SEQ_TB:
1161 	case V4L2_FIELD_SEQ_BT:
1162 		/* Supported natively */
1163 		break;
1164 	case V4L2_FIELD_ALTERNATE:
1165 		switch (vin->format.field) {
1166 		case V4L2_FIELD_TOP:
1167 		case V4L2_FIELD_BOTTOM:
1168 		case V4L2_FIELD_NONE:
1169 		case V4L2_FIELD_ALTERNATE:
1170 			break;
1171 		case V4L2_FIELD_INTERLACED_TB:
1172 		case V4L2_FIELD_INTERLACED_BT:
1173 		case V4L2_FIELD_INTERLACED:
1174 		case V4L2_FIELD_SEQ_TB:
1175 		case V4L2_FIELD_SEQ_BT:
1176 			/* Use VIN hardware to combine the two fields */
1177 			fmt.format.height *= 2;
1178 			break;
1179 		default:
1180 			return -EPIPE;
1181 		}
1182 		break;
1183 	default:
1184 		return -EPIPE;
1185 	}
1186 
1187 	if (fmt.format.width != vin->format.width ||
1188 	    fmt.format.height != vin->format.height ||
1189 	    fmt.format.code != vin->mbus_code)
1190 		return -EPIPE;
1191 
1192 	return 0;
1193 }
1194 
rvin_set_stream(struct rvin_dev * vin,int on)1195 static int rvin_set_stream(struct rvin_dev *vin, int on)
1196 {
1197 	struct media_pipeline *pipe;
1198 	struct media_device *mdev;
1199 	struct v4l2_subdev *sd;
1200 	struct media_pad *pad;
1201 	int ret;
1202 
1203 	/* No media controller used, simply pass operation to subdevice. */
1204 	if (!vin->info->use_mc) {
1205 		ret = v4l2_subdev_call(vin->parallel.subdev, video, s_stream,
1206 				       on);
1207 
1208 		return ret == -ENOIOCTLCMD ? 0 : ret;
1209 	}
1210 
1211 	pad = media_entity_remote_pad(&vin->pad);
1212 	if (!pad)
1213 		return -EPIPE;
1214 
1215 	sd = media_entity_to_v4l2_subdev(pad->entity);
1216 
1217 	if (!on) {
1218 		media_pipeline_stop(&vin->vdev.entity);
1219 		return v4l2_subdev_call(sd, video, s_stream, 0);
1220 	}
1221 
1222 	ret = rvin_mc_validate_format(vin, sd, pad);
1223 	if (ret)
1224 		return ret;
1225 
1226 	/*
1227 	 * The graph lock needs to be taken to protect concurrent
1228 	 * starts of multiple VIN instances as they might share
1229 	 * a common subdevice down the line and then should use
1230 	 * the same pipe.
1231 	 */
1232 	mdev = vin->vdev.entity.graph_obj.mdev;
1233 	mutex_lock(&mdev->graph_mutex);
1234 	pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe;
1235 	ret = __media_pipeline_start(&vin->vdev.entity, pipe);
1236 	mutex_unlock(&mdev->graph_mutex);
1237 	if (ret)
1238 		return ret;
1239 
1240 	ret = v4l2_subdev_call(sd, video, s_stream, 1);
1241 	if (ret == -ENOIOCTLCMD)
1242 		ret = 0;
1243 	if (ret)
1244 		media_pipeline_stop(&vin->vdev.entity);
1245 
1246 	return ret;
1247 }
1248 
rvin_start_streaming(struct rvin_dev * vin)1249 int rvin_start_streaming(struct rvin_dev *vin)
1250 {
1251 	unsigned long flags;
1252 	int ret;
1253 
1254 	ret = rvin_set_stream(vin, 1);
1255 	if (ret)
1256 		return ret;
1257 
1258 	spin_lock_irqsave(&vin->qlock, flags);
1259 
1260 	vin->sequence = 0;
1261 
1262 	ret = rvin_capture_start(vin);
1263 	if (ret)
1264 		rvin_set_stream(vin, 0);
1265 
1266 	spin_unlock_irqrestore(&vin->qlock, flags);
1267 
1268 	return ret;
1269 }
1270 
rvin_start_streaming_vq(struct vb2_queue * vq,unsigned int count)1271 static int rvin_start_streaming_vq(struct vb2_queue *vq, unsigned int count)
1272 {
1273 	struct rvin_dev *vin = vb2_get_drv_priv(vq);
1274 	int ret = -ENOMEM;
1275 
1276 	/* Allocate scratch buffer. */
1277 	vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
1278 					  &vin->scratch_phys, GFP_KERNEL);
1279 	if (!vin->scratch)
1280 		goto err_scratch;
1281 
1282 	ret = rvin_start_streaming(vin);
1283 	if (ret)
1284 		goto err_start;
1285 
1286 	return 0;
1287 err_start:
1288 	dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
1289 			  vin->scratch_phys);
1290 err_scratch:
1291 	return_unused_buffers(vin, VB2_BUF_STATE_QUEUED);
1292 
1293 	return ret;
1294 }
1295 
rvin_stop_streaming(struct rvin_dev * vin)1296 void rvin_stop_streaming(struct rvin_dev *vin)
1297 {
1298 	unsigned int i, retries;
1299 	unsigned long flags;
1300 	bool buffersFreed;
1301 
1302 	spin_lock_irqsave(&vin->qlock, flags);
1303 
1304 	if (vin->state == STOPPED) {
1305 		spin_unlock_irqrestore(&vin->qlock, flags);
1306 		return;
1307 	}
1308 
1309 	vin->state = STOPPING;
1310 
1311 	/* Wait until only scratch buffer is used, max 3 interrupts. */
1312 	retries = 0;
1313 	while (retries++ < RVIN_RETRIES) {
1314 		buffersFreed = true;
1315 		for (i = 0; i < HW_BUFFER_NUM; i++)
1316 			if (vin->buf_hw[i].buffer)
1317 				buffersFreed = false;
1318 
1319 		if (buffersFreed)
1320 			break;
1321 
1322 		spin_unlock_irqrestore(&vin->qlock, flags);
1323 		msleep(RVIN_TIMEOUT_MS);
1324 		spin_lock_irqsave(&vin->qlock, flags);
1325 	}
1326 
1327 	/* Wait for streaming to stop */
1328 	retries = 0;
1329 	while (retries++ < RVIN_RETRIES) {
1330 
1331 		rvin_capture_stop(vin);
1332 
1333 		/* Check if HW is stopped */
1334 		if (!rvin_capture_active(vin)) {
1335 			vin->state = STOPPED;
1336 			break;
1337 		}
1338 
1339 		spin_unlock_irqrestore(&vin->qlock, flags);
1340 		msleep(RVIN_TIMEOUT_MS);
1341 		spin_lock_irqsave(&vin->qlock, flags);
1342 	}
1343 
1344 	if (!buffersFreed || vin->state != STOPPED) {
1345 		/*
1346 		 * If this happens something have gone horribly wrong.
1347 		 * Set state to stopped to prevent the interrupt handler
1348 		 * to make things worse...
1349 		 */
1350 		vin_err(vin, "Failed stop HW, something is seriously broken\n");
1351 		vin->state = STOPPED;
1352 	}
1353 
1354 	spin_unlock_irqrestore(&vin->qlock, flags);
1355 
1356 	rvin_set_stream(vin, 0);
1357 
1358 	/* disable interrupts */
1359 	rvin_disable_interrupts(vin);
1360 }
1361 
rvin_stop_streaming_vq(struct vb2_queue * vq)1362 static void rvin_stop_streaming_vq(struct vb2_queue *vq)
1363 {
1364 	struct rvin_dev *vin = vb2_get_drv_priv(vq);
1365 
1366 	rvin_stop_streaming(vin);
1367 
1368 	/* Free scratch buffer. */
1369 	dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
1370 			  vin->scratch_phys);
1371 
1372 	return_unused_buffers(vin, VB2_BUF_STATE_ERROR);
1373 }
1374 
1375 static const struct vb2_ops rvin_qops = {
1376 	.queue_setup		= rvin_queue_setup,
1377 	.buf_prepare		= rvin_buffer_prepare,
1378 	.buf_queue		= rvin_buffer_queue,
1379 	.start_streaming	= rvin_start_streaming_vq,
1380 	.stop_streaming		= rvin_stop_streaming_vq,
1381 	.wait_prepare		= vb2_ops_wait_prepare,
1382 	.wait_finish		= vb2_ops_wait_finish,
1383 };
1384 
rvin_dma_unregister(struct rvin_dev * vin)1385 void rvin_dma_unregister(struct rvin_dev *vin)
1386 {
1387 	mutex_destroy(&vin->lock);
1388 
1389 	v4l2_device_unregister(&vin->v4l2_dev);
1390 }
1391 
rvin_dma_register(struct rvin_dev * vin,int irq)1392 int rvin_dma_register(struct rvin_dev *vin, int irq)
1393 {
1394 	struct vb2_queue *q = &vin->queue;
1395 	int i, ret;
1396 
1397 	/* Initialize the top-level structure */
1398 	ret = v4l2_device_register(vin->dev, &vin->v4l2_dev);
1399 	if (ret)
1400 		return ret;
1401 
1402 	mutex_init(&vin->lock);
1403 	INIT_LIST_HEAD(&vin->buf_list);
1404 
1405 	spin_lock_init(&vin->qlock);
1406 
1407 	vin->state = STOPPED;
1408 
1409 	for (i = 0; i < HW_BUFFER_NUM; i++)
1410 		vin->buf_hw[i].buffer = NULL;
1411 
1412 	/* buffer queue */
1413 	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1414 	q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1415 	q->lock = &vin->lock;
1416 	q->drv_priv = vin;
1417 	q->buf_struct_size = sizeof(struct rvin_buffer);
1418 	q->ops = &rvin_qops;
1419 	q->mem_ops = &vb2_dma_contig_memops;
1420 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1421 	q->min_buffers_needed = 4;
1422 	q->dev = vin->dev;
1423 
1424 	ret = vb2_queue_init(q);
1425 	if (ret < 0) {
1426 		vin_err(vin, "failed to initialize VB2 queue\n");
1427 		goto error;
1428 	}
1429 
1430 	/* irq */
1431 	ret = devm_request_irq(vin->dev, irq, rvin_irq, IRQF_SHARED,
1432 			       KBUILD_MODNAME, vin);
1433 	if (ret) {
1434 		vin_err(vin, "failed to request irq\n");
1435 		goto error;
1436 	}
1437 
1438 	return 0;
1439 error:
1440 	rvin_dma_unregister(vin);
1441 
1442 	return ret;
1443 }
1444 
1445 /* -----------------------------------------------------------------------------
1446  * Gen3 CHSEL manipulation
1447  */
1448 
1449 /*
1450  * There is no need to have locking around changing the routing
1451  * as it's only possible to do so when no VIN in the group is
1452  * streaming so nothing can race with the VNMC register.
1453  */
rvin_set_channel_routing(struct rvin_dev * vin,u8 chsel)1454 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
1455 {
1456 	const struct rvin_group_route *route;
1457 	u32 ifmd = 0;
1458 	u32 vnmc;
1459 	int ret;
1460 
1461 	ret = pm_runtime_get_sync(vin->dev);
1462 	if (ret < 0) {
1463 		pm_runtime_put_noidle(vin->dev);
1464 		return ret;
1465 	}
1466 
1467 	/* Make register writes take effect immediately. */
1468 	vnmc = rvin_read(vin, VNMC_REG);
1469 	rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
1470 
1471 	/*
1472 	 * Set data expansion mode to "pad with 0s" by inspecting the routes
1473 	 * table to find out which bit fields are available in the IFMD
1474 	 * register. IFMD_DES1 controls data expansion mode for CSI20/21,
1475 	 * IFMD_DES0 controls data expansion mode for CSI40/41.
1476 	 */
1477 	for (route = vin->info->routes; route->mask; route++) {
1478 		if (route->csi == RVIN_CSI20 || route->csi == RVIN_CSI21)
1479 			ifmd |= VNCSI_IFMD_DES1;
1480 		else
1481 			ifmd |= VNCSI_IFMD_DES0;
1482 
1483 		if (ifmd == (VNCSI_IFMD_DES0 | VNCSI_IFMD_DES1))
1484 			break;
1485 	}
1486 
1487 	if (ifmd) {
1488 		ifmd |= VNCSI_IFMD_CSI_CHSEL(chsel);
1489 		rvin_write(vin, ifmd, VNCSI_IFMD_REG);
1490 	}
1491 
1492 	vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
1493 
1494 	vin->chsel = chsel;
1495 
1496 	/* Restore VNMC. */
1497 	rvin_write(vin, vnmc, VNMC_REG);
1498 
1499 	pm_runtime_put(vin->dev);
1500 
1501 	return 0;
1502 }
1503 
rvin_set_alpha(struct rvin_dev * vin,unsigned int alpha)1504 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
1505 {
1506 	unsigned long flags;
1507 	u32 dmr;
1508 
1509 	spin_lock_irqsave(&vin->qlock, flags);
1510 
1511 	vin->alpha = alpha;
1512 
1513 	if (vin->state == STOPPED)
1514 		goto out;
1515 
1516 	switch (vin->format.pixelformat) {
1517 	case V4L2_PIX_FMT_ARGB555:
1518 		dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
1519 		if (vin->alpha)
1520 			dmr |= VNDMR_ABIT;
1521 		break;
1522 	case V4L2_PIX_FMT_ABGR32:
1523 		dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
1524 		dmr |= VNDMR_A8BIT(vin->alpha);
1525 		break;
1526 	default:
1527 		goto out;
1528 	}
1529 
1530 	rvin_write(vin, dmr,  VNDMR_REG);
1531 out:
1532 	spin_unlock_irqrestore(&vin->qlock, flags);
1533 }
1534