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