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
140enum chip_id {
141	RCAR_GEN2,
142	RCAR_H1,
143	RCAR_M1,
144	RCAR_E1,
145};
146
147struct vin_coeff {
148	unsigned short xs_value;
149	u32 coeff_set[24];
150};
151
152static 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
465enum rcar_vin_state {
466	STOPPED = 0,
467	RUNNING,
468	STOPPING,
469};
470
471struct 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
493struct 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
502struct 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 */
528static 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
587static 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
696static 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
706static 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
721static 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
732static 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 */
739static 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
762static 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
805error:
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 */
814static 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
834static 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
862static 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
870static 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
930done:
931	spin_unlock(&priv->lock);
932
933	return IRQ_RETVAL(handled);
934}
935
936static 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
953static 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
985static 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 */
1040static 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
1130static 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
1137static 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
1166static 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
1232static 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
1260static 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
1267static 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
1318static 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
1455static void rcar_vin_put_formats(struct soc_camera_device *icd)
1456{
1457	kfree(icd->host_priv);
1458	icd->host_priv = NULL;
1459}
1460
1461static 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
1538static 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 */
1550static 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
1676static 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
1760static 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
1767static 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
1777static 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
1794static 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
1811static 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};
1820MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1821#endif
1822
1823static 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};
1831MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1832
1833static 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
1937cleanup:
1938	pm_runtime_disable(&pdev->dev);
1939	vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1940
1941	return ret;
1942}
1943
1944static 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
1957static 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
1967module_platform_driver(rcar_vin_driver);
1968
1969MODULE_LICENSE("GPL");
1970MODULE_ALIAS("platform:rcar_vin");
1971MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1972