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 140enum chip_id { 141 RCAR_GEN2, 142 RCAR_H1, 143 RCAR_M1, 144 RCAR_E1, 145}; 146 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 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; 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 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; 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 */ 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) { 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 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 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); 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 834static 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 862static 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 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 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 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; 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 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)) { 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 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 }, 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 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; 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 1455static void rcar_vin_put_formats(struct soc_camera_device *icd) 1456{ 1457 kfree(icd->host_priv); 1458 icd->host_priv = NULL; 1459} 1460 1461static 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 1538static 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 */ 1550static 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 1676static 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 1760static 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 1767static 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 1777static 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 1794static 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 1811static 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}; 1820MODULE_DEVICE_TABLE(of, rcar_vin_of_table); 1821#endif 1822 1823static 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}; 1831MODULE_DEVICE_TABLE(platform, rcar_vin_id_table); 1832 1833static 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 1937cleanup: 1938 pm_runtime_disable(&pdev->dev); 1939 vb2_dma_contig_cleanup_ctx(priv->alloc_ctx); 1940 1941 return ret; 1942} 1943 1944static 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 1957static 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 1967module_platform_driver(rcar_vin_driver); 1968 1969MODULE_LICENSE("GPL"); 1970MODULE_ALIAS("platform:rcar_vin"); 1971MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver"); 1972