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