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