[media] s5p-mfc: Set last buffer flag
[deliverable/linux.git] / drivers / media / platform / soc_camera / rcar_vin.c
CommitLineData
73135e96
VB
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>
3cdcf736 19#include <linux/io.h>
73135e96
VB
20#include <linux/kernel.h>
21#include <linux/module.h>
47c71bd6
BD
22#include <linux/of.h>
23#include <linux/of_device.h>
73135e96
VB
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>
47c71bd6 36#include <media/v4l2-of.h>
73135e96
VB
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 */
4c28078c
KM
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 */
73135e96
VB
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)
cbe504d4
PE
98#define VNMC_INF_YUV10_BT656 (2 << 16)
99#define VNMC_INF_YUV10_BT601 (3 << 16)
73135e96
VB
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)
609f33c9 133#define VNDMR2_VLV(n) ((n & 0xf) << 12)
73135e96
VB
134
135#define VIN_MAX_WIDTH 2048
136#define VIN_MAX_HEIGHT 2048
137
5a9b06a2
KM
138#define TIMEOUT_MS 100
139
73135e96 140enum chip_id {
2a9ecc17 141 RCAR_GEN2,
73135e96
VB
142 RCAR_H1,
143 RCAR_M1,
144 RCAR_E1,
145};
146
4c28078c
KM
147struct vin_coeff {
148 unsigned short xs_value;
149 u32 coeff_set[24];
150};
151
152static 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
73135e96
VB
465enum rcar_vin_state {
466 STOPPED = 0,
467 RUNNING,
468 STOPPING,
469};
470
471struct 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;
73135e96
VB
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;
25dfa02c 483 unsigned int pdata_flags;
73135e96
VB
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
493struct 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
502struct 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;
4c28078c
KM
509 /* User window from S_FMT */
510 unsigned int out_width;
511 unsigned int out_height;
73135e96
VB
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 */
528static 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
587static 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) {
27ffaeb0 623 case MEDIA_BUS_FMT_YUYV8_1X16:
73135e96
VB
624 /* BT.601/BT.1358 16bit YCbCr422 */
625 vnmc |= VNMC_INF_YUV16;
626 break;
27ffaeb0 627 case MEDIA_BUS_FMT_YUYV8_2X8:
73135e96 628 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
25dfa02c 629 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
73135e96 630 VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
cbe504d4 631 break;
27ffaeb0 632 case MEDIA_BUS_FMT_YUYV10_2X10:
cbe504d4 633 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
25dfa02c 634 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
cbe504d4
PE
635 VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
636 break;
73135e96
VB
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:
2a9ecc17 664 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
ca0c9f17 665 priv->chip == RCAR_E1) {
73135e96
VB
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 */
e272d95f 683 interrupts = progressive ? VNIE_FIE : VNIE_EFE;
73135e96
VB
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
696static 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
706static 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
721static 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
732static 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 */
739static 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
762static 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
805error:
806 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
807}
808
4abec468
IM
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 */
814static 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);
5a9b06a2
KM
825 if (!wait_for_completion_timeout(
826 &priv->capture_stop,
827 msecs_to_jiffies(TIMEOUT_MS)))
828 priv->state = STOPPED;
4abec468
IM
829 spin_lock_irq(&priv->lock);
830 }
831 }
832}
833
e99f0115 834static void rcar_vin_stop_streaming(struct vb2_queue *vq)
73135e96 835{
e99f0115 836 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
73135e96
VB
837 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
838 struct rcar_vin_priv *priv = ici->priv;
e99f0115
WT
839 struct list_head *buf_head, *tmp;
840 int i;
73135e96
VB
841
842 spin_lock_irq(&priv->lock);
e99f0115 843 rcar_vin_wait_stop_streaming(priv);
73135e96 844
73135e96 845 for (i = 0; i < MAX_BUFFER_NUM; i++) {
e99f0115
WT
846 if (priv->queue_buf[i]) {
847 vb2_buffer_done(priv->queue_buf[i],
73135e96 848 VB2_BUF_STATE_ERROR);
e99f0115 849 priv->queue_buf[i] = NULL;
73135e96 850 }
73135e96
VB
851 }
852
e99f0115
WT
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);
73135e96 857 list_del_init(buf_head);
e99f0115 858 }
73135e96 859 spin_unlock_irq(&priv->lock);
73135e96
VB
860}
861
862static struct vb2_ops rcar_vin_vb2_ops = {
863 .queue_setup = rcar_vin_videobuf_setup,
73135e96
VB
864 .buf_queue = rcar_vin_videobuf_queue,
865 .stop_streaming = rcar_vin_stop_streaming,
976036df
LP
866 .wait_prepare = vb2_ops_wait_prepare,
867 .wait_finish = vb2_ops_wait_finish,
73135e96
VB
868};
869
870static 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
930done:
931 spin_unlock(&priv->lock);
932
933 return IRQ_RETVAL(handled);
934}
935
936static 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
953static 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
4c28078c
KM
985static 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
73135e96
VB
1039/* rect is guaranteed to not exceed the scaled camera rectangle */
1040static 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;
4c28078c 1048 u32 value;
73135e96
VB
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);
4c28078c 1068 iowrite32((left_offset + cam_subrect->width - 1) << dsize,
73135e96
VB
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);
4c28078c 1075 iowrite32((top_offset + cam_subrect->height) / 2 - 1,
73135e96
VB
1076 priv->base + VNELPRC_REG);
1077 break;
1078 default:
1079 iowrite32(top_offset, priv->base + VNSLPRC_REG);
4c28078c 1080 iowrite32(top_offset + cam_subrect->height - 1,
73135e96
VB
1081 priv->base + VNELPRC_REG);
1082 break;
1083 }
1084
4c28078c
KM
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
73135e96
VB
1109 /* Set Start/End Pixel/Line Post-Clip */
1110 iowrite32(0, priv->base + VNSPPOC_REG);
1111 iowrite32(0, priv->base + VNSLPOC_REG);
4c28078c 1112 iowrite32((cam->out_width - 1) << dsize, priv->base + VNEPPOC_REG);
73135e96
VB
1113 switch (priv->field) {
1114 case V4L2_FIELD_INTERLACED:
1115 case V4L2_FIELD_INTERLACED_TB:
1116 case V4L2_FIELD_INTERLACED_BT:
4c28078c 1117 iowrite32(cam->out_height / 2 - 1,
73135e96
VB
1118 priv->base + VNELPOC_REG);
1119 break;
1120 default:
4c28078c 1121 iowrite32(cam->out_height - 1, priv->base + VNELPOC_REG);
73135e96
VB
1122 break;
1123 }
1124
4c28078c 1125 iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
73135e96
VB
1126
1127 return 0;
1128}
1129
1130static 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
1137static 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
1166static 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)) {
25dfa02c 1197 if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
73135e96
VB
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)) {
25dfa02c 1205 if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
73135e96
VB
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
609f33c9 1216 val = VNDMR2_FTEV | VNDMR2_VLV(1);
73135e96
VB
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
1232static 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
1260static 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
1267static 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 },
e5d49a3e
KM
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 },
73135e96
VB
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
1318static 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;
ebcff5fc
HV
1326 struct v4l2_subdev_mbus_code_enum code = {
1327 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1328 .index = idx,
1329 };
73135e96
VB
1330 const struct soc_mbus_pixelfmt *fmt;
1331
ebcff5fc 1332 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
73135e96
VB
1333 if (ret < 0)
1334 return 0;
1335
ebcff5fc 1336 fmt = soc_mbus_get_fmtdesc(code.code);
73135e96 1337 if (!fmt) {
ebcff5fc 1338 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code);
73135e96
VB
1339 return 0;
1340 }
1341
1342 ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
1343 if (ret < 0)
1344 return 0;
1345
1346 if (!icd->host_priv) {
da298c6d
HV
1347 struct v4l2_subdev_format fmt = {
1348 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1349 };
1350 struct v4l2_mbus_framefmt *mf = &fmt.format;
73135e96
VB
1351 struct v4l2_rect rect;
1352 struct device *dev = icd->parent;
1353 int shift;
1354
da298c6d 1355 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
73135e96
VB
1356 if (ret < 0)
1357 return ret;
1358
1359 /* Cache current client geometry */
1360 ret = soc_camera_client_g_rect(sd, &rect);
1361 if (ret == -ENOIOCTLCMD) {
1362 /* Sensor driver doesn't support cropping */
1363 rect.left = 0;
1364 rect.top = 0;
da298c6d
HV
1365 rect.width = mf->width;
1366 rect.height = mf->height;
73135e96
VB
1367 } else if (ret < 0) {
1368 return ret;
1369 }
1370
1371 /*
1372 * If sensor proposes too large format then try smaller ones:
1373 * 1280x960, 640x480, 320x240
1374 */
1375 for (shift = 0; shift < 3; shift++) {
da298c6d
HV
1376 if (mf->width <= VIN_MAX_WIDTH &&
1377 mf->height <= VIN_MAX_HEIGHT)
73135e96
VB
1378 break;
1379
da298c6d
HV
1380 mf->width = 1280 >> shift;
1381 mf->height = 960 >> shift;
73135e96
VB
1382 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1383 soc_camera_grp_id(icd),
ebf984bb
HV
1384 pad, set_fmt, NULL,
1385 &fmt);
73135e96
VB
1386 if (ret < 0)
1387 return ret;
1388 }
1389
1390 if (shift == 3) {
1391 dev_err(dev,
197a47f2 1392 "Failed to configure the client below %ux%u\n",
da298c6d 1393 mf->width, mf->height);
73135e96
VB
1394 return -EIO;
1395 }
1396
da298c6d 1397 dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height);
73135e96
VB
1398
1399 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1400 if (!cam)
1401 return -ENOMEM;
1402 /*
1403 * We are called with current camera crop,
1404 * initialise subrect with it
1405 */
1406 cam->rect = rect;
1407 cam->subrect = rect;
da298c6d
HV
1408 cam->width = mf->width;
1409 cam->height = mf->height;
1410 cam->out_width = mf->width;
1411 cam->out_height = mf->height;
73135e96
VB
1412
1413 icd->host_priv = cam;
1414 } else {
1415 cam = icd->host_priv;
1416 }
1417
1418 /* Beginning of a pass */
1419 if (!idx)
1420 cam->extra_fmt = NULL;
1421
ebcff5fc 1422 switch (code.code) {
27ffaeb0
BB
1423 case MEDIA_BUS_FMT_YUYV8_1X16:
1424 case MEDIA_BUS_FMT_YUYV8_2X8:
1425 case MEDIA_BUS_FMT_YUYV10_2X10:
73135e96
VB
1426 if (cam->extra_fmt)
1427 break;
1428
1429 /* Add all our formats that can be generated by VIN */
1430 cam->extra_fmt = rcar_vin_formats;
1431
1432 n = ARRAY_SIZE(rcar_vin_formats);
1433 formats += n;
1434 for (k = 0; xlate && k < n; k++, xlate++) {
1435 xlate->host_fmt = &rcar_vin_formats[k];
ebcff5fc 1436 xlate->code = code.code;
73135e96 1437 dev_dbg(dev, "Providing format %s using code %d\n",
ebcff5fc 1438 rcar_vin_formats[k].name, code.code);
73135e96
VB
1439 }
1440 break;
1441 default:
1442 if (!rcar_vin_packing_supported(fmt))
1443 return 0;
1444
1445 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1446 fmt->name);
1447 break;
1448 }
1449
1450 /* Generic pass-through */
1451 formats++;
1452 if (xlate) {
1453 xlate->host_fmt = fmt;
ebcff5fc 1454 xlate->code = code.code;
73135e96
VB
1455 xlate++;
1456 }
1457
1458 return formats;
1459}
1460
1461static void rcar_vin_put_formats(struct soc_camera_device *icd)
1462{
1463 kfree(icd->host_priv);
1464 icd->host_priv = NULL;
1465}
1466
1467static int rcar_vin_set_crop(struct soc_camera_device *icd,
1468 const struct v4l2_crop *a)
1469{
1470 struct v4l2_crop a_writable = *a;
1471 const struct v4l2_rect *rect = &a_writable.c;
1472 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1473 struct rcar_vin_priv *priv = ici->priv;
1474 struct v4l2_crop cam_crop;
1475 struct rcar_vin_cam *cam = icd->host_priv;
1476 struct v4l2_rect *cam_rect = &cam_crop.c;
1477 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1478 struct device *dev = icd->parent;
da298c6d
HV
1479 struct v4l2_subdev_format fmt = {
1480 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1481 };
1482 struct v4l2_mbus_framefmt *mf = &fmt.format;
73135e96
VB
1483 u32 vnmc;
1484 int ret, i;
1485
1486 dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1487 rect->left, rect->top);
1488
1489 /* During camera cropping its output window can change too, stop VIN */
1490 capture_stop_preserve(priv, &vnmc);
1491 dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1492
1493 /* Apply iterative camera S_CROP for new input window. */
1494 ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1495 &cam->rect, &cam->subrect);
1496 if (ret < 0)
1497 return ret;
1498
1499 dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1500 cam_rect->width, cam_rect->height,
1501 cam_rect->left, cam_rect->top);
1502
1503 /* On success cam_crop contains current camera crop */
1504
1505 /* Retrieve camera output window */
da298c6d 1506 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
73135e96
VB
1507 if (ret < 0)
1508 return ret;
1509
da298c6d 1510 if (mf->width > VIN_MAX_WIDTH || mf->height > VIN_MAX_HEIGHT)
73135e96
VB
1511 return -EINVAL;
1512
1513 /* Cache camera output window */
da298c6d
HV
1514 cam->width = mf->width;
1515 cam->height = mf->height;
73135e96
VB
1516
1517 icd->user_width = cam->width;
1518 icd->user_height = cam->height;
1519
1520 cam->vin_left = rect->left & ~1;
1521 cam->vin_top = rect->top & ~1;
1522
1523 /* Use VIN cropping to crop to the new window. */
1524 ret = rcar_vin_set_rect(icd);
1525 if (ret < 0)
1526 return ret;
1527
1528 cam->subrect = *rect;
1529
1530 dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1531 icd->user_width, icd->user_height,
1532 cam->vin_left, cam->vin_top);
1533
1534 /* Restore capture */
1535 for (i = 0; i < MAX_BUFFER_NUM; i++) {
1536 if (priv->queue_buf[i] && priv->state == STOPPED) {
1537 vnmc |= VNMC_ME;
1538 break;
1539 }
1540 }
1541 capture_restore(priv, vnmc);
1542
1543 /* Even if only camera cropping succeeded */
1544 return ret;
1545}
1546
1547static int rcar_vin_get_crop(struct soc_camera_device *icd,
1548 struct v4l2_crop *a)
1549{
1550 struct rcar_vin_cam *cam = icd->host_priv;
1551
1552 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1553 a->c = cam->subrect;
1554
1555 return 0;
1556}
1557
1558/* Similar to set_crop multistage iterative algorithm */
1559static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1560 struct v4l2_format *f)
1561{
1562 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1563 struct rcar_vin_priv *priv = ici->priv;
1564 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1565 struct rcar_vin_cam *cam = icd->host_priv;
1566 struct v4l2_pix_format *pix = &f->fmt.pix;
1567 struct v4l2_mbus_framefmt mf;
1568 struct device *dev = icd->parent;
1569 __u32 pixfmt = pix->pixelformat;
1570 const struct soc_camera_format_xlate *xlate;
1571 unsigned int vin_sub_width = 0, vin_sub_height = 0;
1572 int ret;
1573 bool can_scale;
1574 enum v4l2_field field;
1575 v4l2_std_id std;
1576
1577 dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1578 pixfmt, pix->width, pix->height);
1579
1580 switch (pix->field) {
1581 default:
1582 pix->field = V4L2_FIELD_NONE;
1583 /* fall-through */
1584 case V4L2_FIELD_NONE:
1585 case V4L2_FIELD_TOP:
1586 case V4L2_FIELD_BOTTOM:
1587 case V4L2_FIELD_INTERLACED_TB:
1588 case V4L2_FIELD_INTERLACED_BT:
1589 field = pix->field;
1590 break;
1591 case V4L2_FIELD_INTERLACED:
1592 /* Query for standard if not explicitly mentioned _TB/_BT */
1593 ret = v4l2_subdev_call(sd, video, querystd, &std);
1594 if (ret < 0)
1595 std = V4L2_STD_625_50;
1596
1597 field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1598 V4L2_FIELD_INTERLACED_BT;
1599 break;
1600 }
1601
1602 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1603 if (!xlate) {
1604 dev_warn(dev, "Format %x not found\n", pixfmt);
1605 return -EINVAL;
1606 }
1607 /* Calculate client output geometry */
1608 soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1609 12);
1610 mf.field = pix->field;
1611 mf.colorspace = pix->colorspace;
1612 mf.code = xlate->code;
1613
1614 switch (pixfmt) {
1615 case V4L2_PIX_FMT_RGB32:
1616 can_scale = priv->chip != RCAR_E1;
1617 break;
1618 case V4L2_PIX_FMT_UYVY:
1619 case V4L2_PIX_FMT_YUYV:
1620 case V4L2_PIX_FMT_RGB565:
1621 case V4L2_PIX_FMT_RGB555X:
1622 can_scale = true;
1623 break;
1624 default:
1625 can_scale = false;
1626 break;
1627 }
1628
1629 dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1630
1631 ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1632 &mf, &vin_sub_width, &vin_sub_height,
1633 can_scale, 12);
1634
1635 /* Done with the camera. Now see if we can improve the result */
1636 dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1637 ret, mf.width, mf.height, pix->width, pix->height);
1638
1639 if (ret == -ENOIOCTLCMD)
1640 dev_dbg(dev, "Sensor doesn't support scaling\n");
1641 else if (ret < 0)
1642 return ret;
1643
1644 if (mf.code != xlate->code)
1645 return -EINVAL;
1646
1647 /* Prepare VIN crop */
1648 cam->width = mf.width;
1649 cam->height = mf.height;
1650
1651 /* Use VIN scaling to scale to the requested user window. */
1652
1653 /* We cannot scale up */
1654 if (pix->width > vin_sub_width)
1655 vin_sub_width = pix->width;
1656
1657 if (pix->height > vin_sub_height)
1658 vin_sub_height = pix->height;
1659
1660 pix->colorspace = mf.colorspace;
1661
1662 if (!can_scale) {
1663 pix->width = vin_sub_width;
1664 pix->height = vin_sub_height;
1665 }
1666
1667 /*
1668 * We have calculated CFLCR, the actual configuration will be performed
1669 * in rcar_vin_set_bus_param()
1670 */
1671
1672 dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1673 vin_sub_width, pix->width, vin_sub_height, pix->height);
1674
4c28078c
KM
1675 cam->out_width = pix->width;
1676 cam->out_height = pix->height;
1677
73135e96
VB
1678 icd->current_fmt = xlate;
1679
1680 priv->field = field;
1681
1682 return 0;
1683}
1684
1685static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1686 struct v4l2_format *f)
1687{
1688 const struct soc_camera_format_xlate *xlate;
1689 struct v4l2_pix_format *pix = &f->fmt.pix;
1690 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
5eab4983
HV
1691 struct v4l2_subdev_pad_config pad_cfg;
1692 struct v4l2_subdev_format format = {
1693 .which = V4L2_SUBDEV_FORMAT_TRY,
1694 };
1695 struct v4l2_mbus_framefmt *mf = &format.format;
73135e96
VB
1696 __u32 pixfmt = pix->pixelformat;
1697 int width, height;
1698 int ret;
1699
1700 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1701 if (!xlate) {
1702 xlate = icd->current_fmt;
1703 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1704 pixfmt, xlate->host_fmt->fourcc);
1705 pixfmt = xlate->host_fmt->fourcc;
1706 pix->pixelformat = pixfmt;
1707 pix->colorspace = icd->colorspace;
1708 }
1709
1710 /* FIXME: calculate using depth and bus width */
1711 v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1712 &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1713
1714 width = pix->width;
1715 height = pix->height;
1716
1717 /* let soc-camera calculate these values */
1718 pix->bytesperline = 0;
1719 pix->sizeimage = 0;
1720
1721 /* limit to sensor capabilities */
5eab4983
HV
1722 mf->width = pix->width;
1723 mf->height = pix->height;
1724 mf->field = pix->field;
1725 mf->code = xlate->code;
1726 mf->colorspace = pix->colorspace;
73135e96
VB
1727
1728 ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
5eab4983 1729 pad, set_fmt, &pad_cfg, &format);
73135e96
VB
1730 if (ret < 0)
1731 return ret;
1732
4c28078c 1733 /* Adjust only if VIN cannot scale */
5eab4983
HV
1734 if (pix->width > mf->width * 2)
1735 pix->width = mf->width * 2;
1736 if (pix->height > mf->height * 3)
1737 pix->height = mf->height * 3;
4c28078c 1738
5eab4983
HV
1739 pix->field = mf->field;
1740 pix->colorspace = mf->colorspace;
73135e96
VB
1741
1742 if (pixfmt == V4L2_PIX_FMT_NV16) {
1743 /* FIXME: check against rect_max after converting soc-camera */
1744 /* We can scale precisely, need a bigger image from camera */
1745 if (pix->width < width || pix->height < height) {
1746 /*
1747 * We presume, the sensor behaves sanely, i.e. if
1748 * requested a bigger rectangle, it will not return a
1749 * smaller one.
1750 */
5eab4983
HV
1751 mf->width = VIN_MAX_WIDTH;
1752 mf->height = VIN_MAX_HEIGHT;
73135e96
VB
1753 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1754 soc_camera_grp_id(icd),
5eab4983
HV
1755 pad, set_fmt, &pad_cfg,
1756 &format);
73135e96
VB
1757 if (ret < 0) {
1758 dev_err(icd->parent,
1759 "client try_fmt() = %d\n", ret);
1760 return ret;
1761 }
1762 }
1763 /* We will scale exactly */
5eab4983 1764 if (mf->width > width)
73135e96 1765 pix->width = width;
5eab4983 1766 if (mf->height > height)
73135e96
VB
1767 pix->height = height;
1768 }
1769
1770 return ret;
1771}
1772
1773static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1774{
1775 struct soc_camera_device *icd = file->private_data;
1776
1777 return vb2_poll(&icd->vb2_vidq, file, pt);
1778}
1779
1780static int rcar_vin_querycap(struct soc_camera_host *ici,
1781 struct v4l2_capability *cap)
1782{
1783 strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
42d74e4f
NI
1784 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1785 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1786
73135e96
VB
1787 return 0;
1788}
1789
1790static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1791 struct soc_camera_device *icd)
1792{
976036df
LP
1793 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1794
73135e96
VB
1795 vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1796 vq->io_modes = VB2_MMAP | VB2_USERPTR;
1797 vq->drv_priv = icd;
1798 vq->ops = &rcar_vin_vb2_ops;
1799 vq->mem_ops = &vb2_dma_contig_memops;
1800 vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
ade48681 1801 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
976036df 1802 vq->lock = &ici->host_lock;
73135e96
VB
1803
1804 return vb2_queue_init(vq);
1805}
1806
1807static struct soc_camera_host_ops rcar_vin_host_ops = {
1808 .owner = THIS_MODULE,
1809 .add = rcar_vin_add_device,
1810 .remove = rcar_vin_remove_device,
73135e96
VB
1811 .get_formats = rcar_vin_get_formats,
1812 .put_formats = rcar_vin_put_formats,
1813 .get_crop = rcar_vin_get_crop,
1814 .set_crop = rcar_vin_set_crop,
1815 .try_fmt = rcar_vin_try_fmt,
1816 .set_fmt = rcar_vin_set_fmt,
1817 .poll = rcar_vin_poll,
1818 .querycap = rcar_vin_querycap,
1819 .set_bus_param = rcar_vin_set_bus_param,
1820 .init_videobuf2 = rcar_vin_init_videobuf2,
1821};
1822
47c71bd6
BD
1823#ifdef CONFIG_OF
1824static struct of_device_id rcar_vin_of_table[] = {
76deaff8
YK
1825 { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
1826 { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
47c71bd6
BD
1827 { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
1828 { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
1829 { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
1830 { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
1831 { },
1832};
1833MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1834#endif
1835
73135e96 1836static struct platform_device_id rcar_vin_id_table[] = {
2a9ecc17
VB
1837 { "r8a7791-vin", RCAR_GEN2 },
1838 { "r8a7790-vin", RCAR_GEN2 },
73135e96
VB
1839 { "r8a7779-vin", RCAR_H1 },
1840 { "r8a7778-vin", RCAR_M1 },
1841 { "uPD35004-vin", RCAR_E1 },
1842 {},
1843};
1844MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1845
1846static int rcar_vin_probe(struct platform_device *pdev)
1847{
47c71bd6 1848 const struct of_device_id *match = NULL;
73135e96
VB
1849 struct rcar_vin_priv *priv;
1850 struct resource *mem;
1851 struct rcar_vin_platform_data *pdata;
47c71bd6 1852 unsigned int pdata_flags;
73135e96
VB
1853 int irq, ret;
1854
47c71bd6
BD
1855 if (pdev->dev.of_node) {
1856 struct v4l2_of_endpoint ep;
1857 struct device_node *np;
1858
1859 match = of_match_device(of_match_ptr(rcar_vin_of_table),
1860 &pdev->dev);
1861
1862 np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1863 if (!np) {
1864 dev_err(&pdev->dev, "could not find endpoint\n");
1865 return -EINVAL;
1866 }
1867
1868 ret = v4l2_of_parse_endpoint(np, &ep);
1869 if (ret) {
1870 dev_err(&pdev->dev, "could not parse endpoint\n");
1871 return ret;
1872 }
1873
1874 if (ep.bus_type == V4L2_MBUS_BT656)
1875 pdata_flags = RCAR_VIN_BT656;
1876 else {
1877 pdata_flags = 0;
1878 if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1879 pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
1880 if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1881 pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
1882 }
1883
1884 of_node_put(np);
1885
1886 dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1887 } else {
1888 pdata = pdev->dev.platform_data;
1889 if (!pdata || !pdata->flags) {
1890 dev_err(&pdev->dev, "platform data not set\n");
1891 return -EINVAL;
1892 }
1893 pdata_flags = pdata->flags;
73135e96
VB
1894 }
1895
1896 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1897 if (mem == NULL)
1898 return -EINVAL;
1899
1900 irq = platform_get_irq(pdev, 0);
1901 if (irq <= 0)
1902 return -EINVAL;
1903
1904 priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1905 GFP_KERNEL);
1906 if (!priv)
1907 return -ENOMEM;
1908
1909 priv->base = devm_ioremap_resource(&pdev->dev, mem);
1910 if (IS_ERR(priv->base))
1911 return PTR_ERR(priv->base);
1912
1913 ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1914 dev_name(&pdev->dev), priv);
1915 if (ret)
1916 return ret;
1917
1918 priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1919 if (IS_ERR(priv->alloc_ctx))
1920 return PTR_ERR(priv->alloc_ctx);
1921
1922 priv->ici.priv = priv;
1923 priv->ici.v4l2_dev.dev = &pdev->dev;
73135e96
VB
1924 priv->ici.drv_name = dev_name(&pdev->dev);
1925 priv->ici.ops = &rcar_vin_host_ops;
1926
47c71bd6
BD
1927 priv->pdata_flags = pdata_flags;
1928 if (!match) {
1929 priv->ici.nr = pdev->id;
1930 priv->chip = pdev->id_entry->driver_data;
1931 } else {
1932 priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1933 priv->chip = (enum chip_id)match->data;
c611c908 1934 }
47c71bd6 1935
73135e96
VB
1936 spin_lock_init(&priv->lock);
1937 INIT_LIST_HEAD(&priv->capture);
1938
1939 priv->state = STOPPED;
1940
1941 pm_suspend_ignore_children(&pdev->dev, true);
1942 pm_runtime_enable(&pdev->dev);
1943
1944 ret = soc_camera_host_register(&priv->ici);
1945 if (ret)
1946 goto cleanup;
1947
1948 return 0;
1949
1950cleanup:
1951 pm_runtime_disable(&pdev->dev);
1952 vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1953
1954 return ret;
1955}
1956
1957static int rcar_vin_remove(struct platform_device *pdev)
1958{
1959 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1960 struct rcar_vin_priv *priv = container_of(soc_host,
1961 struct rcar_vin_priv, ici);
1962
1963 soc_camera_host_unregister(soc_host);
1964 pm_runtime_disable(&pdev->dev);
1965 vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1966
1967 return 0;
1968}
1969
1970static struct platform_driver rcar_vin_driver = {
1971 .probe = rcar_vin_probe,
1972 .remove = rcar_vin_remove,
1973 .driver = {
1974 .name = DRV_NAME,
47c71bd6 1975 .of_match_table = of_match_ptr(rcar_vin_of_table),
73135e96
VB
1976 },
1977 .id_table = rcar_vin_id_table,
1978};
1979
1980module_platform_driver(rcar_vin_driver);
1981
1982MODULE_LICENSE("GPL");
1983MODULE_ALIAS("platform:rcar_vin");
1984MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
This page took 0.241424 seconds and 5 git commands to generate.