]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/platform/soc_camera/rcar_vin.c
[media] rcar_vin: call g_std() instead of querystd()
[karo-tx-linux.git] / drivers / media / platform / soc_camera / rcar_vin.c
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_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_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  */
529 static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
530                                    const struct v4l2_format *fmt,
531                                    unsigned int *count,
532                                    unsigned int *num_planes,
533                                    unsigned int sizes[], void *alloc_ctxs[])
534 {
535         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
536         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
537         struct rcar_vin_priv *priv = ici->priv;
538
539         if (fmt) {
540                 const struct soc_camera_format_xlate *xlate;
541                 unsigned int bytes_per_line;
542                 int ret;
543
544                 if (fmt->fmt.pix.sizeimage < icd->sizeimage)
545                         return -EINVAL;
546
547                 xlate = soc_camera_xlate_by_fourcc(icd,
548                                                    fmt->fmt.pix.pixelformat);
549                 if (!xlate)
550                         return -EINVAL;
551                 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
552                                               xlate->host_fmt);
553                 if (ret < 0)
554                         return ret;
555
556                 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
557
558                 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
559                                           fmt->fmt.pix.height);
560                 if (ret < 0)
561                         return ret;
562
563                 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
564         } else {
565                 /* Called from VIDIOC_REQBUFS or in compatibility mode */
566                 sizes[0] = icd->sizeimage;
567         }
568
569         alloc_ctxs[0] = priv->alloc_ctx;
570
571         if (!vq->num_buffers)
572                 priv->sequence = 0;
573
574         if (!*count)
575                 *count = 2;
576         priv->vb_count = *count;
577
578         *num_planes = 1;
579
580         /* Number of hardware slots */
581         if (is_continuous_transfer(priv))
582                 priv->nr_hw_slots = MAX_BUFFER_NUM;
583         else
584                 priv->nr_hw_slots = 1;
585
586         dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
587
588         return 0;
589 }
590
591 static int rcar_vin_setup(struct rcar_vin_priv *priv)
592 {
593         struct soc_camera_device *icd = priv->ici.icd;
594         struct rcar_vin_cam *cam = icd->host_priv;
595         u32 vnmc, dmr, interrupts;
596         bool progressive = false, output_is_yuv = false, input_is_yuv = false;
597
598         switch (priv->field) {
599         case V4L2_FIELD_TOP:
600                 vnmc = VNMC_IM_ODD;
601                 break;
602         case V4L2_FIELD_BOTTOM:
603                 vnmc = VNMC_IM_EVEN;
604                 break;
605         case V4L2_FIELD_INTERLACED:
606         case V4L2_FIELD_INTERLACED_TB:
607                 vnmc = VNMC_IM_FULL;
608                 break;
609         case V4L2_FIELD_INTERLACED_BT:
610                 vnmc = VNMC_IM_FULL | VNMC_FOC;
611                 break;
612         case V4L2_FIELD_NONE:
613                 if (is_continuous_transfer(priv)) {
614                         vnmc = VNMC_IM_ODD_EVEN;
615                         progressive = true;
616                 } else {
617                         vnmc = VNMC_IM_ODD;
618                 }
619                 break;
620         default:
621                 vnmc = VNMC_IM_ODD;
622                 break;
623         }
624
625         /* input interface */
626         switch (icd->current_fmt->code) {
627         case MEDIA_BUS_FMT_YUYV8_1X16:
628                 /* BT.601/BT.1358 16bit YCbCr422 */
629                 vnmc |= VNMC_INF_YUV16;
630                 input_is_yuv = true;
631                 break;
632         case MEDIA_BUS_FMT_YUYV8_2X8:
633                 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
634                 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
635                         VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
636                 input_is_yuv = true;
637                 break;
638         case MEDIA_BUS_FMT_RGB888_1X24:
639                 vnmc |= VNMC_INF_RGB888;
640                 break;
641         case MEDIA_BUS_FMT_YUYV10_2X10:
642                 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
643                 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
644                         VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
645                 input_is_yuv = true;
646                 break;
647         default:
648                 break;
649         }
650
651         /* output format */
652         switch (icd->current_fmt->host_fmt->fourcc) {
653         case V4L2_PIX_FMT_NV16:
654                 iowrite32(ALIGN(cam->width * cam->height, 0x80),
655                           priv->base + VNUVAOF_REG);
656                 dmr = VNDMR_DTMD_YCSEP;
657                 output_is_yuv = true;
658                 break;
659         case V4L2_PIX_FMT_YUYV:
660                 dmr = VNDMR_BPSM;
661                 output_is_yuv = true;
662                 break;
663         case V4L2_PIX_FMT_UYVY:
664                 dmr = 0;
665                 output_is_yuv = true;
666                 break;
667         case V4L2_PIX_FMT_RGB555X:
668                 dmr = VNDMR_DTMD_ARGB1555;
669                 break;
670         case V4L2_PIX_FMT_RGB565:
671                 dmr = 0;
672                 break;
673         case V4L2_PIX_FMT_RGB32:
674                 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
675                     priv->chip == RCAR_E1) {
676                         dmr = VNDMR_EXRGB;
677                         break;
678                 }
679         default:
680                 dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
681                          icd->current_fmt->host_fmt->fourcc);
682                 return -EINVAL;
683         }
684
685         /* Always update on field change */
686         vnmc |= VNMC_VUP;
687
688         /* If input and output use the same colorspace, use bypass mode */
689         if (input_is_yuv == output_is_yuv)
690                 vnmc |= VNMC_BPS;
691
692         /* progressive or interlaced mode */
693         interrupts = progressive ? VNIE_FIE : VNIE_EFE;
694
695         /* ack interrupts */
696         iowrite32(interrupts, priv->base + VNINTS_REG);
697         /* enable interrupts */
698         iowrite32(interrupts, priv->base + VNIE_REG);
699         /* start capturing */
700         iowrite32(dmr, priv->base + VNDMR_REG);
701         iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
702
703         return 0;
704 }
705
706 static void rcar_vin_capture(struct rcar_vin_priv *priv)
707 {
708         if (is_continuous_transfer(priv))
709                 /* Continuous Frame Capture Mode */
710                 iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
711         else
712                 /* Single Frame Capture Mode */
713                 iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
714 }
715
716 static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
717 {
718         priv->state = STOPPING;
719
720         /* set continuous & single transfer off */
721         iowrite32(0, priv->base + VNFC_REG);
722         /* disable capture (release DMA buffer), reset */
723         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
724                   priv->base + VNMC_REG);
725
726         /* update the status if stopped already */
727         if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
728                 priv->state = STOPPED;
729 }
730
731 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
732 {
733         int slot;
734
735         for (slot = 0; slot < priv->nr_hw_slots; slot++)
736                 if (priv->queue_buf[slot] == NULL)
737                         return slot;
738
739         return -1;
740 }
741
742 static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
743 {
744         /* Ensure all HW slots are filled */
745         return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
746 }
747
748 /* Moves a buffer from the queue to the HW slots */
749 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
750 {
751         struct vb2_buffer *vb;
752         dma_addr_t phys_addr_top;
753         int slot;
754
755         if (list_empty(&priv->capture))
756                 return 0;
757
758         /* Find a free HW slot */
759         slot = rcar_vin_get_free_hw_slot(priv);
760         if (slot < 0)
761                 return 0;
762
763         vb = &list_entry(priv->capture.next, struct rcar_vin_buffer, list)->vb;
764         list_del_init(to_buf_list(vb));
765         priv->queue_buf[slot] = vb;
766         phys_addr_top = vb2_dma_contig_plane_dma_addr(vb, 0);
767         iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
768
769         return 1;
770 }
771
772 static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
773 {
774         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
775         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
776         struct rcar_vin_priv *priv = ici->priv;
777         unsigned long size;
778
779         size = icd->sizeimage;
780
781         if (vb2_plane_size(vb, 0) < size) {
782                 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
783                         vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
784                 goto error;
785         }
786
787         vb2_set_plane_payload(vb, 0, size);
788
789         dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
790                 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
791
792         spin_lock_irq(&priv->lock);
793
794         list_add_tail(to_buf_list(vb), &priv->capture);
795         rcar_vin_fill_hw_slot(priv);
796
797         /* If we weren't running, and have enough buffers, start capturing! */
798         if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
799                 if (rcar_vin_setup(priv)) {
800                         /* Submit error */
801                         list_del_init(to_buf_list(vb));
802                         spin_unlock_irq(&priv->lock);
803                         goto error;
804                 }
805                 priv->request_to_stop = false;
806                 init_completion(&priv->capture_stop);
807                 priv->state = RUNNING;
808                 rcar_vin_capture(priv);
809         }
810
811         spin_unlock_irq(&priv->lock);
812
813         return;
814
815 error:
816         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
817 }
818
819 /*
820  * Wait for capture to stop and all in-flight buffers to be finished with by
821  * the video hardware. This must be called under &priv->lock
822  *
823  */
824 static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
825 {
826         while (priv->state != STOPPED) {
827                 /* issue stop if running */
828                 if (priv->state == RUNNING)
829                         rcar_vin_request_capture_stop(priv);
830
831                 /* wait until capturing has been stopped */
832                 if (priv->state == STOPPING) {
833                         priv->request_to_stop = true;
834                         spin_unlock_irq(&priv->lock);
835                         if (!wait_for_completion_timeout(
836                                         &priv->capture_stop,
837                                         msecs_to_jiffies(TIMEOUT_MS)))
838                                 priv->state = STOPPED;
839                         spin_lock_irq(&priv->lock);
840                 }
841         }
842 }
843
844 static void rcar_vin_stop_streaming(struct vb2_queue *vq)
845 {
846         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
847         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
848         struct rcar_vin_priv *priv = ici->priv;
849         struct list_head *buf_head, *tmp;
850         int i;
851
852         spin_lock_irq(&priv->lock);
853         rcar_vin_wait_stop_streaming(priv);
854
855         for (i = 0; i < MAX_BUFFER_NUM; i++) {
856                 if (priv->queue_buf[i]) {
857                         vb2_buffer_done(priv->queue_buf[i],
858                                         VB2_BUF_STATE_ERROR);
859                         priv->queue_buf[i] = NULL;
860                 }
861         }
862
863         list_for_each_safe(buf_head, tmp, &priv->capture) {
864                 vb2_buffer_done(&list_entry(buf_head,
865                                         struct rcar_vin_buffer, list)->vb,
866                                 VB2_BUF_STATE_ERROR);
867                 list_del_init(buf_head);
868         }
869         spin_unlock_irq(&priv->lock);
870 }
871
872 static struct vb2_ops rcar_vin_vb2_ops = {
873         .queue_setup    = rcar_vin_videobuf_setup,
874         .buf_queue      = rcar_vin_videobuf_queue,
875         .stop_streaming = rcar_vin_stop_streaming,
876         .wait_prepare   = vb2_ops_wait_prepare,
877         .wait_finish    = vb2_ops_wait_finish,
878 };
879
880 static irqreturn_t rcar_vin_irq(int irq, void *data)
881 {
882         struct rcar_vin_priv *priv = data;
883         u32 int_status;
884         bool can_run = false, hw_stopped;
885         int slot;
886         unsigned int handled = 0;
887
888         spin_lock(&priv->lock);
889
890         int_status = ioread32(priv->base + VNINTS_REG);
891         if (!int_status)
892                 goto done;
893         /* ack interrupts */
894         iowrite32(int_status, priv->base + VNINTS_REG);
895         handled = 1;
896
897         /* nothing to do if capture status is 'STOPPED' */
898         if (priv->state == STOPPED)
899                 goto done;
900
901         hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
902
903         if (!priv->request_to_stop) {
904                 if (is_continuous_transfer(priv))
905                         slot = (ioread32(priv->base + VNMS_REG) &
906                                 VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
907                 else
908                         slot = 0;
909
910                 priv->queue_buf[slot]->v4l2_buf.field = priv->field;
911                 priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
912                 v4l2_get_timestamp(&priv->queue_buf[slot]->v4l2_buf.timestamp);
913                 vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
914                 priv->queue_buf[slot] = NULL;
915
916                 if (priv->state != STOPPING)
917                         can_run = rcar_vin_fill_hw_slot(priv);
918
919                 if (hw_stopped || !can_run) {
920                         priv->state = STOPPED;
921                 } else if (is_continuous_transfer(priv) &&
922                            list_empty(&priv->capture) &&
923                            priv->state == RUNNING) {
924                         /*
925                          * The continuous capturing requires an explicit stop
926                          * operation when there is no buffer to be set into
927                          * the VnMBm registers.
928                          */
929                         rcar_vin_request_capture_stop(priv);
930                 } else {
931                         rcar_vin_capture(priv);
932                 }
933
934         } else if (hw_stopped) {
935                 priv->state = STOPPED;
936                 priv->request_to_stop = false;
937                 complete(&priv->capture_stop);
938         }
939
940 done:
941         spin_unlock(&priv->lock);
942
943         return IRQ_RETVAL(handled);
944 }
945
946 static int rcar_vin_add_device(struct soc_camera_device *icd)
947 {
948         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
949         struct rcar_vin_priv *priv = ici->priv;
950         int i;
951
952         for (i = 0; i < MAX_BUFFER_NUM; i++)
953                 priv->queue_buf[i] = NULL;
954
955         pm_runtime_get_sync(ici->v4l2_dev.dev);
956
957         dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
958                 icd->devnum);
959
960         return 0;
961 }
962
963 static void rcar_vin_remove_device(struct soc_camera_device *icd)
964 {
965         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
966         struct rcar_vin_priv *priv = ici->priv;
967         struct vb2_buffer *vb;
968         int i;
969
970         /* disable capture, disable interrupts */
971         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
972                   priv->base + VNMC_REG);
973         iowrite32(0, priv->base + VNIE_REG);
974
975         priv->state = STOPPED;
976         priv->request_to_stop = false;
977
978         /* make sure active buffer is cancelled */
979         spin_lock_irq(&priv->lock);
980         for (i = 0; i < MAX_BUFFER_NUM; i++) {
981                 vb = priv->queue_buf[i];
982                 if (vb) {
983                         list_del_init(to_buf_list(vb));
984                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
985                 }
986         }
987         spin_unlock_irq(&priv->lock);
988
989         pm_runtime_put(ici->v4l2_dev.dev);
990
991         dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
992                 icd->devnum);
993 }
994
995 static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
996 {
997         int i;
998         const struct vin_coeff *p_prev_set = NULL;
999         const struct vin_coeff *p_set = NULL;
1000
1001         /* Look for suitable coefficient values */
1002         for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
1003                 p_prev_set = p_set;
1004                 p_set = &vin_coeff_set[i];
1005
1006                 if (xs < p_set->xs_value)
1007                         break;
1008         }
1009
1010         /* Use previous value if its XS value is closer */
1011         if (p_prev_set && p_set &&
1012             xs - p_prev_set->xs_value < p_set->xs_value - xs)
1013                 p_set = p_prev_set;
1014
1015         /* Set coefficient registers */
1016         iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG);
1017         iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG);
1018         iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG);
1019
1020         iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG);
1021         iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG);
1022         iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG);
1023
1024         iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG);
1025         iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG);
1026         iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG);
1027
1028         iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG);
1029         iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG);
1030         iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG);
1031
1032         iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG);
1033         iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG);
1034         iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG);
1035
1036         iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG);
1037         iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG);
1038         iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG);
1039
1040         iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG);
1041         iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG);
1042         iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG);
1043
1044         iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG);
1045         iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG);
1046         iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG);
1047 }
1048
1049 /* rect is guaranteed to not exceed the scaled camera rectangle */
1050 static int rcar_vin_set_rect(struct soc_camera_device *icd)
1051 {
1052         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1053         struct rcar_vin_cam *cam = icd->host_priv;
1054         struct rcar_vin_priv *priv = ici->priv;
1055         unsigned int left_offset, top_offset;
1056         unsigned char dsize = 0;
1057         struct v4l2_rect *cam_subrect = &cam->subrect;
1058         u32 value;
1059
1060         dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
1061                 icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
1062
1063         left_offset = cam->vin_left;
1064         top_offset = cam->vin_top;
1065
1066         if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
1067             priv->chip == RCAR_E1)
1068                 dsize = 1;
1069
1070         dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
1071                 cam->width, cam->height, cam->vin_left, cam->vin_top);
1072         dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
1073                 cam_subrect->width, cam_subrect->height,
1074                 cam_subrect->left, cam_subrect->top);
1075
1076         /* Set Start/End Pixel/Line Pre-Clip */
1077         iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
1078         iowrite32((left_offset + cam_subrect->width - 1) << dsize,
1079                   priv->base + VNEPPRC_REG);
1080         switch (priv->field) {
1081         case V4L2_FIELD_INTERLACED:
1082         case V4L2_FIELD_INTERLACED_TB:
1083         case V4L2_FIELD_INTERLACED_BT:
1084                 iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
1085                 iowrite32((top_offset + cam_subrect->height) / 2 - 1,
1086                           priv->base + VNELPRC_REG);
1087                 break;
1088         default:
1089                 iowrite32(top_offset, priv->base + VNSLPRC_REG);
1090                 iowrite32(top_offset + cam_subrect->height - 1,
1091                           priv->base + VNELPRC_REG);
1092                 break;
1093         }
1094
1095         /* Set scaling coefficient */
1096         value = 0;
1097         if (cam_subrect->height != cam->out_height)
1098                 value = (4096 * cam_subrect->height) / cam->out_height;
1099         dev_dbg(icd->parent, "YS Value: %x\n", value);
1100         iowrite32(value, priv->base + VNYS_REG);
1101
1102         value = 0;
1103         if (cam_subrect->width != cam->out_width)
1104                 value = (4096 * cam_subrect->width) / cam->out_width;
1105
1106         /* Horizontal upscaling is up to double size */
1107         if (0 < value && value < 2048)
1108                 value = 2048;
1109
1110         dev_dbg(icd->parent, "XS Value: %x\n", value);
1111         iowrite32(value, priv->base + VNXS_REG);
1112
1113         /* Horizontal upscaling is carried out by scaling down from double size */
1114         if (value < 4096)
1115                 value *= 2;
1116
1117         set_coeff(priv, value);
1118
1119         /* Set Start/End Pixel/Line Post-Clip */
1120         iowrite32(0, priv->base + VNSPPOC_REG);
1121         iowrite32(0, priv->base + VNSLPOC_REG);
1122         iowrite32((cam->out_width - 1) << dsize, priv->base + VNEPPOC_REG);
1123         switch (priv->field) {
1124         case V4L2_FIELD_INTERLACED:
1125         case V4L2_FIELD_INTERLACED_TB:
1126         case V4L2_FIELD_INTERLACED_BT:
1127                 iowrite32(cam->out_height / 2 - 1,
1128                           priv->base + VNELPOC_REG);
1129                 break;
1130         default:
1131                 iowrite32(cam->out_height - 1, priv->base + VNELPOC_REG);
1132                 break;
1133         }
1134
1135         iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
1136
1137         return 0;
1138 }
1139
1140 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
1141 {
1142         *vnmc = ioread32(priv->base + VNMC_REG);
1143         /* module disable */
1144         iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
1145 }
1146
1147 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
1148 {
1149         unsigned long timeout = jiffies + 10 * HZ;
1150
1151         /*
1152          * Wait until the end of the current frame. It can take a long time,
1153          * but if it has been aborted by a MRST1 reset, it should exit sooner.
1154          */
1155         while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
1156                 time_before(jiffies, timeout))
1157                 msleep(1);
1158
1159         if (time_after(jiffies, timeout)) {
1160                 dev_err(priv->ici.v4l2_dev.dev,
1161                         "Timeout waiting for frame end! Interface problem?\n");
1162                 return;
1163         }
1164
1165         iowrite32(vnmc, priv->base + VNMC_REG);
1166 }
1167
1168 #define VIN_MBUS_FLAGS  (V4L2_MBUS_MASTER |             \
1169                          V4L2_MBUS_PCLK_SAMPLE_RISING | \
1170                          V4L2_MBUS_HSYNC_ACTIVE_HIGH |  \
1171                          V4L2_MBUS_HSYNC_ACTIVE_LOW |   \
1172                          V4L2_MBUS_VSYNC_ACTIVE_HIGH |  \
1173                          V4L2_MBUS_VSYNC_ACTIVE_LOW |   \
1174                          V4L2_MBUS_DATA_ACTIVE_HIGH)
1175
1176 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
1177 {
1178         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1179         struct rcar_vin_priv *priv = ici->priv;
1180         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1181         struct v4l2_mbus_config cfg;
1182         unsigned long common_flags;
1183         u32 vnmc;
1184         u32 val;
1185         int ret;
1186
1187         capture_stop_preserve(priv, &vnmc);
1188
1189         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1190         if (!ret) {
1191                 common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1192                 if (!common_flags) {
1193                         dev_warn(icd->parent,
1194                                  "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1195                                  cfg.flags, VIN_MBUS_FLAGS);
1196                         return -EINVAL;
1197                 }
1198         } else if (ret != -ENOIOCTLCMD) {
1199                 return ret;
1200         } else {
1201                 common_flags = VIN_MBUS_FLAGS;
1202         }
1203
1204         /* Make choises, based on platform preferences */
1205         if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1206             (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1207                 if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
1208                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1209                 else
1210                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1211         }
1212
1213         if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1214             (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1215                 if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
1216                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1217                 else
1218                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1219         }
1220
1221         cfg.flags = common_flags;
1222         ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1223         if (ret < 0 && ret != -ENOIOCTLCMD)
1224                 return ret;
1225
1226         val = VNDMR2_FTEV | VNDMR2_VLV(1);
1227         if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
1228                 val |= VNDMR2_VPS;
1229         if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
1230                 val |= VNDMR2_HPS;
1231         iowrite32(val, priv->base + VNDMR2_REG);
1232
1233         ret = rcar_vin_set_rect(icd);
1234         if (ret < 0)
1235                 return ret;
1236
1237         capture_restore(priv, vnmc);
1238
1239         return 0;
1240 }
1241
1242 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
1243                                   unsigned char buswidth)
1244 {
1245         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1246         struct v4l2_mbus_config cfg;
1247         int ret;
1248
1249         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1250         if (ret == -ENOIOCTLCMD)
1251                 return 0;
1252         else if (ret)
1253                 return ret;
1254
1255         if (buswidth > 24)
1256                 return -EINVAL;
1257
1258         /* check is there common mbus flags */
1259         ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1260         if (ret)
1261                 return 0;
1262
1263         dev_warn(icd->parent,
1264                 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1265                  cfg.flags, VIN_MBUS_FLAGS);
1266
1267         return -EINVAL;
1268 }
1269
1270 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1271 {
1272         return  fmt->packing == SOC_MBUS_PACKING_NONE ||
1273                 (fmt->bits_per_sample > 8 &&
1274                  fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1275 }
1276
1277 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
1278         {
1279                 .fourcc                 = V4L2_PIX_FMT_NV16,
1280                 .name                   = "NV16",
1281                 .bits_per_sample        = 8,
1282                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1283                 .order                  = SOC_MBUS_ORDER_LE,
1284                 .layout                 = SOC_MBUS_LAYOUT_PLANAR_Y_C,
1285         },
1286         {
1287                 .fourcc                 = V4L2_PIX_FMT_YUYV,
1288                 .name                   = "YUYV",
1289                 .bits_per_sample        = 16,
1290                 .packing                = SOC_MBUS_PACKING_NONE,
1291                 .order                  = SOC_MBUS_ORDER_LE,
1292                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1293         },
1294         {
1295                 .fourcc                 = V4L2_PIX_FMT_UYVY,
1296                 .name                   = "UYVY",
1297                 .bits_per_sample        = 16,
1298                 .packing                = SOC_MBUS_PACKING_NONE,
1299                 .order                  = SOC_MBUS_ORDER_LE,
1300                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1301         },
1302         {
1303                 .fourcc                 = V4L2_PIX_FMT_RGB565,
1304                 .name                   = "RGB565",
1305                 .bits_per_sample        = 16,
1306                 .packing                = SOC_MBUS_PACKING_NONE,
1307                 .order                  = SOC_MBUS_ORDER_LE,
1308                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1309         },
1310         {
1311                 .fourcc                 = V4L2_PIX_FMT_RGB555X,
1312                 .name                   = "ARGB1555",
1313                 .bits_per_sample        = 16,
1314                 .packing                = SOC_MBUS_PACKING_NONE,
1315                 .order                  = SOC_MBUS_ORDER_LE,
1316                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1317         },
1318         {
1319                 .fourcc                 = V4L2_PIX_FMT_RGB32,
1320                 .name                   = "RGB888",
1321                 .bits_per_sample        = 32,
1322                 .packing                = SOC_MBUS_PACKING_NONE,
1323                 .order                  = SOC_MBUS_ORDER_LE,
1324                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1325         },
1326 };
1327
1328 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
1329                                 struct soc_camera_format_xlate *xlate)
1330 {
1331         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1332         struct device *dev = icd->parent;
1333         int ret, k, n;
1334         int formats = 0;
1335         struct rcar_vin_cam *cam;
1336         struct v4l2_subdev_mbus_code_enum code = {
1337                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1338                 .index = idx,
1339         };
1340         const struct soc_mbus_pixelfmt *fmt;
1341
1342         ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
1343         if (ret < 0)
1344                 return 0;
1345
1346         fmt = soc_mbus_get_fmtdesc(code.code);
1347         if (!fmt) {
1348                 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code);
1349                 return 0;
1350         }
1351
1352         ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
1353         if (ret < 0)
1354                 return 0;
1355
1356         if (!icd->host_priv) {
1357                 struct v4l2_subdev_format fmt = {
1358                         .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1359                 };
1360                 struct v4l2_mbus_framefmt *mf = &fmt.format;
1361                 struct v4l2_rect rect;
1362                 struct device *dev = icd->parent;
1363                 int shift;
1364
1365                 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
1366                 if (ret < 0)
1367                         return ret;
1368
1369                 /* Cache current client geometry */
1370                 ret = soc_camera_client_g_rect(sd, &rect);
1371                 if (ret == -ENOIOCTLCMD) {
1372                         /* Sensor driver doesn't support cropping */
1373                         rect.left = 0;
1374                         rect.top = 0;
1375                         rect.width = mf->width;
1376                         rect.height = mf->height;
1377                 } else if (ret < 0) {
1378                         return ret;
1379                 }
1380
1381                 /*
1382                  * If sensor proposes too large format then try smaller ones:
1383                  * 1280x960, 640x480, 320x240
1384                  */
1385                 for (shift = 0; shift < 3; shift++) {
1386                         if (mf->width <= VIN_MAX_WIDTH &&
1387                             mf->height <= VIN_MAX_HEIGHT)
1388                                 break;
1389
1390                         mf->width = 1280 >> shift;
1391                         mf->height = 960 >> shift;
1392                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
1393                                                          soc_camera_grp_id(icd),
1394                                                          pad, set_fmt, NULL,
1395                                                          &fmt);
1396                         if (ret < 0)
1397                                 return ret;
1398                 }
1399
1400                 if (shift == 3) {
1401                         dev_err(dev,
1402                                 "Failed to configure the client below %ux%u\n",
1403                                 mf->width, mf->height);
1404                         return -EIO;
1405                 }
1406
1407                 dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height);
1408
1409                 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1410                 if (!cam)
1411                         return -ENOMEM;
1412                 /*
1413                  * We are called with current camera crop,
1414                  * initialise subrect with it
1415                  */
1416                 cam->rect = rect;
1417                 cam->subrect = rect;
1418                 cam->width = mf->width;
1419                 cam->height = mf->height;
1420                 cam->out_width  = mf->width;
1421                 cam->out_height = mf->height;
1422
1423                 icd->host_priv = cam;
1424         } else {
1425                 cam = icd->host_priv;
1426         }
1427
1428         /* Beginning of a pass */
1429         if (!idx)
1430                 cam->extra_fmt = NULL;
1431
1432         switch (code.code) {
1433         case MEDIA_BUS_FMT_YUYV8_1X16:
1434         case MEDIA_BUS_FMT_YUYV8_2X8:
1435         case MEDIA_BUS_FMT_YUYV10_2X10:
1436         case MEDIA_BUS_FMT_RGB888_1X24:
1437                 if (cam->extra_fmt)
1438                         break;
1439
1440                 /* Add all our formats that can be generated by VIN */
1441                 cam->extra_fmt = rcar_vin_formats;
1442
1443                 n = ARRAY_SIZE(rcar_vin_formats);
1444                 formats += n;
1445                 for (k = 0; xlate && k < n; k++, xlate++) {
1446                         xlate->host_fmt = &rcar_vin_formats[k];
1447                         xlate->code = code.code;
1448                         dev_dbg(dev, "Providing format %s using code %d\n",
1449                                 rcar_vin_formats[k].name, code.code);
1450                 }
1451                 break;
1452         default:
1453                 if (!rcar_vin_packing_supported(fmt))
1454                         return 0;
1455
1456                 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1457                         fmt->name);
1458                 break;
1459         }
1460
1461         /* Generic pass-through */
1462         formats++;
1463         if (xlate) {
1464                 xlate->host_fmt = fmt;
1465                 xlate->code = code.code;
1466                 xlate++;
1467         }
1468
1469         return formats;
1470 }
1471
1472 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1473 {
1474         kfree(icd->host_priv);
1475         icd->host_priv = NULL;
1476 }
1477
1478 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1479                              const struct v4l2_crop *a)
1480 {
1481         struct v4l2_crop a_writable = *a;
1482         const struct v4l2_rect *rect = &a_writable.c;
1483         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1484         struct rcar_vin_priv *priv = ici->priv;
1485         struct v4l2_crop cam_crop;
1486         struct rcar_vin_cam *cam = icd->host_priv;
1487         struct v4l2_rect *cam_rect = &cam_crop.c;
1488         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1489         struct device *dev = icd->parent;
1490         struct v4l2_subdev_format fmt = {
1491                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1492         };
1493         struct v4l2_mbus_framefmt *mf = &fmt.format;
1494         u32 vnmc;
1495         int ret, i;
1496
1497         dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1498                 rect->left, rect->top);
1499
1500         /* During camera cropping its output window can change too, stop VIN */
1501         capture_stop_preserve(priv, &vnmc);
1502         dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1503
1504         /* Apply iterative camera S_CROP for new input window. */
1505         ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1506                                        &cam->rect, &cam->subrect);
1507         if (ret < 0)
1508                 return ret;
1509
1510         dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1511                 cam_rect->width, cam_rect->height,
1512                 cam_rect->left, cam_rect->top);
1513
1514         /* On success cam_crop contains current camera crop */
1515
1516         /* Retrieve camera output window */
1517         ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
1518         if (ret < 0)
1519                 return ret;
1520
1521         if (mf->width > VIN_MAX_WIDTH || mf->height > VIN_MAX_HEIGHT)
1522                 return -EINVAL;
1523
1524         /* Cache camera output window */
1525         cam->width = mf->width;
1526         cam->height = mf->height;
1527
1528         icd->user_width  = cam->width;
1529         icd->user_height = cam->height;
1530
1531         cam->vin_left = rect->left & ~1;
1532         cam->vin_top = rect->top & ~1;
1533
1534         /* Use VIN cropping to crop to the new window. */
1535         ret = rcar_vin_set_rect(icd);
1536         if (ret < 0)
1537                 return ret;
1538
1539         cam->subrect = *rect;
1540
1541         dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1542                 icd->user_width, icd->user_height,
1543                 cam->vin_left, cam->vin_top);
1544
1545         /* Restore capture */
1546         for (i = 0; i < MAX_BUFFER_NUM; i++) {
1547                 if (priv->queue_buf[i] && priv->state == STOPPED) {
1548                         vnmc |= VNMC_ME;
1549                         break;
1550                 }
1551         }
1552         capture_restore(priv, vnmc);
1553
1554         /* Even if only camera cropping succeeded */
1555         return ret;
1556 }
1557
1558 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1559                              struct v4l2_crop *a)
1560 {
1561         struct rcar_vin_cam *cam = icd->host_priv;
1562
1563         a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1564         a->c = cam->subrect;
1565
1566         return 0;
1567 }
1568
1569 /* Similar to set_crop multistage iterative algorithm */
1570 static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1571                             struct v4l2_format *f)
1572 {
1573         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1574         struct rcar_vin_priv *priv = ici->priv;
1575         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1576         struct rcar_vin_cam *cam = icd->host_priv;
1577         struct v4l2_pix_format *pix = &f->fmt.pix;
1578         struct v4l2_mbus_framefmt mf;
1579         struct device *dev = icd->parent;
1580         __u32 pixfmt = pix->pixelformat;
1581         const struct soc_camera_format_xlate *xlate;
1582         unsigned int vin_sub_width = 0, vin_sub_height = 0;
1583         int ret;
1584         bool can_scale;
1585         enum v4l2_field field;
1586         v4l2_std_id std;
1587
1588         dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1589                 pixfmt, pix->width, pix->height);
1590
1591         switch (pix->field) {
1592         default:
1593                 pix->field = V4L2_FIELD_NONE;
1594                 /* fall-through */
1595         case V4L2_FIELD_NONE:
1596         case V4L2_FIELD_TOP:
1597         case V4L2_FIELD_BOTTOM:
1598         case V4L2_FIELD_INTERLACED_TB:
1599         case V4L2_FIELD_INTERLACED_BT:
1600                 field = pix->field;
1601                 break;
1602         case V4L2_FIELD_INTERLACED:
1603                 /* Get the last standard if not explicitly mentioned _TB/_BT */
1604                 ret = v4l2_subdev_call(sd, video, g_std, &std);
1605                 if (ret == -ENOIOCTLCMD) {
1606                         field = V4L2_FIELD_NONE;
1607                 } else if (ret < 0) {
1608                         return ret;
1609                 } else {
1610                         field = std & V4L2_STD_625_50 ?
1611                                 V4L2_FIELD_INTERLACED_TB :
1612                                 V4L2_FIELD_INTERLACED_BT;
1613                 }
1614                 break;
1615         }
1616
1617         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1618         if (!xlate) {
1619                 dev_warn(dev, "Format %x not found\n", pixfmt);
1620                 return -EINVAL;
1621         }
1622         /* Calculate client output geometry */
1623         soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1624                                       12);
1625         mf.field = pix->field;
1626         mf.colorspace = pix->colorspace;
1627         mf.code  = xlate->code;
1628
1629         switch (pixfmt) {
1630         case V4L2_PIX_FMT_RGB32:
1631                 can_scale = priv->chip != RCAR_E1;
1632                 break;
1633         case V4L2_PIX_FMT_UYVY:
1634         case V4L2_PIX_FMT_YUYV:
1635         case V4L2_PIX_FMT_RGB565:
1636         case V4L2_PIX_FMT_RGB555X:
1637                 can_scale = true;
1638                 break;
1639         default:
1640                 can_scale = false;
1641                 break;
1642         }
1643
1644         dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1645
1646         ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1647                                       &mf, &vin_sub_width, &vin_sub_height,
1648                                       can_scale, 12);
1649
1650         /* Done with the camera. Now see if we can improve the result */
1651         dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1652                 ret, mf.width, mf.height, pix->width, pix->height);
1653
1654         if (ret == -ENOIOCTLCMD)
1655                 dev_dbg(dev, "Sensor doesn't support scaling\n");
1656         else if (ret < 0)
1657                 return ret;
1658
1659         if (mf.code != xlate->code)
1660                 return -EINVAL;
1661
1662         /* Prepare VIN crop */
1663         cam->width = mf.width;
1664         cam->height = mf.height;
1665
1666         /* Use VIN scaling to scale to the requested user window. */
1667
1668         /* We cannot scale up */
1669         if (pix->width > vin_sub_width)
1670                 vin_sub_width = pix->width;
1671
1672         if (pix->height > vin_sub_height)
1673                 vin_sub_height = pix->height;
1674
1675         pix->colorspace = mf.colorspace;
1676
1677         if (!can_scale) {
1678                 pix->width = vin_sub_width;
1679                 pix->height = vin_sub_height;
1680         }
1681
1682         /*
1683          * We have calculated CFLCR, the actual configuration will be performed
1684          * in rcar_vin_set_bus_param()
1685          */
1686
1687         dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1688                 vin_sub_width, pix->width, vin_sub_height, pix->height);
1689
1690         cam->out_width = pix->width;
1691         cam->out_height = pix->height;
1692
1693         icd->current_fmt = xlate;
1694
1695         priv->field = field;
1696
1697         return 0;
1698 }
1699
1700 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1701                             struct v4l2_format *f)
1702 {
1703         const struct soc_camera_format_xlate *xlate;
1704         struct v4l2_pix_format *pix = &f->fmt.pix;
1705         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1706         struct v4l2_subdev_pad_config pad_cfg;
1707         struct v4l2_subdev_format format = {
1708                 .which = V4L2_SUBDEV_FORMAT_TRY,
1709         };
1710         struct v4l2_mbus_framefmt *mf = &format.format;
1711         __u32 pixfmt = pix->pixelformat;
1712         int width, height;
1713         int ret;
1714
1715         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1716         if (!xlate) {
1717                 xlate = icd->current_fmt;
1718                 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1719                         pixfmt, xlate->host_fmt->fourcc);
1720                 pixfmt = xlate->host_fmt->fourcc;
1721                 pix->pixelformat = pixfmt;
1722                 pix->colorspace = icd->colorspace;
1723         }
1724
1725         /* FIXME: calculate using depth and bus width */
1726         v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1727                               &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1728
1729         width = pix->width;
1730         height = pix->height;
1731
1732         /* let soc-camera calculate these values */
1733         pix->bytesperline = 0;
1734         pix->sizeimage = 0;
1735
1736         /* limit to sensor capabilities */
1737         mf->width = pix->width;
1738         mf->height = pix->height;
1739         mf->field = pix->field;
1740         mf->code = xlate->code;
1741         mf->colorspace = pix->colorspace;
1742
1743         ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1744                                          pad, set_fmt, &pad_cfg, &format);
1745         if (ret < 0)
1746                 return ret;
1747
1748         /* Adjust only if VIN cannot scale */
1749         if (pix->width > mf->width * 2)
1750                 pix->width = mf->width * 2;
1751         if (pix->height > mf->height * 3)
1752                 pix->height = mf->height * 3;
1753
1754         pix->field = mf->field;
1755         pix->colorspace = mf->colorspace;
1756
1757         if (pixfmt == V4L2_PIX_FMT_NV16) {
1758                 /* FIXME: check against rect_max after converting soc-camera */
1759                 /* We can scale precisely, need a bigger image from camera */
1760                 if (pix->width < width || pix->height < height) {
1761                         /*
1762                          * We presume, the sensor behaves sanely, i.e. if
1763                          * requested a bigger rectangle, it will not return a
1764                          * smaller one.
1765                          */
1766                         mf->width = VIN_MAX_WIDTH;
1767                         mf->height = VIN_MAX_HEIGHT;
1768                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
1769                                                          soc_camera_grp_id(icd),
1770                                                          pad, set_fmt, &pad_cfg,
1771                                                          &format);
1772                         if (ret < 0) {
1773                                 dev_err(icd->parent,
1774                                         "client try_fmt() = %d\n", ret);
1775                                 return ret;
1776                         }
1777                 }
1778                 /* We will scale exactly */
1779                 if (mf->width > width)
1780                         pix->width = width;
1781                 if (mf->height > height)
1782                         pix->height = height;
1783         }
1784
1785         return ret;
1786 }
1787
1788 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1789 {
1790         struct soc_camera_device *icd = file->private_data;
1791
1792         return vb2_poll(&icd->vb2_vidq, file, pt);
1793 }
1794
1795 static int rcar_vin_querycap(struct soc_camera_host *ici,
1796                              struct v4l2_capability *cap)
1797 {
1798         strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1799         cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1800         cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1801         snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", DRV_NAME, ici->nr);
1802
1803         return 0;
1804 }
1805
1806 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1807                                    struct soc_camera_device *icd)
1808 {
1809         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1810
1811         vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1812         vq->io_modes = VB2_MMAP | VB2_USERPTR;
1813         vq->drv_priv = icd;
1814         vq->ops = &rcar_vin_vb2_ops;
1815         vq->mem_ops = &vb2_dma_contig_memops;
1816         vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
1817         vq->timestamp_flags  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1818         vq->lock = &ici->host_lock;
1819
1820         return vb2_queue_init(vq);
1821 }
1822
1823 static struct soc_camera_host_ops rcar_vin_host_ops = {
1824         .owner          = THIS_MODULE,
1825         .add            = rcar_vin_add_device,
1826         .remove         = rcar_vin_remove_device,
1827         .get_formats    = rcar_vin_get_formats,
1828         .put_formats    = rcar_vin_put_formats,
1829         .get_crop       = rcar_vin_get_crop,
1830         .set_crop       = rcar_vin_set_crop,
1831         .try_fmt        = rcar_vin_try_fmt,
1832         .set_fmt        = rcar_vin_set_fmt,
1833         .poll           = rcar_vin_poll,
1834         .querycap       = rcar_vin_querycap,
1835         .set_bus_param  = rcar_vin_set_bus_param,
1836         .init_videobuf2 = rcar_vin_init_videobuf2,
1837 };
1838
1839 #ifdef CONFIG_OF
1840 static const struct of_device_id rcar_vin_of_table[] = {
1841         { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
1842         { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
1843         { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
1844         { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
1845         { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
1846         { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
1847         { },
1848 };
1849 MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1850 #endif
1851
1852 static struct platform_device_id rcar_vin_id_table[] = {
1853         { "r8a7779-vin",  RCAR_H1 },
1854         { "r8a7778-vin",  RCAR_M1 },
1855         { "uPD35004-vin", RCAR_E1 },
1856         {},
1857 };
1858 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1859
1860 static int rcar_vin_probe(struct platform_device *pdev)
1861 {
1862         const struct of_device_id *match = NULL;
1863         struct rcar_vin_priv *priv;
1864         struct resource *mem;
1865         struct rcar_vin_platform_data *pdata;
1866         unsigned int pdata_flags;
1867         int irq, ret;
1868
1869         if (pdev->dev.of_node) {
1870                 struct v4l2_of_endpoint ep;
1871                 struct device_node *np;
1872
1873                 match = of_match_device(of_match_ptr(rcar_vin_of_table),
1874                                         &pdev->dev);
1875
1876                 np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1877                 if (!np) {
1878                         dev_err(&pdev->dev, "could not find endpoint\n");
1879                         return -EINVAL;
1880                 }
1881
1882                 ret = v4l2_of_parse_endpoint(np, &ep);
1883                 if (ret) {
1884                         dev_err(&pdev->dev, "could not parse endpoint\n");
1885                         return ret;
1886                 }
1887
1888                 if (ep.bus_type == V4L2_MBUS_BT656)
1889                         pdata_flags = RCAR_VIN_BT656;
1890                 else {
1891                         pdata_flags = 0;
1892                         if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1893                                 pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
1894                         if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1895                                 pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
1896                 }
1897
1898                 of_node_put(np);
1899
1900                 dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1901         } else {
1902                 pdata = pdev->dev.platform_data;
1903                 if (!pdata || !pdata->flags) {
1904                         dev_err(&pdev->dev, "platform data not set\n");
1905                         return -EINVAL;
1906                 }
1907                 pdata_flags = pdata->flags;
1908         }
1909
1910         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1911         if (mem == NULL)
1912                 return -EINVAL;
1913
1914         irq = platform_get_irq(pdev, 0);
1915         if (irq <= 0)
1916                 return -EINVAL;
1917
1918         priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1919                             GFP_KERNEL);
1920         if (!priv)
1921                 return -ENOMEM;
1922
1923         priv->base = devm_ioremap_resource(&pdev->dev, mem);
1924         if (IS_ERR(priv->base))
1925                 return PTR_ERR(priv->base);
1926
1927         ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1928                                dev_name(&pdev->dev), priv);
1929         if (ret)
1930                 return ret;
1931
1932         priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1933         if (IS_ERR(priv->alloc_ctx))
1934                 return PTR_ERR(priv->alloc_ctx);
1935
1936         priv->ici.priv = priv;
1937         priv->ici.v4l2_dev.dev = &pdev->dev;
1938         priv->ici.drv_name = dev_name(&pdev->dev);
1939         priv->ici.ops = &rcar_vin_host_ops;
1940
1941         priv->pdata_flags = pdata_flags;
1942         if (!match) {
1943                 priv->ici.nr = pdev->id;
1944                 priv->chip = pdev->id_entry->driver_data;
1945         } else {
1946                 priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1947                 priv->chip = (enum chip_id)match->data;
1948         }
1949
1950         spin_lock_init(&priv->lock);
1951         INIT_LIST_HEAD(&priv->capture);
1952
1953         priv->state = STOPPED;
1954
1955         pm_suspend_ignore_children(&pdev->dev, true);
1956         pm_runtime_enable(&pdev->dev);
1957
1958         ret = soc_camera_host_register(&priv->ici);
1959         if (ret)
1960                 goto cleanup;
1961
1962         return 0;
1963
1964 cleanup:
1965         pm_runtime_disable(&pdev->dev);
1966         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1967
1968         return ret;
1969 }
1970
1971 static int rcar_vin_remove(struct platform_device *pdev)
1972 {
1973         struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1974         struct rcar_vin_priv *priv = container_of(soc_host,
1975                                                   struct rcar_vin_priv, ici);
1976
1977         soc_camera_host_unregister(soc_host);
1978         pm_runtime_disable(&pdev->dev);
1979         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1980
1981         return 0;
1982 }
1983
1984 static struct platform_driver rcar_vin_driver = {
1985         .probe          = rcar_vin_probe,
1986         .remove         = rcar_vin_remove,
1987         .driver         = {
1988                 .name           = DRV_NAME,
1989                 .of_match_table = of_match_ptr(rcar_vin_of_table),
1990         },
1991         .id_table       = rcar_vin_id_table,
1992 };
1993
1994 module_platform_driver(rcar_vin_driver);
1995
1996 MODULE_LICENSE("GPL");
1997 MODULE_ALIAS("platform:rcar_vin");
1998 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");