1 /*
2  * SoC-camera host driver for Renesas R-Car VIN unit
3  *
4  * Copyright (C) 2011-2013 Renesas Solutions Corp.
5  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
6  *
7  * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
8  *
9  * Copyright (C) 2008 Magnus Damm
10  *
11  * This program is free software; you can redistribute  it and/or modify it
12  * under  the terms of  the GNU General  Public License as published by the
13  * Free Software Foundation;  either version 2 of the  License, or (at your
14  * option) any later version.
15  */
16 
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
19 #include <linux/io.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/of.h>
23 #include <linux/of_device.h>
24 #include <linux/platform_data/camera-rcar.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/slab.h>
28 #include <linux/videodev2.h>
29 
30 #include <media/soc_camera.h>
31 #include <media/soc_mediabus.h>
32 #include <media/v4l2-common.h>
33 #include <media/v4l2-dev.h>
34 #include <media/v4l2-device.h>
35 #include <media/v4l2-mediabus.h>
36 #include <media/v4l2-of.h>
37 #include <media/v4l2-subdev.h>
38 #include <media/videobuf2-dma-contig.h>
39 
40 #include "soc_scale_crop.h"
41 
42 #define DRV_NAME "rcar_vin"
43 
44 /* Register offsets for R-Car VIN */
45 #define VNMC_REG	0x00	/* Video n Main Control Register */
46 #define VNMS_REG	0x04	/* Video n Module Status Register */
47 #define VNFC_REG	0x08	/* Video n Frame Capture Register */
48 #define VNSLPRC_REG	0x0C	/* Video n Start Line Pre-Clip Register */
49 #define VNELPRC_REG	0x10	/* Video n End Line Pre-Clip Register */
50 #define VNSPPRC_REG	0x14	/* Video n Start Pixel Pre-Clip Register */
51 #define VNEPPRC_REG	0x18	/* Video n End Pixel Pre-Clip Register */
52 #define VNSLPOC_REG	0x1C	/* Video n Start Line Post-Clip Register */
53 #define VNELPOC_REG	0x20	/* Video n End Line Post-Clip Register */
54 #define VNSPPOC_REG	0x24	/* Video n Start Pixel Post-Clip Register */
55 #define VNEPPOC_REG	0x28	/* Video n End Pixel Post-Clip Register */
56 #define VNIS_REG	0x2C	/* Video n Image Stride Register */
57 #define VNMB_REG(m)	(0x30 + ((m) << 2)) /* Video n Memory Base m Register */
58 #define VNIE_REG	0x40	/* Video n Interrupt Enable Register */
59 #define VNINTS_REG	0x44	/* Video n Interrupt Status Register */
60 #define VNSI_REG	0x48	/* Video n Scanline Interrupt Register */
61 #define VNMTC_REG	0x4C	/* Video n Memory Transfer Control Register */
62 #define VNYS_REG	0x50	/* Video n Y Scale Register */
63 #define VNXS_REG	0x54	/* Video n X Scale Register */
64 #define VNDMR_REG	0x58	/* Video n Data Mode Register */
65 #define VNDMR2_REG	0x5C	/* Video n Data Mode Register 2 */
66 #define VNUVAOF_REG	0x60	/* Video n UV Address Offset Register */
67 #define VNC1A_REG	0x80	/* Video n Coefficient Set C1A Register */
68 #define VNC1B_REG	0x84	/* Video n Coefficient Set C1B Register */
69 #define VNC1C_REG	0x88	/* Video n Coefficient Set C1C Register */
70 #define VNC2A_REG	0x90	/* Video n Coefficient Set C2A Register */
71 #define VNC2B_REG	0x94	/* Video n Coefficient Set C2B Register */
72 #define VNC2C_REG	0x98	/* Video n Coefficient Set C2C Register */
73 #define VNC3A_REG	0xA0	/* Video n Coefficient Set C3A Register */
74 #define VNC3B_REG	0xA4	/* Video n Coefficient Set C3B Register */
75 #define VNC3C_REG	0xA8	/* Video n Coefficient Set C3C Register */
76 #define VNC4A_REG	0xB0	/* Video n Coefficient Set C4A Register */
77 #define VNC4B_REG	0xB4	/* Video n Coefficient Set C4B Register */
78 #define VNC4C_REG	0xB8	/* Video n Coefficient Set C4C Register */
79 #define VNC5A_REG	0xC0	/* Video n Coefficient Set C5A Register */
80 #define VNC5B_REG	0xC4	/* Video n Coefficient Set C5B Register */
81 #define VNC5C_REG	0xC8	/* Video n Coefficient Set C5C Register */
82 #define VNC6A_REG	0xD0	/* Video n Coefficient Set C6A Register */
83 #define VNC6B_REG	0xD4	/* Video n Coefficient Set C6B Register */
84 #define VNC6C_REG	0xD8	/* Video n Coefficient Set C6C Register */
85 #define VNC7A_REG	0xE0	/* Video n Coefficient Set C7A Register */
86 #define VNC7B_REG	0xE4	/* Video n Coefficient Set C7B Register */
87 #define VNC7C_REG	0xE8	/* Video n Coefficient Set C7C Register */
88 #define VNC8A_REG	0xF0	/* Video n Coefficient Set C8A Register */
89 #define VNC8B_REG	0xF4	/* Video n Coefficient Set C8B Register */
90 #define VNC8C_REG	0xF8	/* Video n Coefficient Set C8C Register */
91 
92 /* Register bit fields for R-Car VIN */
93 /* Video n Main Control Register bits */
94 #define VNMC_FOC		(1 << 21)
95 #define VNMC_YCAL		(1 << 19)
96 #define VNMC_INF_YUV8_BT656	(0 << 16)
97 #define VNMC_INF_YUV8_BT601	(1 << 16)
98 #define VNMC_INF_YUV10_BT656	(2 << 16)
99 #define VNMC_INF_YUV10_BT601	(3 << 16)
100 #define VNMC_INF_YUV16		(5 << 16)
101 #define VNMC_VUP		(1 << 10)
102 #define VNMC_IM_ODD		(0 << 3)
103 #define VNMC_IM_ODD_EVEN	(1 << 3)
104 #define VNMC_IM_EVEN		(2 << 3)
105 #define VNMC_IM_FULL		(3 << 3)
106 #define VNMC_BPS		(1 << 1)
107 #define VNMC_ME			(1 << 0)
108 
109 /* Video n Module Status Register bits */
110 #define VNMS_FBS_MASK		(3 << 3)
111 #define VNMS_FBS_SHIFT		3
112 #define VNMS_AV			(1 << 1)
113 #define VNMS_CA			(1 << 0)
114 
115 /* Video n Frame Capture Register bits */
116 #define VNFC_C_FRAME		(1 << 1)
117 #define VNFC_S_FRAME		(1 << 0)
118 
119 /* Video n Interrupt Enable Register bits */
120 #define VNIE_FIE		(1 << 4)
121 #define VNIE_EFE		(1 << 1)
122 
123 /* Video n Data Mode Register bits */
124 #define VNDMR_EXRGB		(1 << 8)
125 #define VNDMR_BPSM		(1 << 4)
126 #define VNDMR_DTMD_YCSEP	(1 << 1)
127 #define VNDMR_DTMD_ARGB1555	(1 << 0)
128 
129 /* Video n Data Mode Register 2 bits */
130 #define VNDMR2_VPS		(1 << 30)
131 #define VNDMR2_HPS		(1 << 29)
132 #define VNDMR2_FTEV		(1 << 17)
133 #define VNDMR2_VLV(n)		((n & 0xf) << 12)
134 
135 #define VIN_MAX_WIDTH		2048
136 #define VIN_MAX_HEIGHT		2048
137 
138 #define TIMEOUT_MS		100
139 
140 enum chip_id {
141 	RCAR_GEN2,
142 	RCAR_H1,
143 	RCAR_M1,
144 	RCAR_E1,
145 };
146 
147 struct vin_coeff {
148 	unsigned short xs_value;
149 	u32 coeff_set[24];
150 };
151 
152 static const struct vin_coeff vin_coeff_set[] = {
153 	{ 0x0000, {
154 		0x00000000,		0x00000000,		0x00000000,
155 		0x00000000,		0x00000000,		0x00000000,
156 		0x00000000,		0x00000000,		0x00000000,
157 		0x00000000,		0x00000000,		0x00000000,
158 		0x00000000,		0x00000000,		0x00000000,
159 		0x00000000,		0x00000000,		0x00000000,
160 		0x00000000,		0x00000000,		0x00000000,
161 		0x00000000,		0x00000000,		0x00000000 },
162 	},
163 	{ 0x1000, {
164 		0x000fa400,		0x000fa400,		0x09625902,
165 		0x000003f8,		0x00000403,		0x3de0d9f0,
166 		0x001fffed,		0x00000804,		0x3cc1f9c3,
167 		0x001003de,		0x00000c01,		0x3cb34d7f,
168 		0x002003d2,		0x00000c00,		0x3d24a92d,
169 		0x00200bca,		0x00000bff,		0x3df600d2,
170 		0x002013cc,		0x000007ff,		0x3ed70c7e,
171 		0x00100fde,		0x00000000,		0x3f87c036 },
172 	},
173 	{ 0x1200, {
174 		0x002ffff1,		0x002ffff1,		0x02a0a9c8,
175 		0x002003e7,		0x001ffffa,		0x000185bc,
176 		0x002007dc,		0x000003ff,		0x3e52859c,
177 		0x00200bd4,		0x00000002,		0x3d53996b,
178 		0x00100fd0,		0x00000403,		0x3d04ad2d,
179 		0x00000bd5,		0x00000403,		0x3d35ace7,
180 		0x3ff003e4,		0x00000801,		0x3dc674a1,
181 		0x3fffe800,		0x00000800,		0x3e76f461 },
182 	},
183 	{ 0x1400, {
184 		0x00100be3,		0x00100be3,		0x04d1359a,
185 		0x00000fdb,		0x002003ed,		0x0211fd93,
186 		0x00000fd6,		0x002003f4,		0x0002d97b,
187 		0x000007d6,		0x002ffffb,		0x3e93b956,
188 		0x3ff003da,		0x001003ff,		0x3db49926,
189 		0x3fffefe9,		0x00100001,		0x3d655cee,
190 		0x3fffd400,		0x00000003,		0x3d65f4b6,
191 		0x000fb421,		0x00000402,		0x3dc6547e },
192 	},
193 	{ 0x1600, {
194 		0x00000bdd,		0x00000bdd,		0x06519578,
195 		0x3ff007da,		0x00000be3,		0x03c24973,
196 		0x3ff003d9,		0x00000be9,		0x01b30d5f,
197 		0x3ffff7df,		0x001003f1,		0x0003c542,
198 		0x000fdfec,		0x001003f7,		0x3ec4711d,
199 		0x000fc400,		0x002ffffd,		0x3df504f1,
200 		0x001fa81a,		0x002ffc00,		0x3d957cc2,
201 		0x002f8c3c,		0x00100000,		0x3db5c891 },
202 	},
203 	{ 0x1800, {
204 		0x3ff003dc,		0x3ff003dc,		0x0791e558,
205 		0x000ff7dd,		0x3ff007de,		0x05328554,
206 		0x000fe7e3,		0x3ff00be2,		0x03232546,
207 		0x000fd7ee,		0x000007e9,		0x0143bd30,
208 		0x001fb800,		0x000007ee,		0x00044511,
209 		0x002fa015,		0x000007f4,		0x3ef4bcee,
210 		0x002f8832,		0x001003f9,		0x3e4514c7,
211 		0x001f7853,		0x001003fd,		0x3de54c9f },
212 	},
213 	{ 0x1a00, {
214 		0x000fefe0,		0x000fefe0,		0x08721d3c,
215 		0x001fdbe7,		0x000ffbde,		0x0652a139,
216 		0x001fcbf0,		0x000003df,		0x0463292e,
217 		0x002fb3ff,		0x3ff007e3,		0x0293a91d,
218 		0x002f9c12,		0x3ff00be7,		0x01241905,
219 		0x001f8c29,		0x000007ed,		0x3fe470eb,
220 		0x000f7c46,		0x000007f2,		0x3f04b8ca,
221 		0x3fef7865,		0x000007f6,		0x3e74e4a8 },
222 	},
223 	{ 0x1c00, {
224 		0x001fd3e9,		0x001fd3e9,		0x08f23d26,
225 		0x002fbff3,		0x001fe3e4,		0x0712ad23,
226 		0x002fa800,		0x000ff3e0,		0x05631d1b,
227 		0x001f9810,		0x000ffbe1,		0x03b3890d,
228 		0x000f8c23,		0x000003e3,		0x0233e8fa,
229 		0x3fef843b,		0x000003e7,		0x00f430e4,
230 		0x3fbf8456,		0x3ff00bea,		0x00046cc8,
231 		0x3f8f8c72,		0x3ff00bef,		0x3f3490ac },
232 	},
233 	{ 0x1e00, {
234 		0x001fbbf4,		0x001fbbf4,		0x09425112,
235 		0x001fa800,		0x002fc7ed,		0x0792b110,
236 		0x000f980e,		0x001fdbe6,		0x0613110a,
237 		0x3fff8c20,		0x001fe7e3,		0x04a368fd,
238 		0x3fcf8c33,		0x000ff7e2,		0x0343b8ed,
239 		0x3f9f8c4a,		0x000fffe3,		0x0203f8da,
240 		0x3f5f9c61,		0x000003e6,		0x00e428c5,
241 		0x3f1fb07b,		0x000003eb,		0x3fe440af },
242 	},
243 	{ 0x2000, {
244 		0x000fa400,		0x000fa400,		0x09625902,
245 		0x3fff980c,		0x001fb7f5,		0x0812b0ff,
246 		0x3fdf901c,		0x001fc7ed,		0x06b2fcfa,
247 		0x3faf902d,		0x001fd3e8,		0x055348f1,
248 		0x3f7f983f,		0x001fe3e5,		0x04038ce3,
249 		0x3f3fa454,		0x001fefe3,		0x02e3c8d1,
250 		0x3f0fb86a,		0x001ff7e4,		0x01c3e8c0,
251 		0x3ecfd880,		0x000fffe6,		0x00c404ac },
252 	},
253 	{ 0x2200, {
254 		0x3fdf9c0b,		0x3fdf9c0b,		0x09725cf4,
255 		0x3fbf9818,		0x3fffa400,		0x0842a8f1,
256 		0x3f8f9827,		0x000fb3f7,		0x0702f0ec,
257 		0x3f5fa037,		0x000fc3ef,		0x05d330e4,
258 		0x3f2fac49,		0x001fcfea,		0x04a364d9,
259 		0x3effc05c,		0x001fdbe7,		0x038394ca,
260 		0x3ecfdc6f,		0x001fe7e6,		0x0273b0bb,
261 		0x3ea00083,		0x001fefe6,		0x0183c0a9 },
262 	},
263 	{ 0x2400, {
264 		0x3f9fa014,		0x3f9fa014,		0x098260e6,
265 		0x3f7f9c23,		0x3fcf9c0a,		0x08629ce5,
266 		0x3f4fa431,		0x3fefa400,		0x0742d8e1,
267 		0x3f1fb440,		0x3fffb3f8,		0x062310d9,
268 		0x3eefc850,		0x000fbbf2,		0x050340d0,
269 		0x3ecfe062,		0x000fcbec,		0x041364c2,
270 		0x3ea00073,		0x001fd3ea,		0x03037cb5,
271 		0x3e902086,		0x001fdfe8,		0x022388a5 },
272 	},
273 	{ 0x2600, {
274 		0x3f5fa81e,		0x3f5fa81e,		0x096258da,
275 		0x3f3fac2b,		0x3f8fa412,		0x088290d8,
276 		0x3f0fbc38,		0x3fafa408,		0x0772c8d5,
277 		0x3eefcc47,		0x3fcfa800,		0x0672f4ce,
278 		0x3ecfe456,		0x3fefaffa,		0x05531cc6,
279 		0x3eb00066,		0x3fffbbf3,		0x047334bb,
280 		0x3ea01c77,		0x000fc7ee,		0x039348ae,
281 		0x3ea04486,		0x000fd3eb,		0x02b350a1 },
282 	},
283 	{ 0x2800, {
284 		0x3f2fb426,		0x3f2fb426,		0x094250ce,
285 		0x3f0fc032,		0x3f4fac1b,		0x086284cd,
286 		0x3eefd040,		0x3f7fa811,		0x0782acc9,
287 		0x3ecfe84c,		0x3f9fa807,		0x06a2d8c4,
288 		0x3eb0005b,		0x3fbfac00,		0x05b2f4bc,
289 		0x3eb0186a,		0x3fdfb3fa,		0x04c308b4,
290 		0x3eb04077,		0x3fefbbf4,		0x03f31ca8,
291 		0x3ec06884,		0x000fbff2,		0x03031c9e },
292 	},
293 	{ 0x2a00, {
294 		0x3f0fc42d,		0x3f0fc42d,		0x090240c4,
295 		0x3eefd439,		0x3f2fb822,		0x08526cc2,
296 		0x3edfe845,		0x3f4fb018,		0x078294bf,
297 		0x3ec00051,		0x3f6fac0f,		0x06b2b4bb,
298 		0x3ec0185f,		0x3f8fac07,		0x05e2ccb4,
299 		0x3ec0386b,		0x3fafac00,		0x0502e8ac,
300 		0x3ed05c77,		0x3fcfb3fb,		0x0432f0a3,
301 		0x3ef08482,		0x3fdfbbf6,		0x0372f898 },
302 	},
303 	{ 0x2c00, {
304 		0x3eefdc31,		0x3eefdc31,		0x08e238b8,
305 		0x3edfec3d,		0x3f0fc828,		0x082258b9,
306 		0x3ed00049,		0x3f1fc01e,		0x077278b6,
307 		0x3ed01455,		0x3f3fb815,		0x06c294b2,
308 		0x3ed03460,		0x3f5fb40d,		0x0602acac,
309 		0x3ef0506c,		0x3f7fb006,		0x0542c0a4,
310 		0x3f107476,		0x3f9fb400,		0x0472c89d,
311 		0x3f309c80,		0x3fbfb7fc,		0x03b2cc94 },
312 	},
313 	{ 0x2e00, {
314 		0x3eefec37,		0x3eefec37,		0x088220b0,
315 		0x3ee00041,		0x3effdc2d,		0x07f244ae,
316 		0x3ee0144c,		0x3f0fd023,		0x07625cad,
317 		0x3ef02c57,		0x3f1fc81a,		0x06c274a9,
318 		0x3f004861,		0x3f3fbc13,		0x060288a6,
319 		0x3f20686b,		0x3f5fb80c,		0x05529c9e,
320 		0x3f408c74,		0x3f6fb805,		0x04b2ac96,
321 		0x3f80ac7e,		0x3f8fb800,		0x0402ac8e },
322 	},
323 	{ 0x3000, {
324 		0x3ef0003a,		0x3ef0003a,		0x084210a6,
325 		0x3ef01045,		0x3effec32,		0x07b228a7,
326 		0x3f00284e,		0x3f0fdc29,		0x073244a4,
327 		0x3f104058,		0x3f0fd420,		0x06a258a2,
328 		0x3f305c62,		0x3f2fc818,		0x0612689d,
329 		0x3f508069,		0x3f3fc011,		0x05728496,
330 		0x3f80a072,		0x3f4fc00a,		0x04d28c90,
331 		0x3fc0c07b,		0x3f6fbc04,		0x04429088 },
332 	},
333 	{ 0x3200, {
334 		0x3f00103e,		0x3f00103e,		0x07f1fc9e,
335 		0x3f102447,		0x3f000035,		0x0782149d,
336 		0x3f203c4f,		0x3f0ff02c,		0x07122c9c,
337 		0x3f405458,		0x3f0fe424,		0x06924099,
338 		0x3f607061,		0x3f1fd41d,		0x06024c97,
339 		0x3f909068,		0x3f2fcc16,		0x05726490,
340 		0x3fc0b070,		0x3f3fc80f,		0x04f26c8a,
341 		0x0000d077,		0x3f4fc409,		0x04627484 },
342 	},
343 	{ 0x3400, {
344 		0x3f202040,		0x3f202040,		0x07a1e898,
345 		0x3f303449,		0x3f100c38,		0x0741fc98,
346 		0x3f504c50,		0x3f10002f,		0x06e21495,
347 		0x3f706459,		0x3f1ff028,		0x06722492,
348 		0x3fa08060,		0x3f1fe421,		0x05f2348f,
349 		0x3fd09c67,		0x3f1fdc19,		0x05824c89,
350 		0x0000bc6e,		0x3f2fd014,		0x04f25086,
351 		0x0040dc74,		0x3f3fcc0d,		0x04825c7f },
352 	},
353 	{ 0x3600, {
354 		0x3f403042,		0x3f403042,		0x0761d890,
355 		0x3f504848,		0x3f301c3b,		0x0701f090,
356 		0x3f805c50,		0x3f200c33,		0x06a2008f,
357 		0x3fa07458,		0x3f10002b,		0x06520c8d,
358 		0x3fd0905e,		0x3f1ff424,		0x05e22089,
359 		0x0000ac65,		0x3f1fe81d,		0x05823483,
360 		0x0030cc6a,		0x3f2fdc18,		0x04f23c81,
361 		0x0080e871,		0x3f2fd412,		0x0482407c },
362 	},
363 	{ 0x3800, {
364 		0x3f604043,		0x3f604043,		0x0721c88a,
365 		0x3f80544a,		0x3f502c3c,		0x06d1d88a,
366 		0x3fb06851,		0x3f301c35,		0x0681e889,
367 		0x3fd08456,		0x3f30082f,		0x0611fc88,
368 		0x00009c5d,		0x3f200027,		0x05d20884,
369 		0x0030b863,		0x3f2ff421,		0x05621880,
370 		0x0070d468,		0x3f2fe81b,		0x0502247c,
371 		0x00c0ec6f,		0x3f2fe015,		0x04a22877 },
372 	},
373 	{ 0x3a00, {
374 		0x3f904c44,		0x3f904c44,		0x06e1b884,
375 		0x3fb0604a,		0x3f70383e,		0x0691c885,
376 		0x3fe07451,		0x3f502c36,		0x0661d483,
377 		0x00009055,		0x3f401831,		0x0601ec81,
378 		0x0030a85b,		0x3f300c2a,		0x05b1f480,
379 		0x0070c061,		0x3f300024,		0x0562047a,
380 		0x00b0d867,		0x3f3ff41e,		0x05020c77,
381 		0x00f0f46b,		0x3f2fec19,		0x04a21474 },
382 	},
383 	{ 0x3c00, {
384 		0x3fb05c43,		0x3fb05c43,		0x06c1b07e,
385 		0x3fe06c4b,		0x3f902c3f,		0x0681c081,
386 		0x0000844f,		0x3f703838,		0x0631cc7d,
387 		0x00309855,		0x3f602433,		0x05d1d47e,
388 		0x0060b459,		0x3f50142e,		0x0581e47b,
389 		0x00a0c85f,		0x3f400828,		0x0531f078,
390 		0x00e0e064,		0x3f300021,		0x0501fc73,
391 		0x00b0fc6a,		0x3f3ff41d,		0x04a20873 },
392 	},
393 	{ 0x3e00, {
394 		0x3fe06444,		0x3fe06444,		0x0681a07a,
395 		0x00007849,		0x3fc0503f,		0x0641b07a,
396 		0x0020904d,		0x3fa0403a,		0x05f1c07a,
397 		0x0060a453,		0x3f803034,		0x05c1c878,
398 		0x0090b858,		0x3f70202f,		0x0571d477,
399 		0x00d0d05d,		0x3f501829,		0x0531e073,
400 		0x0110e462,		0x3f500825,		0x04e1e471,
401 		0x01510065,		0x3f40001f,		0x04a1f06d },
402 	},
403 	{ 0x4000, {
404 		0x00007044,		0x00007044,		0x06519476,
405 		0x00208448,		0x3fe05c3f,		0x0621a476,
406 		0x0050984d,		0x3fc04c3a,		0x05e1b075,
407 		0x0080ac52,		0x3fa03c35,		0x05a1b875,
408 		0x00c0c056,		0x3f803030,		0x0561c473,
409 		0x0100d45b,		0x3f70202b,		0x0521d46f,
410 		0x0140e860,		0x3f601427,		0x04d1d46e,
411 		0x01810064,		0x3f500822,		0x0491dc6b },
412 	},
413 	{ 0x5000, {
414 		0x0110a442,		0x0110a442,		0x0551545e,
415 		0x0140b045,		0x00e0983f,		0x0531585f,
416 		0x0160c047,		0x00c08c3c,		0x0511645e,
417 		0x0190cc4a,		0x00908039,		0x04f1685f,
418 		0x01c0dc4c,		0x00707436,		0x04d1705e,
419 		0x0200e850,		0x00506833,		0x04b1785b,
420 		0x0230f453,		0x00305c30,		0x0491805a,
421 		0x02710056,		0x0010542d,		0x04718059 },
422 	},
423 	{ 0x6000, {
424 		0x01c0bc40,		0x01c0bc40,		0x04c13052,
425 		0x01e0c841,		0x01a0b43d,		0x04c13851,
426 		0x0210cc44,		0x0180a83c,		0x04a13453,
427 		0x0230d845,		0x0160a03a,		0x04913c52,
428 		0x0260e047,		0x01409838,		0x04714052,
429 		0x0280ec49,		0x01208c37,		0x04514c50,
430 		0x02b0f44b,		0x01008435,		0x04414c50,
431 		0x02d1004c,		0x00e07c33,		0x0431544f },
432 	},
433 	{ 0x7000, {
434 		0x0230c83e,		0x0230c83e,		0x04711c4c,
435 		0x0250d03f,		0x0210c43c,		0x0471204b,
436 		0x0270d840,		0x0200b83c,		0x0451244b,
437 		0x0290dc42,		0x01e0b43a,		0x0441244c,
438 		0x02b0e443,		0x01c0b038,		0x0441284b,
439 		0x02d0ec44,		0x01b0a438,		0x0421304a,
440 		0x02f0f445,		0x0190a036,		0x04213449,
441 		0x0310f847,		0x01709c34,		0x04213848 },
442 	},
443 	{ 0x8000, {
444 		0x0280d03d,		0x0280d03d,		0x04310c48,
445 		0x02a0d43e,		0x0270c83c,		0x04311047,
446 		0x02b0dc3e,		0x0250c83a,		0x04311447,
447 		0x02d0e040,		0x0240c03a,		0x04211446,
448 		0x02e0e840,		0x0220bc39,		0x04111847,
449 		0x0300e842,		0x0210b438,		0x04012445,
450 		0x0310f043,		0x0200b037,		0x04012045,
451 		0x0330f444,		0x01e0ac36,		0x03f12445 },
452 	},
453 	{ 0xefff, {
454 		0x0340dc3a,		0x0340dc3a,		0x03b0ec40,
455 		0x0340e03a,		0x0330e039,		0x03c0f03e,
456 		0x0350e03b,		0x0330dc39,		0x03c0ec3e,
457 		0x0350e43a,		0x0320dc38,		0x03c0f43e,
458 		0x0360e43b,		0x0320d839,		0x03b0f03e,
459 		0x0360e83b,		0x0310d838,		0x03c0fc3b,
460 		0x0370e83b,		0x0310d439,		0x03a0f83d,
461 		0x0370e83c,		0x0300d438,		0x03b0fc3c },
462 	}
463 };
464 
465 enum rcar_vin_state {
466 	STOPPED = 0,
467 	RUNNING,
468 	STOPPING,
469 };
470 
471 struct rcar_vin_priv {
472 	void __iomem			*base;
473 	spinlock_t			lock;
474 	int				sequence;
475 	/* State of the VIN module in capturing mode */
476 	enum rcar_vin_state		state;
477 	struct soc_camera_host		ici;
478 	struct list_head		capture;
479 #define MAX_BUFFER_NUM			3
480 	struct vb2_buffer		*queue_buf[MAX_BUFFER_NUM];
481 	struct vb2_alloc_ctx		*alloc_ctx;
482 	enum v4l2_field			field;
483 	unsigned int			pdata_flags;
484 	unsigned int			vb_count;
485 	unsigned int			nr_hw_slots;
486 	bool				request_to_stop;
487 	struct completion		capture_stop;
488 	enum chip_id			chip;
489 };
490 
491 #define is_continuous_transfer(priv)	(priv->vb_count > MAX_BUFFER_NUM)
492 
493 struct rcar_vin_buffer {
494 	struct vb2_buffer		vb;
495 	struct list_head		list;
496 };
497 
498 #define to_buf_list(vb2_buffer)	(&container_of(vb2_buffer, \
499 						       struct rcar_vin_buffer, \
500 						       vb)->list)
501 
502 struct rcar_vin_cam {
503 	/* VIN offsets within the camera output, before the VIN scaler */
504 	unsigned int			vin_left;
505 	unsigned int			vin_top;
506 	/* Client output, as seen by the VIN */
507 	unsigned int			width;
508 	unsigned int			height;
509 	/* User window from S_FMT */
510 	unsigned int out_width;
511 	unsigned int out_height;
512 	/*
513 	 * User window from S_CROP / G_CROP, produced by client cropping and
514 	 * scaling, VIN scaling and VIN cropping, mapped back onto the client
515 	 * input window
516 	 */
517 	struct v4l2_rect		subrect;
518 	/* Camera cropping rectangle */
519 	struct v4l2_rect		rect;
520 	const struct soc_mbus_pixelfmt	*extra_fmt;
521 };
522 
523 /*
524  * .queue_setup() is called to check whether the driver can accept the requested
525  * number of buffers and to fill in plane sizes for the current frame format if
526  * required
527  */
rcar_vin_videobuf_setup(struct vb2_queue * vq,const struct v4l2_format * fmt,unsigned int * count,unsigned int * num_planes,unsigned int sizes[],void * alloc_ctxs[])528 static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
529 				   const struct v4l2_format *fmt,
530 				   unsigned int *count,
531 				   unsigned int *num_planes,
532 				   unsigned int sizes[], void *alloc_ctxs[])
533 {
534 	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
535 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
536 	struct rcar_vin_priv *priv = ici->priv;
537 
538 	if (fmt) {
539 		const struct soc_camera_format_xlate *xlate;
540 		unsigned int bytes_per_line;
541 		int ret;
542 
543 		xlate = soc_camera_xlate_by_fourcc(icd,
544 						   fmt->fmt.pix.pixelformat);
545 		if (!xlate)
546 			return -EINVAL;
547 		ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
548 					      xlate->host_fmt);
549 		if (ret < 0)
550 			return ret;
551 
552 		bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
553 
554 		ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
555 					  fmt->fmt.pix.height);
556 		if (ret < 0)
557 			return ret;
558 
559 		sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
560 	} else {
561 		/* Called from VIDIOC_REQBUFS or in compatibility mode */
562 		sizes[0] = icd->sizeimage;
563 	}
564 
565 	alloc_ctxs[0] = priv->alloc_ctx;
566 
567 	if (!vq->num_buffers)
568 		priv->sequence = 0;
569 
570 	if (!*count)
571 		*count = 2;
572 	priv->vb_count = *count;
573 
574 	*num_planes = 1;
575 
576 	/* Number of hardware slots */
577 	if (is_continuous_transfer(priv))
578 		priv->nr_hw_slots = MAX_BUFFER_NUM;
579 	else
580 		priv->nr_hw_slots = 1;
581 
582 	dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
583 
584 	return 0;
585 }
586 
rcar_vin_setup(struct rcar_vin_priv * priv)587 static int rcar_vin_setup(struct rcar_vin_priv *priv)
588 {
589 	struct soc_camera_device *icd = priv->ici.icd;
590 	struct rcar_vin_cam *cam = icd->host_priv;
591 	u32 vnmc, dmr, interrupts;
592 	bool progressive = false, output_is_yuv = false;
593 
594 	switch (priv->field) {
595 	case V4L2_FIELD_TOP:
596 		vnmc = VNMC_IM_ODD;
597 		break;
598 	case V4L2_FIELD_BOTTOM:
599 		vnmc = VNMC_IM_EVEN;
600 		break;
601 	case V4L2_FIELD_INTERLACED:
602 	case V4L2_FIELD_INTERLACED_TB:
603 		vnmc = VNMC_IM_FULL;
604 		break;
605 	case V4L2_FIELD_INTERLACED_BT:
606 		vnmc = VNMC_IM_FULL | VNMC_FOC;
607 		break;
608 	case V4L2_FIELD_NONE:
609 		if (is_continuous_transfer(priv)) {
610 			vnmc = VNMC_IM_ODD_EVEN;
611 			progressive = true;
612 		} else {
613 			vnmc = VNMC_IM_ODD;
614 		}
615 		break;
616 	default:
617 		vnmc = VNMC_IM_ODD;
618 		break;
619 	}
620 
621 	/* input interface */
622 	switch (icd->current_fmt->code) {
623 	case MEDIA_BUS_FMT_YUYV8_1X16:
624 		/* BT.601/BT.1358 16bit YCbCr422 */
625 		vnmc |= VNMC_INF_YUV16;
626 		break;
627 	case MEDIA_BUS_FMT_YUYV8_2X8:
628 		/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
629 		vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
630 			VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
631 		break;
632 	case MEDIA_BUS_FMT_YUYV10_2X10:
633 		/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
634 		vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
635 			VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
636 		break;
637 	default:
638 		break;
639 	}
640 
641 	/* output format */
642 	switch (icd->current_fmt->host_fmt->fourcc) {
643 	case V4L2_PIX_FMT_NV16:
644 		iowrite32(ALIGN(cam->width * cam->height, 0x80),
645 			  priv->base + VNUVAOF_REG);
646 		dmr = VNDMR_DTMD_YCSEP;
647 		output_is_yuv = true;
648 		break;
649 	case V4L2_PIX_FMT_YUYV:
650 		dmr = VNDMR_BPSM;
651 		output_is_yuv = true;
652 		break;
653 	case V4L2_PIX_FMT_UYVY:
654 		dmr = 0;
655 		output_is_yuv = true;
656 		break;
657 	case V4L2_PIX_FMT_RGB555X:
658 		dmr = VNDMR_DTMD_ARGB1555;
659 		break;
660 	case V4L2_PIX_FMT_RGB565:
661 		dmr = 0;
662 		break;
663 	case V4L2_PIX_FMT_RGB32:
664 		if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
665 		    priv->chip == RCAR_E1) {
666 			dmr = VNDMR_EXRGB;
667 			break;
668 		}
669 	default:
670 		dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
671 			 icd->current_fmt->host_fmt->fourcc);
672 		return -EINVAL;
673 	}
674 
675 	/* Always update on field change */
676 	vnmc |= VNMC_VUP;
677 
678 	/* If input and output use the same colorspace, use bypass mode */
679 	if (output_is_yuv)
680 		vnmc |= VNMC_BPS;
681 
682 	/* progressive or interlaced mode */
683 	interrupts = progressive ? VNIE_FIE : VNIE_EFE;
684 
685 	/* ack interrupts */
686 	iowrite32(interrupts, priv->base + VNINTS_REG);
687 	/* enable interrupts */
688 	iowrite32(interrupts, priv->base + VNIE_REG);
689 	/* start capturing */
690 	iowrite32(dmr, priv->base + VNDMR_REG);
691 	iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
692 
693 	return 0;
694 }
695 
rcar_vin_capture(struct rcar_vin_priv * priv)696 static void rcar_vin_capture(struct rcar_vin_priv *priv)
697 {
698 	if (is_continuous_transfer(priv))
699 		/* Continuous Frame Capture Mode */
700 		iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
701 	else
702 		/* Single Frame Capture Mode */
703 		iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
704 }
705 
rcar_vin_request_capture_stop(struct rcar_vin_priv * priv)706 static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
707 {
708 	priv->state = STOPPING;
709 
710 	/* set continuous & single transfer off */
711 	iowrite32(0, priv->base + VNFC_REG);
712 	/* disable capture (release DMA buffer), reset */
713 	iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
714 		  priv->base + VNMC_REG);
715 
716 	/* update the status if stopped already */
717 	if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
718 		priv->state = STOPPED;
719 }
720 
rcar_vin_get_free_hw_slot(struct rcar_vin_priv * priv)721 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
722 {
723 	int slot;
724 
725 	for (slot = 0; slot < priv->nr_hw_slots; slot++)
726 		if (priv->queue_buf[slot] == NULL)
727 			return slot;
728 
729 	return -1;
730 }
731 
rcar_vin_hw_ready(struct rcar_vin_priv * priv)732 static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
733 {
734 	/* Ensure all HW slots are filled */
735 	return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
736 }
737 
738 /* Moves a buffer from the queue to the HW slots */
rcar_vin_fill_hw_slot(struct rcar_vin_priv * priv)739 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
740 {
741 	struct vb2_buffer *vb;
742 	dma_addr_t phys_addr_top;
743 	int slot;
744 
745 	if (list_empty(&priv->capture))
746 		return 0;
747 
748 	/* Find a free HW slot */
749 	slot = rcar_vin_get_free_hw_slot(priv);
750 	if (slot < 0)
751 		return 0;
752 
753 	vb = &list_entry(priv->capture.next, struct rcar_vin_buffer, list)->vb;
754 	list_del_init(to_buf_list(vb));
755 	priv->queue_buf[slot] = vb;
756 	phys_addr_top = vb2_dma_contig_plane_dma_addr(vb, 0);
757 	iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
758 
759 	return 1;
760 }
761 
rcar_vin_videobuf_queue(struct vb2_buffer * vb)762 static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
763 {
764 	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
765 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
766 	struct rcar_vin_priv *priv = ici->priv;
767 	unsigned long size;
768 
769 	size = icd->sizeimage;
770 
771 	if (vb2_plane_size(vb, 0) < size) {
772 		dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
773 			vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
774 		goto error;
775 	}
776 
777 	vb2_set_plane_payload(vb, 0, size);
778 
779 	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
780 		vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
781 
782 	spin_lock_irq(&priv->lock);
783 
784 	list_add_tail(to_buf_list(vb), &priv->capture);
785 	rcar_vin_fill_hw_slot(priv);
786 
787 	/* If we weren't running, and have enough buffers, start capturing! */
788 	if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
789 		if (rcar_vin_setup(priv)) {
790 			/* Submit error */
791 			list_del_init(to_buf_list(vb));
792 			spin_unlock_irq(&priv->lock);
793 			goto error;
794 		}
795 		priv->request_to_stop = false;
796 		init_completion(&priv->capture_stop);
797 		priv->state = RUNNING;
798 		rcar_vin_capture(priv);
799 	}
800 
801 	spin_unlock_irq(&priv->lock);
802 
803 	return;
804 
805 error:
806 	vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
807 }
808 
809 /*
810  * Wait for capture to stop and all in-flight buffers to be finished with by
811  * the video hardware. This must be called under &priv->lock
812  *
813  */
rcar_vin_wait_stop_streaming(struct rcar_vin_priv * priv)814 static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
815 {
816 	while (priv->state != STOPPED) {
817 		/* issue stop if running */
818 		if (priv->state == RUNNING)
819 			rcar_vin_request_capture_stop(priv);
820 
821 		/* wait until capturing has been stopped */
822 		if (priv->state == STOPPING) {
823 			priv->request_to_stop = true;
824 			spin_unlock_irq(&priv->lock);
825 			if (!wait_for_completion_timeout(
826 					&priv->capture_stop,
827 					msecs_to_jiffies(TIMEOUT_MS)))
828 				priv->state = STOPPED;
829 			spin_lock_irq(&priv->lock);
830 		}
831 	}
832 }
833 
rcar_vin_stop_streaming(struct vb2_queue * vq)834 static void rcar_vin_stop_streaming(struct vb2_queue *vq)
835 {
836 	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
837 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
838 	struct rcar_vin_priv *priv = ici->priv;
839 	struct list_head *buf_head, *tmp;
840 	int i;
841 
842 	spin_lock_irq(&priv->lock);
843 	rcar_vin_wait_stop_streaming(priv);
844 
845 	for (i = 0; i < MAX_BUFFER_NUM; i++) {
846 		if (priv->queue_buf[i]) {
847 			vb2_buffer_done(priv->queue_buf[i],
848 					VB2_BUF_STATE_ERROR);
849 			priv->queue_buf[i] = NULL;
850 		}
851 	}
852 
853 	list_for_each_safe(buf_head, tmp, &priv->capture) {
854 		vb2_buffer_done(&list_entry(buf_head,
855 					struct rcar_vin_buffer, list)->vb,
856 				VB2_BUF_STATE_ERROR);
857 		list_del_init(buf_head);
858 	}
859 	spin_unlock_irq(&priv->lock);
860 }
861 
862 static struct vb2_ops rcar_vin_vb2_ops = {
863 	.queue_setup	= rcar_vin_videobuf_setup,
864 	.buf_queue	= rcar_vin_videobuf_queue,
865 	.stop_streaming	= rcar_vin_stop_streaming,
866 	.wait_prepare	= vb2_ops_wait_prepare,
867 	.wait_finish	= vb2_ops_wait_finish,
868 };
869 
rcar_vin_irq(int irq,void * data)870 static irqreturn_t rcar_vin_irq(int irq, void *data)
871 {
872 	struct rcar_vin_priv *priv = data;
873 	u32 int_status;
874 	bool can_run = false, hw_stopped;
875 	int slot;
876 	unsigned int handled = 0;
877 
878 	spin_lock(&priv->lock);
879 
880 	int_status = ioread32(priv->base + VNINTS_REG);
881 	if (!int_status)
882 		goto done;
883 	/* ack interrupts */
884 	iowrite32(int_status, priv->base + VNINTS_REG);
885 	handled = 1;
886 
887 	/* nothing to do if capture status is 'STOPPED' */
888 	if (priv->state == STOPPED)
889 		goto done;
890 
891 	hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
892 
893 	if (!priv->request_to_stop) {
894 		if (is_continuous_transfer(priv))
895 			slot = (ioread32(priv->base + VNMS_REG) &
896 				VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
897 		else
898 			slot = 0;
899 
900 		priv->queue_buf[slot]->v4l2_buf.field = priv->field;
901 		priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
902 		do_gettimeofday(&priv->queue_buf[slot]->v4l2_buf.timestamp);
903 		vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
904 		priv->queue_buf[slot] = NULL;
905 
906 		if (priv->state != STOPPING)
907 			can_run = rcar_vin_fill_hw_slot(priv);
908 
909 		if (hw_stopped || !can_run) {
910 			priv->state = STOPPED;
911 		} else if (is_continuous_transfer(priv) &&
912 			   list_empty(&priv->capture) &&
913 			   priv->state == RUNNING) {
914 			/*
915 			 * The continuous capturing requires an explicit stop
916 			 * operation when there is no buffer to be set into
917 			 * the VnMBm registers.
918 			 */
919 			rcar_vin_request_capture_stop(priv);
920 		} else {
921 			rcar_vin_capture(priv);
922 		}
923 
924 	} else if (hw_stopped) {
925 		priv->state = STOPPED;
926 		priv->request_to_stop = false;
927 		complete(&priv->capture_stop);
928 	}
929 
930 done:
931 	spin_unlock(&priv->lock);
932 
933 	return IRQ_RETVAL(handled);
934 }
935 
rcar_vin_add_device(struct soc_camera_device * icd)936 static int rcar_vin_add_device(struct soc_camera_device *icd)
937 {
938 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
939 	struct rcar_vin_priv *priv = ici->priv;
940 	int i;
941 
942 	for (i = 0; i < MAX_BUFFER_NUM; i++)
943 		priv->queue_buf[i] = NULL;
944 
945 	pm_runtime_get_sync(ici->v4l2_dev.dev);
946 
947 	dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
948 		icd->devnum);
949 
950 	return 0;
951 }
952 
rcar_vin_remove_device(struct soc_camera_device * icd)953 static void rcar_vin_remove_device(struct soc_camera_device *icd)
954 {
955 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
956 	struct rcar_vin_priv *priv = ici->priv;
957 	struct vb2_buffer *vb;
958 	int i;
959 
960 	/* disable capture, disable interrupts */
961 	iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
962 		  priv->base + VNMC_REG);
963 	iowrite32(0, priv->base + VNIE_REG);
964 
965 	priv->state = STOPPED;
966 	priv->request_to_stop = false;
967 
968 	/* make sure active buffer is cancelled */
969 	spin_lock_irq(&priv->lock);
970 	for (i = 0; i < MAX_BUFFER_NUM; i++) {
971 		vb = priv->queue_buf[i];
972 		if (vb) {
973 			list_del_init(to_buf_list(vb));
974 			vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
975 		}
976 	}
977 	spin_unlock_irq(&priv->lock);
978 
979 	pm_runtime_put(ici->v4l2_dev.dev);
980 
981 	dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
982 		icd->devnum);
983 }
984 
set_coeff(struct rcar_vin_priv * priv,unsigned short xs)985 static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
986 {
987 	int i;
988 	const struct vin_coeff *p_prev_set = NULL;
989 	const struct vin_coeff *p_set = NULL;
990 
991 	/* Look for suitable coefficient values */
992 	for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
993 		p_prev_set = p_set;
994 		p_set = &vin_coeff_set[i];
995 
996 		if (xs < p_set->xs_value)
997 			break;
998 	}
999 
1000 	/* Use previous value if its XS value is closer */
1001 	if (p_prev_set && p_set &&
1002 	    xs - p_prev_set->xs_value < p_set->xs_value - xs)
1003 		p_set = p_prev_set;
1004 
1005 	/* Set coefficient registers */
1006 	iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG);
1007 	iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG);
1008 	iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG);
1009 
1010 	iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG);
1011 	iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG);
1012 	iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG);
1013 
1014 	iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG);
1015 	iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG);
1016 	iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG);
1017 
1018 	iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG);
1019 	iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG);
1020 	iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG);
1021 
1022 	iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG);
1023 	iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG);
1024 	iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG);
1025 
1026 	iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG);
1027 	iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG);
1028 	iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG);
1029 
1030 	iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG);
1031 	iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG);
1032 	iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG);
1033 
1034 	iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG);
1035 	iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG);
1036 	iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG);
1037 }
1038 
1039 /* rect is guaranteed to not exceed the scaled camera rectangle */
rcar_vin_set_rect(struct soc_camera_device * icd)1040 static int rcar_vin_set_rect(struct soc_camera_device *icd)
1041 {
1042 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1043 	struct rcar_vin_cam *cam = icd->host_priv;
1044 	struct rcar_vin_priv *priv = ici->priv;
1045 	unsigned int left_offset, top_offset;
1046 	unsigned char dsize = 0;
1047 	struct v4l2_rect *cam_subrect = &cam->subrect;
1048 	u32 value;
1049 
1050 	dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
1051 		icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
1052 
1053 	left_offset = cam->vin_left;
1054 	top_offset = cam->vin_top;
1055 
1056 	if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
1057 	    priv->chip == RCAR_E1)
1058 		dsize = 1;
1059 
1060 	dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
1061 		cam->width, cam->height, cam->vin_left, cam->vin_top);
1062 	dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
1063 		cam_subrect->width, cam_subrect->height,
1064 		cam_subrect->left, cam_subrect->top);
1065 
1066 	/* Set Start/End Pixel/Line Pre-Clip */
1067 	iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
1068 	iowrite32((left_offset + cam_subrect->width - 1) << dsize,
1069 		  priv->base + VNEPPRC_REG);
1070 	switch (priv->field) {
1071 	case V4L2_FIELD_INTERLACED:
1072 	case V4L2_FIELD_INTERLACED_TB:
1073 	case V4L2_FIELD_INTERLACED_BT:
1074 		iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
1075 		iowrite32((top_offset + cam_subrect->height) / 2 - 1,
1076 			  priv->base + VNELPRC_REG);
1077 		break;
1078 	default:
1079 		iowrite32(top_offset, priv->base + VNSLPRC_REG);
1080 		iowrite32(top_offset + cam_subrect->height - 1,
1081 			  priv->base + VNELPRC_REG);
1082 		break;
1083 	}
1084 
1085 	/* Set scaling coefficient */
1086 	value = 0;
1087 	if (cam_subrect->height != cam->out_height)
1088 		value = (4096 * cam_subrect->height) / cam->out_height;
1089 	dev_dbg(icd->parent, "YS Value: %x\n", value);
1090 	iowrite32(value, priv->base + VNYS_REG);
1091 
1092 	value = 0;
1093 	if (cam_subrect->width != cam->out_width)
1094 		value = (4096 * cam_subrect->width) / cam->out_width;
1095 
1096 	/* Horizontal upscaling is up to double size */
1097 	if (0 < value && value < 2048)
1098 		value = 2048;
1099 
1100 	dev_dbg(icd->parent, "XS Value: %x\n", value);
1101 	iowrite32(value, priv->base + VNXS_REG);
1102 
1103 	/* Horizontal upscaling is carried out by scaling down from double size */
1104 	if (value < 4096)
1105 		value *= 2;
1106 
1107 	set_coeff(priv, value);
1108 
1109 	/* Set Start/End Pixel/Line Post-Clip */
1110 	iowrite32(0, priv->base + VNSPPOC_REG);
1111 	iowrite32(0, priv->base + VNSLPOC_REG);
1112 	iowrite32((cam->out_width - 1) << dsize, priv->base + VNEPPOC_REG);
1113 	switch (priv->field) {
1114 	case V4L2_FIELD_INTERLACED:
1115 	case V4L2_FIELD_INTERLACED_TB:
1116 	case V4L2_FIELD_INTERLACED_BT:
1117 		iowrite32(cam->out_height / 2 - 1,
1118 			  priv->base + VNELPOC_REG);
1119 		break;
1120 	default:
1121 		iowrite32(cam->out_height - 1, priv->base + VNELPOC_REG);
1122 		break;
1123 	}
1124 
1125 	iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
1126 
1127 	return 0;
1128 }
1129 
capture_stop_preserve(struct rcar_vin_priv * priv,u32 * vnmc)1130 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
1131 {
1132 	*vnmc = ioread32(priv->base + VNMC_REG);
1133 	/* module disable */
1134 	iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
1135 }
1136 
capture_restore(struct rcar_vin_priv * priv,u32 vnmc)1137 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
1138 {
1139 	unsigned long timeout = jiffies + 10 * HZ;
1140 
1141 	/*
1142 	 * Wait until the end of the current frame. It can take a long time,
1143 	 * but if it has been aborted by a MRST1 reset, it should exit sooner.
1144 	 */
1145 	while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
1146 		time_before(jiffies, timeout))
1147 		msleep(1);
1148 
1149 	if (time_after(jiffies, timeout)) {
1150 		dev_err(priv->ici.v4l2_dev.dev,
1151 			"Timeout waiting for frame end! Interface problem?\n");
1152 		return;
1153 	}
1154 
1155 	iowrite32(vnmc, priv->base + VNMC_REG);
1156 }
1157 
1158 #define VIN_MBUS_FLAGS	(V4L2_MBUS_MASTER |		\
1159 			 V4L2_MBUS_PCLK_SAMPLE_RISING |	\
1160 			 V4L2_MBUS_HSYNC_ACTIVE_HIGH |	\
1161 			 V4L2_MBUS_HSYNC_ACTIVE_LOW |	\
1162 			 V4L2_MBUS_VSYNC_ACTIVE_HIGH |	\
1163 			 V4L2_MBUS_VSYNC_ACTIVE_LOW |	\
1164 			 V4L2_MBUS_DATA_ACTIVE_HIGH)
1165 
rcar_vin_set_bus_param(struct soc_camera_device * icd)1166 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
1167 {
1168 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1169 	struct rcar_vin_priv *priv = ici->priv;
1170 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1171 	struct v4l2_mbus_config cfg;
1172 	unsigned long common_flags;
1173 	u32 vnmc;
1174 	u32 val;
1175 	int ret;
1176 
1177 	capture_stop_preserve(priv, &vnmc);
1178 
1179 	ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1180 	if (!ret) {
1181 		common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1182 		if (!common_flags) {
1183 			dev_warn(icd->parent,
1184 				 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1185 				 cfg.flags, VIN_MBUS_FLAGS);
1186 			return -EINVAL;
1187 		}
1188 	} else if (ret != -ENOIOCTLCMD) {
1189 		return ret;
1190 	} else {
1191 		common_flags = VIN_MBUS_FLAGS;
1192 	}
1193 
1194 	/* Make choises, based on platform preferences */
1195 	if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1196 	    (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1197 		if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
1198 			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1199 		else
1200 			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1201 	}
1202 
1203 	if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1204 	    (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1205 		if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
1206 			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1207 		else
1208 			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1209 	}
1210 
1211 	cfg.flags = common_flags;
1212 	ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1213 	if (ret < 0 && ret != -ENOIOCTLCMD)
1214 		return ret;
1215 
1216 	val = VNDMR2_FTEV | VNDMR2_VLV(1);
1217 	if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
1218 		val |= VNDMR2_VPS;
1219 	if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
1220 		val |= VNDMR2_HPS;
1221 	iowrite32(val, priv->base + VNDMR2_REG);
1222 
1223 	ret = rcar_vin_set_rect(icd);
1224 	if (ret < 0)
1225 		return ret;
1226 
1227 	capture_restore(priv, vnmc);
1228 
1229 	return 0;
1230 }
1231 
rcar_vin_try_bus_param(struct soc_camera_device * icd,unsigned char buswidth)1232 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
1233 				  unsigned char buswidth)
1234 {
1235 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1236 	struct v4l2_mbus_config cfg;
1237 	int ret;
1238 
1239 	ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1240 	if (ret == -ENOIOCTLCMD)
1241 		return 0;
1242 	else if (ret)
1243 		return ret;
1244 
1245 	if (buswidth > 24)
1246 		return -EINVAL;
1247 
1248 	/* check is there common mbus flags */
1249 	ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1250 	if (ret)
1251 		return 0;
1252 
1253 	dev_warn(icd->parent,
1254 		"MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1255 		 cfg.flags, VIN_MBUS_FLAGS);
1256 
1257 	return -EINVAL;
1258 }
1259 
rcar_vin_packing_supported(const struct soc_mbus_pixelfmt * fmt)1260 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1261 {
1262 	return	fmt->packing == SOC_MBUS_PACKING_NONE ||
1263 		(fmt->bits_per_sample > 8 &&
1264 		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1265 }
1266 
1267 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
1268 	{
1269 		.fourcc			= V4L2_PIX_FMT_NV16,
1270 		.name			= "NV16",
1271 		.bits_per_sample	= 8,
1272 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
1273 		.order			= SOC_MBUS_ORDER_LE,
1274 		.layout			= SOC_MBUS_LAYOUT_PLANAR_Y_C,
1275 	},
1276 	{
1277 		.fourcc			= V4L2_PIX_FMT_YUYV,
1278 		.name			= "YUYV",
1279 		.bits_per_sample	= 16,
1280 		.packing		= SOC_MBUS_PACKING_NONE,
1281 		.order			= SOC_MBUS_ORDER_LE,
1282 		.layout			= SOC_MBUS_LAYOUT_PACKED,
1283 	},
1284 	{
1285 		.fourcc			= V4L2_PIX_FMT_UYVY,
1286 		.name			= "UYVY",
1287 		.bits_per_sample	= 16,
1288 		.packing		= SOC_MBUS_PACKING_NONE,
1289 		.order			= SOC_MBUS_ORDER_LE,
1290 		.layout			= SOC_MBUS_LAYOUT_PACKED,
1291 	},
1292 	{
1293 		.fourcc			= V4L2_PIX_FMT_RGB565,
1294 		.name			= "RGB565",
1295 		.bits_per_sample	= 16,
1296 		.packing		= SOC_MBUS_PACKING_NONE,
1297 		.order			= SOC_MBUS_ORDER_LE,
1298 		.layout			= SOC_MBUS_LAYOUT_PACKED,
1299 	},
1300 	{
1301 		.fourcc			= V4L2_PIX_FMT_RGB555X,
1302 		.name			= "ARGB1555",
1303 		.bits_per_sample	= 16,
1304 		.packing		= SOC_MBUS_PACKING_NONE,
1305 		.order			= SOC_MBUS_ORDER_LE,
1306 		.layout			= SOC_MBUS_LAYOUT_PACKED,
1307 	},
1308 	{
1309 		.fourcc			= V4L2_PIX_FMT_RGB32,
1310 		.name			= "RGB888",
1311 		.bits_per_sample	= 32,
1312 		.packing		= SOC_MBUS_PACKING_NONE,
1313 		.order			= SOC_MBUS_ORDER_LE,
1314 		.layout			= SOC_MBUS_LAYOUT_PACKED,
1315 	},
1316 };
1317 
rcar_vin_get_formats(struct soc_camera_device * icd,unsigned int idx,struct soc_camera_format_xlate * xlate)1318 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
1319 				struct soc_camera_format_xlate *xlate)
1320 {
1321 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1322 	struct device *dev = icd->parent;
1323 	int ret, k, n;
1324 	int formats = 0;
1325 	struct rcar_vin_cam *cam;
1326 	u32 code;
1327 	const struct soc_mbus_pixelfmt *fmt;
1328 
1329 	ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1330 	if (ret < 0)
1331 		return 0;
1332 
1333 	fmt = soc_mbus_get_fmtdesc(code);
1334 	if (!fmt) {
1335 		dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
1336 		return 0;
1337 	}
1338 
1339 	ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
1340 	if (ret < 0)
1341 		return 0;
1342 
1343 	if (!icd->host_priv) {
1344 		struct v4l2_mbus_framefmt mf;
1345 		struct v4l2_rect rect;
1346 		struct device *dev = icd->parent;
1347 		int shift;
1348 
1349 		ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1350 		if (ret < 0)
1351 			return ret;
1352 
1353 		/* Cache current client geometry */
1354 		ret = soc_camera_client_g_rect(sd, &rect);
1355 		if (ret == -ENOIOCTLCMD) {
1356 			/* Sensor driver doesn't support cropping */
1357 			rect.left = 0;
1358 			rect.top = 0;
1359 			rect.width = mf.width;
1360 			rect.height = mf.height;
1361 		} else if (ret < 0) {
1362 			return ret;
1363 		}
1364 
1365 		/*
1366 		 * If sensor proposes too large format then try smaller ones:
1367 		 * 1280x960, 640x480, 320x240
1368 		 */
1369 		for (shift = 0; shift < 3; shift++) {
1370 			if (mf.width <= VIN_MAX_WIDTH &&
1371 			    mf.height <= VIN_MAX_HEIGHT)
1372 				break;
1373 
1374 			mf.width = 1280 >> shift;
1375 			mf.height = 960 >> shift;
1376 			ret = v4l2_device_call_until_err(sd->v4l2_dev,
1377 							 soc_camera_grp_id(icd),
1378 							 video, s_mbus_fmt,
1379 							 &mf);
1380 			if (ret < 0)
1381 				return ret;
1382 		}
1383 
1384 		if (shift == 3) {
1385 			dev_err(dev,
1386 				"Failed to configure the client below %ux%u\n",
1387 				mf.width, mf.height);
1388 			return -EIO;
1389 		}
1390 
1391 		dev_dbg(dev, "camera fmt %ux%u\n", mf.width, mf.height);
1392 
1393 		cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1394 		if (!cam)
1395 			return -ENOMEM;
1396 		/*
1397 		 * We are called with current camera crop,
1398 		 * initialise subrect with it
1399 		 */
1400 		cam->rect = rect;
1401 		cam->subrect = rect;
1402 		cam->width = mf.width;
1403 		cam->height = mf.height;
1404 		cam->out_width	= mf.width;
1405 		cam->out_height	= mf.height;
1406 
1407 		icd->host_priv = cam;
1408 	} else {
1409 		cam = icd->host_priv;
1410 	}
1411 
1412 	/* Beginning of a pass */
1413 	if (!idx)
1414 		cam->extra_fmt = NULL;
1415 
1416 	switch (code) {
1417 	case MEDIA_BUS_FMT_YUYV8_1X16:
1418 	case MEDIA_BUS_FMT_YUYV8_2X8:
1419 	case MEDIA_BUS_FMT_YUYV10_2X10:
1420 		if (cam->extra_fmt)
1421 			break;
1422 
1423 		/* Add all our formats that can be generated by VIN */
1424 		cam->extra_fmt = rcar_vin_formats;
1425 
1426 		n = ARRAY_SIZE(rcar_vin_formats);
1427 		formats += n;
1428 		for (k = 0; xlate && k < n; k++, xlate++) {
1429 			xlate->host_fmt = &rcar_vin_formats[k];
1430 			xlate->code = code;
1431 			dev_dbg(dev, "Providing format %s using code %d\n",
1432 				rcar_vin_formats[k].name, code);
1433 		}
1434 		break;
1435 	default:
1436 		if (!rcar_vin_packing_supported(fmt))
1437 			return 0;
1438 
1439 		dev_dbg(dev, "Providing format %s in pass-through mode\n",
1440 			fmt->name);
1441 		break;
1442 	}
1443 
1444 	/* Generic pass-through */
1445 	formats++;
1446 	if (xlate) {
1447 		xlate->host_fmt = fmt;
1448 		xlate->code = code;
1449 		xlate++;
1450 	}
1451 
1452 	return formats;
1453 }
1454 
rcar_vin_put_formats(struct soc_camera_device * icd)1455 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1456 {
1457 	kfree(icd->host_priv);
1458 	icd->host_priv = NULL;
1459 }
1460 
rcar_vin_set_crop(struct soc_camera_device * icd,const struct v4l2_crop * a)1461 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1462 			     const struct v4l2_crop *a)
1463 {
1464 	struct v4l2_crop a_writable = *a;
1465 	const struct v4l2_rect *rect = &a_writable.c;
1466 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1467 	struct rcar_vin_priv *priv = ici->priv;
1468 	struct v4l2_crop cam_crop;
1469 	struct rcar_vin_cam *cam = icd->host_priv;
1470 	struct v4l2_rect *cam_rect = &cam_crop.c;
1471 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1472 	struct device *dev = icd->parent;
1473 	struct v4l2_mbus_framefmt mf;
1474 	u32 vnmc;
1475 	int ret, i;
1476 
1477 	dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1478 		rect->left, rect->top);
1479 
1480 	/* During camera cropping its output window can change too, stop VIN */
1481 	capture_stop_preserve(priv, &vnmc);
1482 	dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1483 
1484 	/* Apply iterative camera S_CROP for new input window. */
1485 	ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1486 				       &cam->rect, &cam->subrect);
1487 	if (ret < 0)
1488 		return ret;
1489 
1490 	dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1491 		cam_rect->width, cam_rect->height,
1492 		cam_rect->left, cam_rect->top);
1493 
1494 	/* On success cam_crop contains current camera crop */
1495 
1496 	/* Retrieve camera output window */
1497 	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1498 	if (ret < 0)
1499 		return ret;
1500 
1501 	if (mf.width > VIN_MAX_WIDTH || mf.height > VIN_MAX_HEIGHT)
1502 		return -EINVAL;
1503 
1504 	/* Cache camera output window */
1505 	cam->width = mf.width;
1506 	cam->height = mf.height;
1507 
1508 	icd->user_width  = cam->width;
1509 	icd->user_height = cam->height;
1510 
1511 	cam->vin_left = rect->left & ~1;
1512 	cam->vin_top = rect->top & ~1;
1513 
1514 	/* Use VIN cropping to crop to the new window. */
1515 	ret = rcar_vin_set_rect(icd);
1516 	if (ret < 0)
1517 		return ret;
1518 
1519 	cam->subrect = *rect;
1520 
1521 	dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1522 		icd->user_width, icd->user_height,
1523 		cam->vin_left, cam->vin_top);
1524 
1525 	/* Restore capture */
1526 	for (i = 0; i < MAX_BUFFER_NUM; i++) {
1527 		if (priv->queue_buf[i] && priv->state == STOPPED) {
1528 			vnmc |= VNMC_ME;
1529 			break;
1530 		}
1531 	}
1532 	capture_restore(priv, vnmc);
1533 
1534 	/* Even if only camera cropping succeeded */
1535 	return ret;
1536 }
1537 
rcar_vin_get_crop(struct soc_camera_device * icd,struct v4l2_crop * a)1538 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1539 			     struct v4l2_crop *a)
1540 {
1541 	struct rcar_vin_cam *cam = icd->host_priv;
1542 
1543 	a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1544 	a->c = cam->subrect;
1545 
1546 	return 0;
1547 }
1548 
1549 /* Similar to set_crop multistage iterative algorithm */
rcar_vin_set_fmt(struct soc_camera_device * icd,struct v4l2_format * f)1550 static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1551 			    struct v4l2_format *f)
1552 {
1553 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1554 	struct rcar_vin_priv *priv = ici->priv;
1555 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1556 	struct rcar_vin_cam *cam = icd->host_priv;
1557 	struct v4l2_pix_format *pix = &f->fmt.pix;
1558 	struct v4l2_mbus_framefmt mf;
1559 	struct device *dev = icd->parent;
1560 	__u32 pixfmt = pix->pixelformat;
1561 	const struct soc_camera_format_xlate *xlate;
1562 	unsigned int vin_sub_width = 0, vin_sub_height = 0;
1563 	int ret;
1564 	bool can_scale;
1565 	enum v4l2_field field;
1566 	v4l2_std_id std;
1567 
1568 	dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1569 		pixfmt, pix->width, pix->height);
1570 
1571 	switch (pix->field) {
1572 	default:
1573 		pix->field = V4L2_FIELD_NONE;
1574 		/* fall-through */
1575 	case V4L2_FIELD_NONE:
1576 	case V4L2_FIELD_TOP:
1577 	case V4L2_FIELD_BOTTOM:
1578 	case V4L2_FIELD_INTERLACED_TB:
1579 	case V4L2_FIELD_INTERLACED_BT:
1580 		field = pix->field;
1581 		break;
1582 	case V4L2_FIELD_INTERLACED:
1583 		/* Query for standard if not explicitly mentioned _TB/_BT */
1584 		ret = v4l2_subdev_call(sd, video, querystd, &std);
1585 		if (ret < 0)
1586 			std = V4L2_STD_625_50;
1587 
1588 		field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1589 						V4L2_FIELD_INTERLACED_BT;
1590 		break;
1591 	}
1592 
1593 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1594 	if (!xlate) {
1595 		dev_warn(dev, "Format %x not found\n", pixfmt);
1596 		return -EINVAL;
1597 	}
1598 	/* Calculate client output geometry */
1599 	soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1600 				      12);
1601 	mf.field = pix->field;
1602 	mf.colorspace = pix->colorspace;
1603 	mf.code	 = xlate->code;
1604 
1605 	switch (pixfmt) {
1606 	case V4L2_PIX_FMT_RGB32:
1607 		can_scale = priv->chip != RCAR_E1;
1608 		break;
1609 	case V4L2_PIX_FMT_UYVY:
1610 	case V4L2_PIX_FMT_YUYV:
1611 	case V4L2_PIX_FMT_RGB565:
1612 	case V4L2_PIX_FMT_RGB555X:
1613 		can_scale = true;
1614 		break;
1615 	default:
1616 		can_scale = false;
1617 		break;
1618 	}
1619 
1620 	dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1621 
1622 	ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1623 				      &mf, &vin_sub_width, &vin_sub_height,
1624 				      can_scale, 12);
1625 
1626 	/* Done with the camera. Now see if we can improve the result */
1627 	dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1628 		ret, mf.width, mf.height, pix->width, pix->height);
1629 
1630 	if (ret == -ENOIOCTLCMD)
1631 		dev_dbg(dev, "Sensor doesn't support scaling\n");
1632 	else if (ret < 0)
1633 		return ret;
1634 
1635 	if (mf.code != xlate->code)
1636 		return -EINVAL;
1637 
1638 	/* Prepare VIN crop */
1639 	cam->width = mf.width;
1640 	cam->height = mf.height;
1641 
1642 	/* Use VIN scaling to scale to the requested user window. */
1643 
1644 	/* We cannot scale up */
1645 	if (pix->width > vin_sub_width)
1646 		vin_sub_width = pix->width;
1647 
1648 	if (pix->height > vin_sub_height)
1649 		vin_sub_height = pix->height;
1650 
1651 	pix->colorspace = mf.colorspace;
1652 
1653 	if (!can_scale) {
1654 		pix->width = vin_sub_width;
1655 		pix->height = vin_sub_height;
1656 	}
1657 
1658 	/*
1659 	 * We have calculated CFLCR, the actual configuration will be performed
1660 	 * in rcar_vin_set_bus_param()
1661 	 */
1662 
1663 	dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1664 		vin_sub_width, pix->width, vin_sub_height, pix->height);
1665 
1666 	cam->out_width = pix->width;
1667 	cam->out_height = pix->height;
1668 
1669 	icd->current_fmt = xlate;
1670 
1671 	priv->field = field;
1672 
1673 	return 0;
1674 }
1675 
rcar_vin_try_fmt(struct soc_camera_device * icd,struct v4l2_format * f)1676 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1677 			    struct v4l2_format *f)
1678 {
1679 	const struct soc_camera_format_xlate *xlate;
1680 	struct v4l2_pix_format *pix = &f->fmt.pix;
1681 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1682 	struct v4l2_mbus_framefmt mf;
1683 	__u32 pixfmt = pix->pixelformat;
1684 	int width, height;
1685 	int ret;
1686 
1687 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1688 	if (!xlate) {
1689 		xlate = icd->current_fmt;
1690 		dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1691 			pixfmt, xlate->host_fmt->fourcc);
1692 		pixfmt = xlate->host_fmt->fourcc;
1693 		pix->pixelformat = pixfmt;
1694 		pix->colorspace = icd->colorspace;
1695 	}
1696 
1697 	/* FIXME: calculate using depth and bus width */
1698 	v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1699 			      &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1700 
1701 	width = pix->width;
1702 	height = pix->height;
1703 
1704 	/* let soc-camera calculate these values */
1705 	pix->bytesperline = 0;
1706 	pix->sizeimage = 0;
1707 
1708 	/* limit to sensor capabilities */
1709 	mf.width = pix->width;
1710 	mf.height = pix->height;
1711 	mf.field = pix->field;
1712 	mf.code = xlate->code;
1713 	mf.colorspace = pix->colorspace;
1714 
1715 	ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1716 					 video, try_mbus_fmt, &mf);
1717 	if (ret < 0)
1718 		return ret;
1719 
1720 	/* Adjust only if VIN cannot scale */
1721 	if (pix->width > mf.width * 2)
1722 		pix->width = mf.width * 2;
1723 	if (pix->height > mf.height * 3)
1724 		pix->height = mf.height * 3;
1725 
1726 	pix->field = mf.field;
1727 	pix->colorspace = mf.colorspace;
1728 
1729 	if (pixfmt == V4L2_PIX_FMT_NV16) {
1730 		/* FIXME: check against rect_max after converting soc-camera */
1731 		/* We can scale precisely, need a bigger image from camera */
1732 		if (pix->width < width || pix->height < height) {
1733 			/*
1734 			 * We presume, the sensor behaves sanely, i.e. if
1735 			 * requested a bigger rectangle, it will not return a
1736 			 * smaller one.
1737 			 */
1738 			mf.width = VIN_MAX_WIDTH;
1739 			mf.height = VIN_MAX_HEIGHT;
1740 			ret = v4l2_device_call_until_err(sd->v4l2_dev,
1741 							 soc_camera_grp_id(icd),
1742 							 video, try_mbus_fmt,
1743 							 &mf);
1744 			if (ret < 0) {
1745 				dev_err(icd->parent,
1746 					"client try_fmt() = %d\n", ret);
1747 				return ret;
1748 			}
1749 		}
1750 		/* We will scale exactly */
1751 		if (mf.width > width)
1752 			pix->width = width;
1753 		if (mf.height > height)
1754 			pix->height = height;
1755 	}
1756 
1757 	return ret;
1758 }
1759 
rcar_vin_poll(struct file * file,poll_table * pt)1760 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1761 {
1762 	struct soc_camera_device *icd = file->private_data;
1763 
1764 	return vb2_poll(&icd->vb2_vidq, file, pt);
1765 }
1766 
rcar_vin_querycap(struct soc_camera_host * ici,struct v4l2_capability * cap)1767 static int rcar_vin_querycap(struct soc_camera_host *ici,
1768 			     struct v4l2_capability *cap)
1769 {
1770 	strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1771 	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1772 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1773 
1774 	return 0;
1775 }
1776 
rcar_vin_init_videobuf2(struct vb2_queue * vq,struct soc_camera_device * icd)1777 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1778 				   struct soc_camera_device *icd)
1779 {
1780 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1781 
1782 	vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1783 	vq->io_modes = VB2_MMAP | VB2_USERPTR;
1784 	vq->drv_priv = icd;
1785 	vq->ops = &rcar_vin_vb2_ops;
1786 	vq->mem_ops = &vb2_dma_contig_memops;
1787 	vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
1788 	vq->timestamp_flags  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1789 	vq->lock = &ici->host_lock;
1790 
1791 	return vb2_queue_init(vq);
1792 }
1793 
1794 static struct soc_camera_host_ops rcar_vin_host_ops = {
1795 	.owner		= THIS_MODULE,
1796 	.add		= rcar_vin_add_device,
1797 	.remove		= rcar_vin_remove_device,
1798 	.get_formats	= rcar_vin_get_formats,
1799 	.put_formats	= rcar_vin_put_formats,
1800 	.get_crop	= rcar_vin_get_crop,
1801 	.set_crop	= rcar_vin_set_crop,
1802 	.try_fmt	= rcar_vin_try_fmt,
1803 	.set_fmt	= rcar_vin_set_fmt,
1804 	.poll		= rcar_vin_poll,
1805 	.querycap	= rcar_vin_querycap,
1806 	.set_bus_param	= rcar_vin_set_bus_param,
1807 	.init_videobuf2	= rcar_vin_init_videobuf2,
1808 };
1809 
1810 #ifdef CONFIG_OF
1811 static struct of_device_id rcar_vin_of_table[] = {
1812 	{ .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
1813 	{ .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
1814 	{ .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
1815 	{ .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
1816 	{ .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
1817 	{ .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
1818 	{ },
1819 };
1820 MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1821 #endif
1822 
1823 static struct platform_device_id rcar_vin_id_table[] = {
1824 	{ "r8a7791-vin",  RCAR_GEN2 },
1825 	{ "r8a7790-vin",  RCAR_GEN2 },
1826 	{ "r8a7779-vin",  RCAR_H1 },
1827 	{ "r8a7778-vin",  RCAR_M1 },
1828 	{ "uPD35004-vin", RCAR_E1 },
1829 	{},
1830 };
1831 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1832 
rcar_vin_probe(struct platform_device * pdev)1833 static int rcar_vin_probe(struct platform_device *pdev)
1834 {
1835 	const struct of_device_id *match = NULL;
1836 	struct rcar_vin_priv *priv;
1837 	struct resource *mem;
1838 	struct rcar_vin_platform_data *pdata;
1839 	unsigned int pdata_flags;
1840 	int irq, ret;
1841 
1842 	if (pdev->dev.of_node) {
1843 		struct v4l2_of_endpoint ep;
1844 		struct device_node *np;
1845 
1846 		match = of_match_device(of_match_ptr(rcar_vin_of_table),
1847 					&pdev->dev);
1848 
1849 		np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1850 		if (!np) {
1851 			dev_err(&pdev->dev, "could not find endpoint\n");
1852 			return -EINVAL;
1853 		}
1854 
1855 		ret = v4l2_of_parse_endpoint(np, &ep);
1856 		if (ret) {
1857 			dev_err(&pdev->dev, "could not parse endpoint\n");
1858 			return ret;
1859 		}
1860 
1861 		if (ep.bus_type == V4L2_MBUS_BT656)
1862 			pdata_flags = RCAR_VIN_BT656;
1863 		else {
1864 			pdata_flags = 0;
1865 			if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1866 				pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
1867 			if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1868 				pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
1869 		}
1870 
1871 		of_node_put(np);
1872 
1873 		dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1874 	} else {
1875 		pdata = pdev->dev.platform_data;
1876 		if (!pdata || !pdata->flags) {
1877 			dev_err(&pdev->dev, "platform data not set\n");
1878 			return -EINVAL;
1879 		}
1880 		pdata_flags = pdata->flags;
1881 	}
1882 
1883 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1884 	if (mem == NULL)
1885 		return -EINVAL;
1886 
1887 	irq = platform_get_irq(pdev, 0);
1888 	if (irq <= 0)
1889 		return -EINVAL;
1890 
1891 	priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1892 			    GFP_KERNEL);
1893 	if (!priv)
1894 		return -ENOMEM;
1895 
1896 	priv->base = devm_ioremap_resource(&pdev->dev, mem);
1897 	if (IS_ERR(priv->base))
1898 		return PTR_ERR(priv->base);
1899 
1900 	ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1901 			       dev_name(&pdev->dev), priv);
1902 	if (ret)
1903 		return ret;
1904 
1905 	priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1906 	if (IS_ERR(priv->alloc_ctx))
1907 		return PTR_ERR(priv->alloc_ctx);
1908 
1909 	priv->ici.priv = priv;
1910 	priv->ici.v4l2_dev.dev = &pdev->dev;
1911 	priv->ici.drv_name = dev_name(&pdev->dev);
1912 	priv->ici.ops = &rcar_vin_host_ops;
1913 
1914 	priv->pdata_flags = pdata_flags;
1915 	if (!match) {
1916 		priv->ici.nr = pdev->id;
1917 		priv->chip = pdev->id_entry->driver_data;
1918 	} else {
1919 		priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1920 		priv->chip = (enum chip_id)match->data;
1921 	}
1922 
1923 	spin_lock_init(&priv->lock);
1924 	INIT_LIST_HEAD(&priv->capture);
1925 
1926 	priv->state = STOPPED;
1927 
1928 	pm_suspend_ignore_children(&pdev->dev, true);
1929 	pm_runtime_enable(&pdev->dev);
1930 
1931 	ret = soc_camera_host_register(&priv->ici);
1932 	if (ret)
1933 		goto cleanup;
1934 
1935 	return 0;
1936 
1937 cleanup:
1938 	pm_runtime_disable(&pdev->dev);
1939 	vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1940 
1941 	return ret;
1942 }
1943 
rcar_vin_remove(struct platform_device * pdev)1944 static int rcar_vin_remove(struct platform_device *pdev)
1945 {
1946 	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1947 	struct rcar_vin_priv *priv = container_of(soc_host,
1948 						  struct rcar_vin_priv, ici);
1949 
1950 	soc_camera_host_unregister(soc_host);
1951 	pm_runtime_disable(&pdev->dev);
1952 	vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1953 
1954 	return 0;
1955 }
1956 
1957 static struct platform_driver rcar_vin_driver = {
1958 	.probe		= rcar_vin_probe,
1959 	.remove		= rcar_vin_remove,
1960 	.driver		= {
1961 		.name		= DRV_NAME,
1962 		.of_match_table	= of_match_ptr(rcar_vin_of_table),
1963 	},
1964 	.id_table	= rcar_vin_id_table,
1965 };
1966 
1967 module_platform_driver(rcar_vin_driver);
1968 
1969 MODULE_LICENSE("GPL");
1970 MODULE_ALIAS("platform:rcar_vin");
1971 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1972