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