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