1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Driver for Renesas R-Car VIN 4 * 5 * Copyright (C) 2016 Renesas Electronics Corp. 6 * Copyright (C) 2011-2013 Renesas Solutions Corp. 7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com> 8 * Copyright (C) 2008 Magnus Damm 9 * 10 * Based on the soc-camera rcar_vin driver 11 */ 12 13 #include <linux/delay.h> 14 #include <linux/interrupt.h> 15 #include <linux/pm_runtime.h> 16 17 #include <media/videobuf2-dma-contig.h> 18 19 #include "rcar-vin.h" 20 21 /* ----------------------------------------------------------------------------- 22 * HW Functions 23 */ 24 25 /* Register offsets for R-Car VIN */ 26 #define VNMC_REG 0x00 /* Video n Main Control Register */ 27 #define VNMS_REG 0x04 /* Video n Module Status Register */ 28 #define VNFC_REG 0x08 /* Video n Frame Capture Register */ 29 #define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */ 30 #define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */ 31 #define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */ 32 #define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */ 33 #define VNIS_REG 0x2C /* Video n Image Stride Register */ 34 #define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */ 35 #define VNIE_REG 0x40 /* Video n Interrupt Enable Register */ 36 #define VNINTS_REG 0x44 /* Video n Interrupt Status Register */ 37 #define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */ 38 #define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */ 39 #define VNDMR_REG 0x58 /* Video n Data Mode Register */ 40 #define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */ 41 #define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */ 42 43 /* Register offsets specific for Gen2 */ 44 #define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */ 45 #define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */ 46 #define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */ 47 #define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */ 48 #define VNYS_REG 0x50 /* Video n Y Scale Register */ 49 #define VNXS_REG 0x54 /* Video n X Scale Register */ 50 #define VNC1A_REG 0x80 /* Video n Coefficient Set C1A Register */ 51 #define VNC1B_REG 0x84 /* Video n Coefficient Set C1B Register */ 52 #define VNC1C_REG 0x88 /* Video n Coefficient Set C1C Register */ 53 #define VNC2A_REG 0x90 /* Video n Coefficient Set C2A Register */ 54 #define VNC2B_REG 0x94 /* Video n Coefficient Set C2B Register */ 55 #define VNC2C_REG 0x98 /* Video n Coefficient Set C2C Register */ 56 #define VNC3A_REG 0xA0 /* Video n Coefficient Set C3A Register */ 57 #define VNC3B_REG 0xA4 /* Video n Coefficient Set C3B Register */ 58 #define VNC3C_REG 0xA8 /* Video n Coefficient Set C3C Register */ 59 #define VNC4A_REG 0xB0 /* Video n Coefficient Set C4A Register */ 60 #define VNC4B_REG 0xB4 /* Video n Coefficient Set C4B Register */ 61 #define VNC4C_REG 0xB8 /* Video n Coefficient Set C4C Register */ 62 #define VNC5A_REG 0xC0 /* Video n Coefficient Set C5A Register */ 63 #define VNC5B_REG 0xC4 /* Video n Coefficient Set C5B Register */ 64 #define VNC5C_REG 0xC8 /* Video n Coefficient Set C5C Register */ 65 #define VNC6A_REG 0xD0 /* Video n Coefficient Set C6A Register */ 66 #define VNC6B_REG 0xD4 /* Video n Coefficient Set C6B Register */ 67 #define VNC6C_REG 0xD8 /* Video n Coefficient Set C6C Register */ 68 #define VNC7A_REG 0xE0 /* Video n Coefficient Set C7A Register */ 69 #define VNC7B_REG 0xE4 /* Video n Coefficient Set C7B Register */ 70 #define VNC7C_REG 0xE8 /* Video n Coefficient Set C7C Register */ 71 #define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */ 72 #define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */ 73 #define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */ 74 75 /* Register offsets specific for Gen3 */ 76 #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */ 77 #define VNUDS_CTRL_REG 0x80 /* Video n scaling control register */ 78 #define VNUDS_SCALE_REG 0x84 /* Video n scaling factor register */ 79 #define VNUDS_PASS_BWIDTH_REG 0x90 /* Video n passband register */ 80 #define VNUDS_CLIP_SIZE_REG 0xa4 /* Video n UDS output size clipping reg */ 81 82 /* Register bit fields for R-Car VIN */ 83 /* Video n Main Control Register bits */ 84 #define VNMC_INF_MASK (7 << 16) 85 #define VNMC_DPINE (1 << 27) /* Gen3 specific */ 86 #define VNMC_SCLE (1 << 26) /* Gen3 specific */ 87 #define VNMC_FOC (1 << 21) 88 #define VNMC_YCAL (1 << 19) 89 #define VNMC_INF_YUV8_BT656 (0 << 16) 90 #define VNMC_INF_YUV8_BT601 (1 << 16) 91 #define VNMC_INF_YUV10_BT656 (2 << 16) 92 #define VNMC_INF_YUV10_BT601 (3 << 16) 93 #define VNMC_INF_RAW8 (4 << 16) 94 #define VNMC_INF_YUV16 (5 << 16) 95 #define VNMC_INF_RGB888 (6 << 16) 96 #define VNMC_INF_RGB666 (7 << 16) 97 #define VNMC_EXINF_RAW8 (1 << 12) /* Gen4 specific */ 98 #define VNMC_VUP (1 << 10) 99 #define VNMC_IM_ODD (0 << 3) 100 #define VNMC_IM_ODD_EVEN (1 << 3) 101 #define VNMC_IM_EVEN (2 << 3) 102 #define VNMC_IM_FULL (3 << 3) 103 #define VNMC_BPS (1 << 1) 104 #define VNMC_ME (1 << 0) 105 106 /* Video n Module Status Register bits */ 107 #define VNMS_FBS_MASK (3 << 3) 108 #define VNMS_FBS_SHIFT 3 109 #define VNMS_FS (1 << 2) 110 #define VNMS_AV (1 << 1) 111 #define VNMS_CA (1 << 0) 112 113 /* Video n Frame Capture Register bits */ 114 #define VNFC_C_FRAME (1 << 1) 115 #define VNFC_S_FRAME (1 << 0) 116 117 /* Video n Interrupt Enable Register bits */ 118 #define VNIE_FIE (1 << 4) 119 #define VNIE_EFE (1 << 1) 120 121 /* Video n Interrupt Status Register bits */ 122 #define VNINTS_FIS (1 << 4) 123 124 /* Video n Data Mode Register bits */ 125 #define VNDMR_A8BIT(n) (((n) & 0xff) << 24) 126 #define VNDMR_A8BIT_MASK (0xff << 24) 127 #define VNDMR_RMODE_RAW10 (2 << 19) 128 #define VNDMR_YMODE_Y8 (1 << 12) 129 #define VNDMR_YC_THR (1 << 11) 130 #define VNDMR_EXRGB (1 << 8) 131 #define VNDMR_BPSM (1 << 4) 132 #define VNDMR_ABIT (1 << 2) 133 #define VNDMR_DTMD_YCSEP (1 << 1) 134 #define VNDMR_DTMD_ARGB (1 << 0) 135 #define VNDMR_DTMD_YCSEP_420 (3 << 0) 136 137 /* Video n Data Mode Register 2 bits */ 138 #define VNDMR2_VPS (1 << 30) 139 #define VNDMR2_HPS (1 << 29) 140 #define VNDMR2_CES (1 << 28) 141 #define VNDMR2_YDS (1 << 22) 142 #define VNDMR2_FTEV (1 << 17) 143 #define VNDMR2_VLV(n) ((n & 0xf) << 12) 144 145 /* Video n CSI2 Interface Mode Register (Gen3) */ 146 #define VNCSI_IFMD_DES1 (1 << 26) 147 #define VNCSI_IFMD_DES0 (1 << 25) 148 #define VNCSI_IFMD_CSI_CHSEL(n) (((n) & 0xf) << 0) 149 150 /* Video n scaling control register (Gen3) */ 151 #define VNUDS_CTRL_AMD (1 << 30) 152 153 struct rvin_buffer { 154 struct vb2_v4l2_buffer vb; 155 struct list_head list; 156 }; 157 158 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \ 159 struct rvin_buffer, \ 160 vb)->list) 161 162 static void rvin_write(struct rvin_dev *vin, u32 value, u32 offset) 163 { 164 iowrite32(value, vin->base + offset); 165 } 166 167 static u32 rvin_read(struct rvin_dev *vin, u32 offset) 168 { 169 return ioread32(vin->base + offset); 170 } 171 172 /* ----------------------------------------------------------------------------- 173 * Crop and Scaling 174 */ 175 176 static bool rvin_scaler_needed(const struct rvin_dev *vin) 177 { 178 return !(vin->crop.width == vin->format.width && 179 vin->compose.width == vin->format.width && 180 vin->crop.height == vin->format.height && 181 vin->compose.height == vin->format.height); 182 } 183 184 struct vin_coeff { 185 unsigned short xs_value; 186 u32 coeff_set[24]; 187 }; 188 189 static const struct vin_coeff vin_coeff_set[] = { 190 { 0x0000, { 191 0x00000000, 0x00000000, 0x00000000, 192 0x00000000, 0x00000000, 0x00000000, 193 0x00000000, 0x00000000, 0x00000000, 194 0x00000000, 0x00000000, 0x00000000, 195 0x00000000, 0x00000000, 0x00000000, 196 0x00000000, 0x00000000, 0x00000000, 197 0x00000000, 0x00000000, 0x00000000, 198 0x00000000, 0x00000000, 0x00000000 }, 199 }, 200 { 0x1000, { 201 0x000fa400, 0x000fa400, 0x09625902, 202 0x000003f8, 0x00000403, 0x3de0d9f0, 203 0x001fffed, 0x00000804, 0x3cc1f9c3, 204 0x001003de, 0x00000c01, 0x3cb34d7f, 205 0x002003d2, 0x00000c00, 0x3d24a92d, 206 0x00200bca, 0x00000bff, 0x3df600d2, 207 0x002013cc, 0x000007ff, 0x3ed70c7e, 208 0x00100fde, 0x00000000, 0x3f87c036 }, 209 }, 210 { 0x1200, { 211 0x002ffff1, 0x002ffff1, 0x02a0a9c8, 212 0x002003e7, 0x001ffffa, 0x000185bc, 213 0x002007dc, 0x000003ff, 0x3e52859c, 214 0x00200bd4, 0x00000002, 0x3d53996b, 215 0x00100fd0, 0x00000403, 0x3d04ad2d, 216 0x00000bd5, 0x00000403, 0x3d35ace7, 217 0x3ff003e4, 0x00000801, 0x3dc674a1, 218 0x3fffe800, 0x00000800, 0x3e76f461 }, 219 }, 220 { 0x1400, { 221 0x00100be3, 0x00100be3, 0x04d1359a, 222 0x00000fdb, 0x002003ed, 0x0211fd93, 223 0x00000fd6, 0x002003f4, 0x0002d97b, 224 0x000007d6, 0x002ffffb, 0x3e93b956, 225 0x3ff003da, 0x001003ff, 0x3db49926, 226 0x3fffefe9, 0x00100001, 0x3d655cee, 227 0x3fffd400, 0x00000003, 0x3d65f4b6, 228 0x000fb421, 0x00000402, 0x3dc6547e }, 229 }, 230 { 0x1600, { 231 0x00000bdd, 0x00000bdd, 0x06519578, 232 0x3ff007da, 0x00000be3, 0x03c24973, 233 0x3ff003d9, 0x00000be9, 0x01b30d5f, 234 0x3ffff7df, 0x001003f1, 0x0003c542, 235 0x000fdfec, 0x001003f7, 0x3ec4711d, 236 0x000fc400, 0x002ffffd, 0x3df504f1, 237 0x001fa81a, 0x002ffc00, 0x3d957cc2, 238 0x002f8c3c, 0x00100000, 0x3db5c891 }, 239 }, 240 { 0x1800, { 241 0x3ff003dc, 0x3ff003dc, 0x0791e558, 242 0x000ff7dd, 0x3ff007de, 0x05328554, 243 0x000fe7e3, 0x3ff00be2, 0x03232546, 244 0x000fd7ee, 0x000007e9, 0x0143bd30, 245 0x001fb800, 0x000007ee, 0x00044511, 246 0x002fa015, 0x000007f4, 0x3ef4bcee, 247 0x002f8832, 0x001003f9, 0x3e4514c7, 248 0x001f7853, 0x001003fd, 0x3de54c9f }, 249 }, 250 { 0x1a00, { 251 0x000fefe0, 0x000fefe0, 0x08721d3c, 252 0x001fdbe7, 0x000ffbde, 0x0652a139, 253 0x001fcbf0, 0x000003df, 0x0463292e, 254 0x002fb3ff, 0x3ff007e3, 0x0293a91d, 255 0x002f9c12, 0x3ff00be7, 0x01241905, 256 0x001f8c29, 0x000007ed, 0x3fe470eb, 257 0x000f7c46, 0x000007f2, 0x3f04b8ca, 258 0x3fef7865, 0x000007f6, 0x3e74e4a8 }, 259 }, 260 { 0x1c00, { 261 0x001fd3e9, 0x001fd3e9, 0x08f23d26, 262 0x002fbff3, 0x001fe3e4, 0x0712ad23, 263 0x002fa800, 0x000ff3e0, 0x05631d1b, 264 0x001f9810, 0x000ffbe1, 0x03b3890d, 265 0x000f8c23, 0x000003e3, 0x0233e8fa, 266 0x3fef843b, 0x000003e7, 0x00f430e4, 267 0x3fbf8456, 0x3ff00bea, 0x00046cc8, 268 0x3f8f8c72, 0x3ff00bef, 0x3f3490ac }, 269 }, 270 { 0x1e00, { 271 0x001fbbf4, 0x001fbbf4, 0x09425112, 272 0x001fa800, 0x002fc7ed, 0x0792b110, 273 0x000f980e, 0x001fdbe6, 0x0613110a, 274 0x3fff8c20, 0x001fe7e3, 0x04a368fd, 275 0x3fcf8c33, 0x000ff7e2, 0x0343b8ed, 276 0x3f9f8c4a, 0x000fffe3, 0x0203f8da, 277 0x3f5f9c61, 0x000003e6, 0x00e428c5, 278 0x3f1fb07b, 0x000003eb, 0x3fe440af }, 279 }, 280 { 0x2000, { 281 0x000fa400, 0x000fa400, 0x09625902, 282 0x3fff980c, 0x001fb7f5, 0x0812b0ff, 283 0x3fdf901c, 0x001fc7ed, 0x06b2fcfa, 284 0x3faf902d, 0x001fd3e8, 0x055348f1, 285 0x3f7f983f, 0x001fe3e5, 0x04038ce3, 286 0x3f3fa454, 0x001fefe3, 0x02e3c8d1, 287 0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0, 288 0x3ecfd880, 0x000fffe6, 0x00c404ac }, 289 }, 290 { 0x2200, { 291 0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4, 292 0x3fbf9818, 0x3fffa400, 0x0842a8f1, 293 0x3f8f9827, 0x000fb3f7, 0x0702f0ec, 294 0x3f5fa037, 0x000fc3ef, 0x05d330e4, 295 0x3f2fac49, 0x001fcfea, 0x04a364d9, 296 0x3effc05c, 0x001fdbe7, 0x038394ca, 297 0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb, 298 0x3ea00083, 0x001fefe6, 0x0183c0a9 }, 299 }, 300 { 0x2400, { 301 0x3f9fa014, 0x3f9fa014, 0x098260e6, 302 0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5, 303 0x3f4fa431, 0x3fefa400, 0x0742d8e1, 304 0x3f1fb440, 0x3fffb3f8, 0x062310d9, 305 0x3eefc850, 0x000fbbf2, 0x050340d0, 306 0x3ecfe062, 0x000fcbec, 0x041364c2, 307 0x3ea00073, 0x001fd3ea, 0x03037cb5, 308 0x3e902086, 0x001fdfe8, 0x022388a5 }, 309 }, 310 { 0x2600, { 311 0x3f5fa81e, 0x3f5fa81e, 0x096258da, 312 0x3f3fac2b, 0x3f8fa412, 0x088290d8, 313 0x3f0fbc38, 0x3fafa408, 0x0772c8d5, 314 0x3eefcc47, 0x3fcfa800, 0x0672f4ce, 315 0x3ecfe456, 0x3fefaffa, 0x05531cc6, 316 0x3eb00066, 0x3fffbbf3, 0x047334bb, 317 0x3ea01c77, 0x000fc7ee, 0x039348ae, 318 0x3ea04486, 0x000fd3eb, 0x02b350a1 }, 319 }, 320 { 0x2800, { 321 0x3f2fb426, 0x3f2fb426, 0x094250ce, 322 0x3f0fc032, 0x3f4fac1b, 0x086284cd, 323 0x3eefd040, 0x3f7fa811, 0x0782acc9, 324 0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4, 325 0x3eb0005b, 0x3fbfac00, 0x05b2f4bc, 326 0x3eb0186a, 0x3fdfb3fa, 0x04c308b4, 327 0x3eb04077, 0x3fefbbf4, 0x03f31ca8, 328 0x3ec06884, 0x000fbff2, 0x03031c9e }, 329 }, 330 { 0x2a00, { 331 0x3f0fc42d, 0x3f0fc42d, 0x090240c4, 332 0x3eefd439, 0x3f2fb822, 0x08526cc2, 333 0x3edfe845, 0x3f4fb018, 0x078294bf, 334 0x3ec00051, 0x3f6fac0f, 0x06b2b4bb, 335 0x3ec0185f, 0x3f8fac07, 0x05e2ccb4, 336 0x3ec0386b, 0x3fafac00, 0x0502e8ac, 337 0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3, 338 0x3ef08482, 0x3fdfbbf6, 0x0372f898 }, 339 }, 340 { 0x2c00, { 341 0x3eefdc31, 0x3eefdc31, 0x08e238b8, 342 0x3edfec3d, 0x3f0fc828, 0x082258b9, 343 0x3ed00049, 0x3f1fc01e, 0x077278b6, 344 0x3ed01455, 0x3f3fb815, 0x06c294b2, 345 0x3ed03460, 0x3f5fb40d, 0x0602acac, 346 0x3ef0506c, 0x3f7fb006, 0x0542c0a4, 347 0x3f107476, 0x3f9fb400, 0x0472c89d, 348 0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 }, 349 }, 350 { 0x2e00, { 351 0x3eefec37, 0x3eefec37, 0x088220b0, 352 0x3ee00041, 0x3effdc2d, 0x07f244ae, 353 0x3ee0144c, 0x3f0fd023, 0x07625cad, 354 0x3ef02c57, 0x3f1fc81a, 0x06c274a9, 355 0x3f004861, 0x3f3fbc13, 0x060288a6, 356 0x3f20686b, 0x3f5fb80c, 0x05529c9e, 357 0x3f408c74, 0x3f6fb805, 0x04b2ac96, 358 0x3f80ac7e, 0x3f8fb800, 0x0402ac8e }, 359 }, 360 { 0x3000, { 361 0x3ef0003a, 0x3ef0003a, 0x084210a6, 362 0x3ef01045, 0x3effec32, 0x07b228a7, 363 0x3f00284e, 0x3f0fdc29, 0x073244a4, 364 0x3f104058, 0x3f0fd420, 0x06a258a2, 365 0x3f305c62, 0x3f2fc818, 0x0612689d, 366 0x3f508069, 0x3f3fc011, 0x05728496, 367 0x3f80a072, 0x3f4fc00a, 0x04d28c90, 368 0x3fc0c07b, 0x3f6fbc04, 0x04429088 }, 369 }, 370 { 0x3200, { 371 0x3f00103e, 0x3f00103e, 0x07f1fc9e, 372 0x3f102447, 0x3f000035, 0x0782149d, 373 0x3f203c4f, 0x3f0ff02c, 0x07122c9c, 374 0x3f405458, 0x3f0fe424, 0x06924099, 375 0x3f607061, 0x3f1fd41d, 0x06024c97, 376 0x3f909068, 0x3f2fcc16, 0x05726490, 377 0x3fc0b070, 0x3f3fc80f, 0x04f26c8a, 378 0x0000d077, 0x3f4fc409, 0x04627484 }, 379 }, 380 { 0x3400, { 381 0x3f202040, 0x3f202040, 0x07a1e898, 382 0x3f303449, 0x3f100c38, 0x0741fc98, 383 0x3f504c50, 0x3f10002f, 0x06e21495, 384 0x3f706459, 0x3f1ff028, 0x06722492, 385 0x3fa08060, 0x3f1fe421, 0x05f2348f, 386 0x3fd09c67, 0x3f1fdc19, 0x05824c89, 387 0x0000bc6e, 0x3f2fd014, 0x04f25086, 388 0x0040dc74, 0x3f3fcc0d, 0x04825c7f }, 389 }, 390 { 0x3600, { 391 0x3f403042, 0x3f403042, 0x0761d890, 392 0x3f504848, 0x3f301c3b, 0x0701f090, 393 0x3f805c50, 0x3f200c33, 0x06a2008f, 394 0x3fa07458, 0x3f10002b, 0x06520c8d, 395 0x3fd0905e, 0x3f1ff424, 0x05e22089, 396 0x0000ac65, 0x3f1fe81d, 0x05823483, 397 0x0030cc6a, 0x3f2fdc18, 0x04f23c81, 398 0x0080e871, 0x3f2fd412, 0x0482407c }, 399 }, 400 { 0x3800, { 401 0x3f604043, 0x3f604043, 0x0721c88a, 402 0x3f80544a, 0x3f502c3c, 0x06d1d88a, 403 0x3fb06851, 0x3f301c35, 0x0681e889, 404 0x3fd08456, 0x3f30082f, 0x0611fc88, 405 0x00009c5d, 0x3f200027, 0x05d20884, 406 0x0030b863, 0x3f2ff421, 0x05621880, 407 0x0070d468, 0x3f2fe81b, 0x0502247c, 408 0x00c0ec6f, 0x3f2fe015, 0x04a22877 }, 409 }, 410 { 0x3a00, { 411 0x3f904c44, 0x3f904c44, 0x06e1b884, 412 0x3fb0604a, 0x3f70383e, 0x0691c885, 413 0x3fe07451, 0x3f502c36, 0x0661d483, 414 0x00009055, 0x3f401831, 0x0601ec81, 415 0x0030a85b, 0x3f300c2a, 0x05b1f480, 416 0x0070c061, 0x3f300024, 0x0562047a, 417 0x00b0d867, 0x3f3ff41e, 0x05020c77, 418 0x00f0f46b, 0x3f2fec19, 0x04a21474 }, 419 }, 420 { 0x3c00, { 421 0x3fb05c43, 0x3fb05c43, 0x06c1b07e, 422 0x3fe06c4b, 0x3f902c3f, 0x0681c081, 423 0x0000844f, 0x3f703838, 0x0631cc7d, 424 0x00309855, 0x3f602433, 0x05d1d47e, 425 0x0060b459, 0x3f50142e, 0x0581e47b, 426 0x00a0c85f, 0x3f400828, 0x0531f078, 427 0x00e0e064, 0x3f300021, 0x0501fc73, 428 0x00b0fc6a, 0x3f3ff41d, 0x04a20873 }, 429 }, 430 { 0x3e00, { 431 0x3fe06444, 0x3fe06444, 0x0681a07a, 432 0x00007849, 0x3fc0503f, 0x0641b07a, 433 0x0020904d, 0x3fa0403a, 0x05f1c07a, 434 0x0060a453, 0x3f803034, 0x05c1c878, 435 0x0090b858, 0x3f70202f, 0x0571d477, 436 0x00d0d05d, 0x3f501829, 0x0531e073, 437 0x0110e462, 0x3f500825, 0x04e1e471, 438 0x01510065, 0x3f40001f, 0x04a1f06d }, 439 }, 440 { 0x4000, { 441 0x00007044, 0x00007044, 0x06519476, 442 0x00208448, 0x3fe05c3f, 0x0621a476, 443 0x0050984d, 0x3fc04c3a, 0x05e1b075, 444 0x0080ac52, 0x3fa03c35, 0x05a1b875, 445 0x00c0c056, 0x3f803030, 0x0561c473, 446 0x0100d45b, 0x3f70202b, 0x0521d46f, 447 0x0140e860, 0x3f601427, 0x04d1d46e, 448 0x01810064, 0x3f500822, 0x0491dc6b }, 449 }, 450 { 0x5000, { 451 0x0110a442, 0x0110a442, 0x0551545e, 452 0x0140b045, 0x00e0983f, 0x0531585f, 453 0x0160c047, 0x00c08c3c, 0x0511645e, 454 0x0190cc4a, 0x00908039, 0x04f1685f, 455 0x01c0dc4c, 0x00707436, 0x04d1705e, 456 0x0200e850, 0x00506833, 0x04b1785b, 457 0x0230f453, 0x00305c30, 0x0491805a, 458 0x02710056, 0x0010542d, 0x04718059 }, 459 }, 460 { 0x6000, { 461 0x01c0bc40, 0x01c0bc40, 0x04c13052, 462 0x01e0c841, 0x01a0b43d, 0x04c13851, 463 0x0210cc44, 0x0180a83c, 0x04a13453, 464 0x0230d845, 0x0160a03a, 0x04913c52, 465 0x0260e047, 0x01409838, 0x04714052, 466 0x0280ec49, 0x01208c37, 0x04514c50, 467 0x02b0f44b, 0x01008435, 0x04414c50, 468 0x02d1004c, 0x00e07c33, 0x0431544f }, 469 }, 470 { 0x7000, { 471 0x0230c83e, 0x0230c83e, 0x04711c4c, 472 0x0250d03f, 0x0210c43c, 0x0471204b, 473 0x0270d840, 0x0200b83c, 0x0451244b, 474 0x0290dc42, 0x01e0b43a, 0x0441244c, 475 0x02b0e443, 0x01c0b038, 0x0441284b, 476 0x02d0ec44, 0x01b0a438, 0x0421304a, 477 0x02f0f445, 0x0190a036, 0x04213449, 478 0x0310f847, 0x01709c34, 0x04213848 }, 479 }, 480 { 0x8000, { 481 0x0280d03d, 0x0280d03d, 0x04310c48, 482 0x02a0d43e, 0x0270c83c, 0x04311047, 483 0x02b0dc3e, 0x0250c83a, 0x04311447, 484 0x02d0e040, 0x0240c03a, 0x04211446, 485 0x02e0e840, 0x0220bc39, 0x04111847, 486 0x0300e842, 0x0210b438, 0x04012445, 487 0x0310f043, 0x0200b037, 0x04012045, 488 0x0330f444, 0x01e0ac36, 0x03f12445 }, 489 }, 490 { 0xefff, { 491 0x0340dc3a, 0x0340dc3a, 0x03b0ec40, 492 0x0340e03a, 0x0330e039, 0x03c0f03e, 493 0x0350e03b, 0x0330dc39, 0x03c0ec3e, 494 0x0350e43a, 0x0320dc38, 0x03c0f43e, 495 0x0360e43b, 0x0320d839, 0x03b0f03e, 496 0x0360e83b, 0x0310d838, 0x03c0fc3b, 497 0x0370e83b, 0x0310d439, 0x03a0f83d, 498 0x0370e83c, 0x0300d438, 0x03b0fc3c }, 499 } 500 }; 501 502 static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) 503 { 504 int i; 505 const struct vin_coeff *p_prev_set = NULL; 506 const struct vin_coeff *p_set = NULL; 507 508 /* Look for suitable coefficient values */ 509 for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) { 510 p_prev_set = p_set; 511 p_set = &vin_coeff_set[i]; 512 513 if (xs < p_set->xs_value) 514 break; 515 } 516 517 /* Use previous value if its XS value is closer */ 518 if (p_prev_set && 519 xs - p_prev_set->xs_value < p_set->xs_value - xs) 520 p_set = p_prev_set; 521 522 /* Set coefficient registers */ 523 rvin_write(vin, p_set->coeff_set[0], VNC1A_REG); 524 rvin_write(vin, p_set->coeff_set[1], VNC1B_REG); 525 rvin_write(vin, p_set->coeff_set[2], VNC1C_REG); 526 527 rvin_write(vin, p_set->coeff_set[3], VNC2A_REG); 528 rvin_write(vin, p_set->coeff_set[4], VNC2B_REG); 529 rvin_write(vin, p_set->coeff_set[5], VNC2C_REG); 530 531 rvin_write(vin, p_set->coeff_set[6], VNC3A_REG); 532 rvin_write(vin, p_set->coeff_set[7], VNC3B_REG); 533 rvin_write(vin, p_set->coeff_set[8], VNC3C_REG); 534 535 rvin_write(vin, p_set->coeff_set[9], VNC4A_REG); 536 rvin_write(vin, p_set->coeff_set[10], VNC4B_REG); 537 rvin_write(vin, p_set->coeff_set[11], VNC4C_REG); 538 539 rvin_write(vin, p_set->coeff_set[12], VNC5A_REG); 540 rvin_write(vin, p_set->coeff_set[13], VNC5B_REG); 541 rvin_write(vin, p_set->coeff_set[14], VNC5C_REG); 542 543 rvin_write(vin, p_set->coeff_set[15], VNC6A_REG); 544 rvin_write(vin, p_set->coeff_set[16], VNC6B_REG); 545 rvin_write(vin, p_set->coeff_set[17], VNC6C_REG); 546 547 rvin_write(vin, p_set->coeff_set[18], VNC7A_REG); 548 rvin_write(vin, p_set->coeff_set[19], VNC7B_REG); 549 rvin_write(vin, p_set->coeff_set[20], VNC7C_REG); 550 551 rvin_write(vin, p_set->coeff_set[21], VNC8A_REG); 552 rvin_write(vin, p_set->coeff_set[22], VNC8B_REG); 553 rvin_write(vin, p_set->coeff_set[23], VNC8C_REG); 554 } 555 556 void rvin_scaler_gen2(struct rvin_dev *vin) 557 { 558 unsigned int crop_height; 559 u32 xs, ys; 560 561 /* Set scaling coefficient */ 562 crop_height = vin->crop.height; 563 if (V4L2_FIELD_HAS_BOTH(vin->format.field)) 564 crop_height *= 2; 565 566 ys = 0; 567 if (crop_height != vin->compose.height) 568 ys = (4096 * crop_height) / vin->compose.height; 569 rvin_write(vin, ys, VNYS_REG); 570 571 xs = 0; 572 if (vin->crop.width != vin->compose.width) 573 xs = (4096 * vin->crop.width) / vin->compose.width; 574 575 /* Horizontal upscaling is up to double size */ 576 if (xs > 0 && xs < 2048) 577 xs = 2048; 578 579 rvin_write(vin, xs, VNXS_REG); 580 581 /* Horizontal upscaling is done out by scaling down from double size */ 582 if (xs < 4096) 583 xs *= 2; 584 585 rvin_set_coeff(vin, xs); 586 587 /* Set Start/End Pixel/Line Post-Clip */ 588 rvin_write(vin, 0, VNSPPOC_REG); 589 rvin_write(vin, 0, VNSLPOC_REG); 590 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG); 591 592 if (V4L2_FIELD_HAS_BOTH(vin->format.field)) 593 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG); 594 else 595 rvin_write(vin, vin->format.height - 1, VNELPOC_REG); 596 597 vin_dbg(vin, 598 "Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n", 599 vin->crop.width, vin->crop.height, vin->crop.left, 600 vin->crop.top, ys, xs, vin->format.width, vin->format.height, 601 0, 0); 602 } 603 604 static unsigned int rvin_uds_scale_ratio(unsigned int in, unsigned int out) 605 { 606 unsigned int ratio; 607 608 ratio = in * 4096 / out; 609 return ratio >= 0x10000 ? 0xffff : ratio; 610 } 611 612 static unsigned int rvin_uds_filter_width(unsigned int ratio) 613 { 614 if (ratio >= 0x1000) 615 return 64 * (ratio & 0xf000) / ratio; 616 617 return 64; 618 } 619 620 void rvin_scaler_gen3(struct rvin_dev *vin) 621 { 622 unsigned int ratio_h, ratio_v; 623 unsigned int bwidth_h, bwidth_v; 624 u32 vnmc, clip_size; 625 626 vnmc = rvin_read(vin, VNMC_REG); 627 628 /* Disable scaler if not needed. */ 629 if (!rvin_scaler_needed(vin)) { 630 rvin_write(vin, vnmc & ~VNMC_SCLE, VNMC_REG); 631 return; 632 } 633 634 ratio_h = rvin_uds_scale_ratio(vin->crop.width, vin->compose.width); 635 bwidth_h = rvin_uds_filter_width(ratio_h); 636 637 ratio_v = rvin_uds_scale_ratio(vin->crop.height, vin->compose.height); 638 bwidth_v = rvin_uds_filter_width(ratio_v); 639 640 clip_size = vin->compose.width << 16; 641 642 switch (vin->format.field) { 643 case V4L2_FIELD_INTERLACED_TB: 644 case V4L2_FIELD_INTERLACED_BT: 645 case V4L2_FIELD_INTERLACED: 646 clip_size |= vin->compose.height / 2; 647 break; 648 default: 649 clip_size |= vin->compose.height; 650 break; 651 } 652 653 rvin_write(vin, vnmc | VNMC_SCLE, VNMC_REG); 654 rvin_write(vin, VNUDS_CTRL_AMD, VNUDS_CTRL_REG); 655 rvin_write(vin, (ratio_h << 16) | ratio_v, VNUDS_SCALE_REG); 656 rvin_write(vin, (bwidth_h << 16) | bwidth_v, VNUDS_PASS_BWIDTH_REG); 657 rvin_write(vin, clip_size, VNUDS_CLIP_SIZE_REG); 658 659 vin_dbg(vin, "Pre-Clip: %ux%u@%u:%u Post-Clip: %ux%u@%u:%u\n", 660 vin->crop.width, vin->crop.height, vin->crop.left, 661 vin->crop.top, vin->compose.width, vin->compose.height, 662 vin->compose.left, vin->compose.top); 663 } 664 665 void rvin_crop_scale_comp(struct rvin_dev *vin) 666 { 667 const struct rvin_video_format *fmt; 668 u32 stride; 669 670 /* Set Start/End Pixel/Line Pre-Clip */ 671 rvin_write(vin, vin->crop.left, VNSPPRC_REG); 672 rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG); 673 rvin_write(vin, vin->crop.top, VNSLPRC_REG); 674 rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG); 675 676 if (vin->scaler) 677 vin->scaler(vin); 678 679 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); 680 stride = vin->format.bytesperline / fmt->bpp; 681 rvin_write(vin, stride, VNIS_REG); 682 } 683 684 /* ----------------------------------------------------------------------------- 685 * Hardware setup 686 */ 687 688 static int rvin_setup(struct rvin_dev *vin) 689 { 690 u32 vnmc, dmr, dmr2, interrupts; 691 bool progressive = false, output_is_yuv = false, input_is_yuv = false; 692 693 switch (vin->format.field) { 694 case V4L2_FIELD_TOP: 695 vnmc = VNMC_IM_ODD; 696 break; 697 case V4L2_FIELD_BOTTOM: 698 vnmc = VNMC_IM_EVEN; 699 break; 700 case V4L2_FIELD_INTERLACED: 701 /* Default to TB */ 702 vnmc = VNMC_IM_FULL; 703 /* Use BT if video standard can be read and is 60 Hz format */ 704 if (!vin->info->use_mc && vin->std & V4L2_STD_525_60) 705 vnmc = VNMC_IM_FULL | VNMC_FOC; 706 break; 707 case V4L2_FIELD_INTERLACED_TB: 708 vnmc = VNMC_IM_FULL; 709 break; 710 case V4L2_FIELD_INTERLACED_BT: 711 vnmc = VNMC_IM_FULL | VNMC_FOC; 712 break; 713 case V4L2_FIELD_NONE: 714 case V4L2_FIELD_ALTERNATE: 715 vnmc = VNMC_IM_ODD_EVEN; 716 progressive = true; 717 break; 718 default: 719 vnmc = VNMC_IM_ODD; 720 break; 721 } 722 723 /* 724 * Input interface 725 */ 726 switch (vin->mbus_code) { 727 case MEDIA_BUS_FMT_YUYV8_1X16: 728 if (vin->is_csi) 729 /* YCbCr422 8-bit */ 730 vnmc |= VNMC_INF_YUV8_BT601; 731 else 732 /* BT.601/BT.1358 16bit YCbCr422 */ 733 vnmc |= VNMC_INF_YUV16; 734 input_is_yuv = true; 735 break; 736 case MEDIA_BUS_FMT_UYVY8_1X16: 737 if (vin->is_csi) 738 /* YCbCr422 8-bit */ 739 vnmc |= VNMC_INF_YUV8_BT601; 740 else 741 /* BT.601/BT.1358 16bit YCbCr422 */ 742 vnmc |= VNMC_INF_YUV16; 743 vnmc |= VNMC_YCAL; 744 input_is_yuv = true; 745 break; 746 case MEDIA_BUS_FMT_UYVY8_2X8: 747 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ 748 if (!vin->is_csi && 749 vin->parallel.mbus_type == V4L2_MBUS_BT656) 750 vnmc |= VNMC_INF_YUV8_BT656; 751 else 752 vnmc |= VNMC_INF_YUV8_BT601; 753 754 input_is_yuv = true; 755 break; 756 case MEDIA_BUS_FMT_RGB888_1X24: 757 vnmc |= VNMC_INF_RGB888; 758 break; 759 case MEDIA_BUS_FMT_UYVY10_2X10: 760 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ 761 if (!vin->is_csi && 762 vin->parallel.mbus_type == V4L2_MBUS_BT656) 763 vnmc |= VNMC_INF_YUV10_BT656; 764 else 765 vnmc |= VNMC_INF_YUV10_BT601; 766 767 input_is_yuv = true; 768 break; 769 case MEDIA_BUS_FMT_SBGGR8_1X8: 770 case MEDIA_BUS_FMT_SGBRG8_1X8: 771 case MEDIA_BUS_FMT_SGRBG8_1X8: 772 case MEDIA_BUS_FMT_SRGGB8_1X8: 773 case MEDIA_BUS_FMT_Y8_1X8: 774 vnmc |= VNMC_INF_RAW8; 775 if (vin->info->model == RCAR_GEN4) 776 vnmc |= VNMC_EXINF_RAW8; 777 break; 778 case MEDIA_BUS_FMT_SBGGR10_1X10: 779 case MEDIA_BUS_FMT_SGBRG10_1X10: 780 case MEDIA_BUS_FMT_SGRBG10_1X10: 781 case MEDIA_BUS_FMT_SRGGB10_1X10: 782 vnmc |= VNMC_INF_RGB666; 783 break; 784 default: 785 break; 786 } 787 788 /* Enable VSYNC Field Toggle mode after one VSYNC input */ 789 if (vin->info->model == RCAR_GEN3 || vin->info->model == RCAR_GEN4) 790 dmr2 = VNDMR2_FTEV; 791 else 792 dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); 793 794 if (!vin->is_csi) { 795 /* Hsync Signal Polarity Select */ 796 if (!(vin->parallel.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) 797 dmr2 |= VNDMR2_HPS; 798 799 /* Vsync Signal Polarity Select */ 800 if (!(vin->parallel.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) 801 dmr2 |= VNDMR2_VPS; 802 803 /* Data Enable Polarity Select */ 804 if (vin->parallel.bus.flags & V4L2_MBUS_DATA_ENABLE_LOW) 805 dmr2 |= VNDMR2_CES; 806 807 switch (vin->mbus_code) { 808 case MEDIA_BUS_FMT_UYVY8_2X8: 809 if (vin->parallel.bus.bus_width == 8 && 810 vin->parallel.bus.data_shift == 8) 811 dmr2 |= VNDMR2_YDS; 812 break; 813 default: 814 break; 815 } 816 } 817 818 /* 819 * Output format 820 */ 821 switch (vin->format.pixelformat) { 822 case V4L2_PIX_FMT_NV12: 823 case V4L2_PIX_FMT_NV16: 824 rvin_write(vin, 825 ALIGN(vin->format.bytesperline * vin->format.height, 826 0x80), VNUVAOF_REG); 827 dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ? 828 VNDMR_DTMD_YCSEP_420 : VNDMR_DTMD_YCSEP; 829 output_is_yuv = true; 830 break; 831 case V4L2_PIX_FMT_YUYV: 832 dmr = VNDMR_BPSM; 833 output_is_yuv = true; 834 break; 835 case V4L2_PIX_FMT_UYVY: 836 dmr = 0; 837 output_is_yuv = true; 838 break; 839 case V4L2_PIX_FMT_XRGB555: 840 dmr = VNDMR_DTMD_ARGB; 841 break; 842 case V4L2_PIX_FMT_RGB565: 843 dmr = 0; 844 break; 845 case V4L2_PIX_FMT_XBGR32: 846 /* Note: not supported on M1 */ 847 dmr = VNDMR_EXRGB; 848 break; 849 case V4L2_PIX_FMT_ARGB555: 850 dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB; 851 break; 852 case V4L2_PIX_FMT_ABGR32: 853 dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB; 854 break; 855 case V4L2_PIX_FMT_SBGGR8: 856 case V4L2_PIX_FMT_SGBRG8: 857 case V4L2_PIX_FMT_SGRBG8: 858 case V4L2_PIX_FMT_SRGGB8: 859 dmr = 0; 860 break; 861 case V4L2_PIX_FMT_GREY: 862 if (input_is_yuv) { 863 dmr = VNDMR_DTMD_YCSEP | VNDMR_YMODE_Y8; 864 output_is_yuv = true; 865 } else { 866 dmr = 0; 867 } 868 break; 869 case V4L2_PIX_FMT_SBGGR10: 870 case V4L2_PIX_FMT_SGBRG10: 871 case V4L2_PIX_FMT_SGRBG10: 872 case V4L2_PIX_FMT_SRGGB10: 873 dmr = VNDMR_RMODE_RAW10; 874 break; 875 default: 876 vin_err(vin, "Invalid pixelformat (0x%x)\n", 877 vin->format.pixelformat); 878 return -EINVAL; 879 } 880 881 /* Always update on field change */ 882 vnmc |= VNMC_VUP; 883 884 if (!vin->info->use_isp) { 885 /* If input and output use the same colorspace, use bypass mode */ 886 if (input_is_yuv == output_is_yuv) 887 vnmc |= VNMC_BPS; 888 889 if (vin->info->model == RCAR_GEN3 || vin->info->model == RCAR_GEN4) { 890 /* Select between CSI-2 and parallel input */ 891 if (vin->is_csi) 892 vnmc &= ~VNMC_DPINE; 893 else 894 vnmc |= VNMC_DPINE; 895 } 896 } 897 898 /* Progressive or interlaced mode */ 899 interrupts = progressive ? VNIE_FIE : VNIE_EFE; 900 901 /* Ack interrupts */ 902 rvin_write(vin, interrupts, VNINTS_REG); 903 /* Enable interrupts */ 904 rvin_write(vin, interrupts, VNIE_REG); 905 /* Start capturing */ 906 rvin_write(vin, dmr, VNDMR_REG); 907 rvin_write(vin, dmr2, VNDMR2_REG); 908 909 /* Enable module */ 910 rvin_write(vin, vnmc | VNMC_ME, VNMC_REG); 911 912 return 0; 913 } 914 915 static void rvin_disable_interrupts(struct rvin_dev *vin) 916 { 917 rvin_write(vin, 0, VNIE_REG); 918 } 919 920 static u32 rvin_get_interrupt_status(struct rvin_dev *vin) 921 { 922 return rvin_read(vin, VNINTS_REG); 923 } 924 925 static void rvin_ack_interrupt(struct rvin_dev *vin) 926 { 927 rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG); 928 } 929 930 static bool rvin_capture_active(struct rvin_dev *vin) 931 { 932 return rvin_read(vin, VNMS_REG) & VNMS_CA; 933 } 934 935 static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) 936 { 937 if (vin->format.field == V4L2_FIELD_ALTERNATE) { 938 /* If FS is set it is an Even field. */ 939 if (vnms & VNMS_FS) 940 return V4L2_FIELD_BOTTOM; 941 return V4L2_FIELD_TOP; 942 } 943 944 return vin->format.field; 945 } 946 947 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) 948 { 949 const struct rvin_video_format *fmt; 950 int offsetx, offsety; 951 dma_addr_t offset; 952 953 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); 954 955 /* 956 * There is no HW support for composition do the beast we can 957 * by modifying the buffer offset 958 */ 959 offsetx = vin->compose.left * fmt->bpp; 960 offsety = vin->compose.top * vin->format.bytesperline; 961 offset = addr + offsetx + offsety; 962 963 /* 964 * The address needs to be 128 bytes aligned. Driver should never accept 965 * settings that do not satisfy this in the first place... 966 */ 967 if (WARN_ON((offsetx | offsety | offset) & HW_BUFFER_MASK)) 968 return; 969 970 rvin_write(vin, offset, VNMB_REG(slot)); 971 } 972 973 /* 974 * Moves a buffer from the queue to the HW slot. If no buffer is 975 * available use the scratch buffer. The scratch buffer is never 976 * returned to userspace, its only function is to enable the capture 977 * loop to keep running. 978 */ 979 static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot) 980 { 981 struct rvin_buffer *buf; 982 struct vb2_v4l2_buffer *vbuf; 983 dma_addr_t phys_addr; 984 985 /* A already populated slot shall never be overwritten. */ 986 if (WARN_ON(vin->buf_hw[slot].buffer)) 987 return; 988 989 if (list_empty(&vin->buf_list)) { 990 vin->buf_hw[slot].buffer = NULL; 991 phys_addr = vin->scratch_phys; 992 } else { 993 /* Keep track of buffer we give to HW */ 994 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list); 995 vbuf = &buf->vb; 996 list_del_init(to_buf_list(vbuf)); 997 vin->buf_hw[slot].buffer = vbuf; 998 999 /* Setup DMA */ 1000 phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); 1001 } 1002 1003 vin_dbg(vin, "Filling HW slot: %d buffer: %p\n", 1004 slot, vin->buf_hw[slot].buffer); 1005 1006 vin->buf_hw[slot].phys = phys_addr; 1007 rvin_set_slot_addr(vin, slot, phys_addr); 1008 } 1009 1010 static int rvin_capture_start(struct rvin_dev *vin) 1011 { 1012 int ret; 1013 1014 for (unsigned int slot = 0; slot < HW_BUFFER_NUM; slot++) { 1015 vin->buf_hw[slot].buffer = NULL; 1016 rvin_fill_hw_slot(vin, slot); 1017 } 1018 1019 ret = rvin_setup(vin); 1020 if (ret) 1021 return ret; 1022 1023 rvin_crop_scale_comp(vin); 1024 1025 vin_dbg(vin, "Starting to capture\n"); 1026 1027 /* Continuous Frame Capture Mode */ 1028 rvin_write(vin, VNFC_C_FRAME, VNFC_REG); 1029 1030 return 0; 1031 } 1032 1033 static void rvin_capture_stop(struct rvin_dev *vin) 1034 { 1035 /* Set continuous & single transfer off */ 1036 rvin_write(vin, 0, VNFC_REG); 1037 1038 /* Disable module */ 1039 rvin_write(vin, rvin_read(vin, VNMC_REG) & ~VNMC_ME, VNMC_REG); 1040 } 1041 1042 /* ----------------------------------------------------------------------------- 1043 * DMA Functions 1044 */ 1045 1046 #define RVIN_TIMEOUT_MS 100 1047 #define RVIN_RETRIES 10 1048 1049 static irqreturn_t rvin_irq(int irq, void *data) 1050 { 1051 struct rvin_dev *vin = data; 1052 u32 int_status, vnms; 1053 int slot; 1054 unsigned int handled = 0; 1055 unsigned long flags; 1056 1057 spin_lock_irqsave(&vin->qlock, flags); 1058 1059 int_status = rvin_get_interrupt_status(vin); 1060 if (!int_status) 1061 goto done; 1062 1063 rvin_ack_interrupt(vin); 1064 handled = 1; 1065 1066 /* Nothing to do if nothing was captured. */ 1067 if (!(int_status & VNINTS_FIS)) 1068 goto done; 1069 1070 /* Nothing to do if not running. */ 1071 if (!vin->running) { 1072 vin_dbg(vin, "IRQ while not running, ignoring\n"); 1073 goto done; 1074 } 1075 1076 /* Prepare for capture and update state */ 1077 vnms = rvin_read(vin, VNMS_REG); 1078 slot = (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT; 1079 1080 /* 1081 * To hand buffers back in a known order to userspace start 1082 * to capture first from slot 0. 1083 */ 1084 if (!vin->sequence) { 1085 if (slot != 0) { 1086 vin_dbg(vin, "Starting sync slot: %d\n", slot); 1087 goto done; 1088 } 1089 1090 vin_dbg(vin, "Capture start synced!\n"); 1091 } 1092 1093 /* Capture frame */ 1094 if (vin->buf_hw[slot].buffer) { 1095 vin->buf_hw[slot].buffer->field = 1096 rvin_get_active_field(vin, vnms); 1097 vin->buf_hw[slot].buffer->sequence = vin->sequence; 1098 vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns(); 1099 vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf, 1100 VB2_BUF_STATE_DONE); 1101 vin->buf_hw[slot].buffer = NULL; 1102 } else { 1103 /* Scratch buffer was used, dropping frame. */ 1104 vin_dbg(vin, "Dropping frame %u\n", vin->sequence); 1105 } 1106 1107 vin->sequence++; 1108 1109 /* Prepare for next frame */ 1110 rvin_fill_hw_slot(vin, slot); 1111 done: 1112 spin_unlock_irqrestore(&vin->qlock, flags); 1113 1114 return IRQ_RETVAL(handled); 1115 } 1116 1117 static void return_unused_buffers(struct rvin_dev *vin, 1118 enum vb2_buffer_state state) 1119 { 1120 struct rvin_buffer *buf, *node; 1121 unsigned long flags; 1122 1123 spin_lock_irqsave(&vin->qlock, flags); 1124 1125 list_for_each_entry_safe(buf, node, &vin->buf_list, list) { 1126 vb2_buffer_done(&buf->vb.vb2_buf, state); 1127 list_del(&buf->list); 1128 } 1129 1130 spin_unlock_irqrestore(&vin->qlock, flags); 1131 } 1132 1133 static int rvin_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 1134 unsigned int *nplanes, unsigned int sizes[], 1135 struct device *alloc_devs[]) 1136 1137 { 1138 struct rvin_dev *vin = vb2_get_drv_priv(vq); 1139 1140 /* Make sure the image size is large enough. */ 1141 if (*nplanes) 1142 return sizes[0] < vin->format.sizeimage ? -EINVAL : 0; 1143 1144 *nplanes = 1; 1145 sizes[0] = vin->format.sizeimage; 1146 1147 return 0; 1148 }; 1149 1150 static int rvin_buffer_prepare(struct vb2_buffer *vb) 1151 { 1152 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue); 1153 unsigned long size = vin->format.sizeimage; 1154 1155 if (vb2_plane_size(vb, 0) < size) { 1156 vin_err(vin, "buffer too small (%lu < %lu)\n", 1157 vb2_plane_size(vb, 0), size); 1158 return -EINVAL; 1159 } 1160 1161 vb2_set_plane_payload(vb, 0, size); 1162 1163 return 0; 1164 } 1165 1166 static void rvin_buffer_queue(struct vb2_buffer *vb) 1167 { 1168 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1169 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue); 1170 unsigned long flags; 1171 1172 spin_lock_irqsave(&vin->qlock, flags); 1173 1174 list_add_tail(to_buf_list(vbuf), &vin->buf_list); 1175 1176 spin_unlock_irqrestore(&vin->qlock, flags); 1177 } 1178 1179 static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd, 1180 struct media_pad *pad) 1181 { 1182 struct v4l2_subdev_format fmt = { 1183 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1184 }; 1185 1186 fmt.pad = pad->index; 1187 if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) 1188 return -EPIPE; 1189 1190 switch (fmt.format.code) { 1191 case MEDIA_BUS_FMT_YUYV8_1X16: 1192 case MEDIA_BUS_FMT_UYVY8_1X16: 1193 case MEDIA_BUS_FMT_UYVY8_2X8: 1194 case MEDIA_BUS_FMT_UYVY10_2X10: 1195 case MEDIA_BUS_FMT_RGB888_1X24: 1196 break; 1197 case MEDIA_BUS_FMT_SBGGR8_1X8: 1198 if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8) 1199 return -EPIPE; 1200 break; 1201 case MEDIA_BUS_FMT_SGBRG8_1X8: 1202 if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8) 1203 return -EPIPE; 1204 break; 1205 case MEDIA_BUS_FMT_SGRBG8_1X8: 1206 if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8) 1207 return -EPIPE; 1208 break; 1209 case MEDIA_BUS_FMT_SRGGB8_1X8: 1210 if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8) 1211 return -EPIPE; 1212 break; 1213 case MEDIA_BUS_FMT_Y8_1X8: 1214 if (vin->format.pixelformat != V4L2_PIX_FMT_GREY) 1215 return -EPIPE; 1216 break; 1217 case MEDIA_BUS_FMT_SBGGR10_1X10: 1218 if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR10) 1219 return -EPIPE; 1220 break; 1221 case MEDIA_BUS_FMT_SGBRG10_1X10: 1222 if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG10) 1223 return -EPIPE; 1224 break; 1225 case MEDIA_BUS_FMT_SGRBG10_1X10: 1226 if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG10) 1227 return -EPIPE; 1228 break; 1229 case MEDIA_BUS_FMT_SRGGB10_1X10: 1230 if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB10) 1231 return -EPIPE; 1232 break; 1233 default: 1234 return -EPIPE; 1235 } 1236 vin->mbus_code = fmt.format.code; 1237 1238 switch (fmt.format.field) { 1239 case V4L2_FIELD_TOP: 1240 case V4L2_FIELD_BOTTOM: 1241 case V4L2_FIELD_NONE: 1242 case V4L2_FIELD_INTERLACED_TB: 1243 case V4L2_FIELD_INTERLACED_BT: 1244 case V4L2_FIELD_INTERLACED: 1245 /* Supported natively */ 1246 break; 1247 case V4L2_FIELD_ALTERNATE: 1248 switch (vin->format.field) { 1249 case V4L2_FIELD_TOP: 1250 case V4L2_FIELD_BOTTOM: 1251 case V4L2_FIELD_NONE: 1252 case V4L2_FIELD_ALTERNATE: 1253 break; 1254 case V4L2_FIELD_INTERLACED_TB: 1255 case V4L2_FIELD_INTERLACED_BT: 1256 case V4L2_FIELD_INTERLACED: 1257 /* Use VIN hardware to combine the two fields */ 1258 fmt.format.height *= 2; 1259 break; 1260 default: 1261 return -EPIPE; 1262 } 1263 break; 1264 default: 1265 return -EPIPE; 1266 } 1267 1268 if (rvin_scaler_needed(vin)) { 1269 /* Gen3 can't scale NV12 */ 1270 if ((vin->info->model == RCAR_GEN3 || vin->info->model == RCAR_GEN4) && 1271 vin->format.pixelformat == V4L2_PIX_FMT_NV12) 1272 return -EPIPE; 1273 1274 if (!vin->scaler) 1275 return -EPIPE; 1276 } else { 1277 if (vin->format.pixelformat == V4L2_PIX_FMT_NV12) { 1278 if (ALIGN(fmt.format.width, 32) != vin->format.width || 1279 ALIGN(fmt.format.height, 32) != vin->format.height) 1280 return -EPIPE; 1281 } else { 1282 if (fmt.format.width != vin->format.width || 1283 fmt.format.height != vin->format.height) 1284 return -EPIPE; 1285 } 1286 } 1287 1288 if (fmt.format.code != vin->mbus_code) 1289 return -EPIPE; 1290 1291 return 0; 1292 } 1293 1294 static int rvin_set_stream(struct rvin_dev *vin, int on) 1295 { 1296 struct v4l2_subdev *sd; 1297 struct media_pad *pad; 1298 int ret; 1299 1300 /* No media controller used, simply pass operation to subdevice. */ 1301 if (!vin->info->use_mc) { 1302 ret = v4l2_subdev_call(vin->parallel.subdev, video, s_stream, 1303 on); 1304 1305 return ret == -ENOIOCTLCMD ? 0 : ret; 1306 } 1307 1308 pad = media_pad_remote_pad_first(&vin->pad); 1309 if (!pad) 1310 return -EPIPE; 1311 1312 sd = media_entity_to_v4l2_subdev(pad->entity); 1313 1314 if (!on) { 1315 video_device_pipeline_stop(&vin->vdev); 1316 return v4l2_subdev_disable_streams(sd, pad->index, BIT_ULL(0)); 1317 } 1318 1319 ret = rvin_mc_validate_format(vin, sd, pad); 1320 if (ret) 1321 return ret; 1322 1323 ret = video_device_pipeline_alloc_start(&vin->vdev); 1324 if (ret) 1325 return ret; 1326 1327 ret = v4l2_subdev_enable_streams(sd, pad->index, BIT_ULL(0)); 1328 if (ret == -ENOIOCTLCMD) 1329 ret = 0; 1330 if (ret) 1331 video_device_pipeline_stop(&vin->vdev); 1332 1333 return ret; 1334 } 1335 1336 int rvin_start_streaming(struct rvin_dev *vin) 1337 { 1338 unsigned long flags; 1339 int ret; 1340 1341 ret = rvin_set_stream(vin, 1); 1342 if (ret) 1343 return ret; 1344 1345 spin_lock_irqsave(&vin->qlock, flags); 1346 1347 vin->sequence = 0; 1348 1349 ret = rvin_capture_start(vin); 1350 if (ret) 1351 rvin_set_stream(vin, 0); 1352 1353 vin->running = true; 1354 1355 spin_unlock_irqrestore(&vin->qlock, flags); 1356 1357 return ret; 1358 } 1359 1360 static int rvin_start_streaming_vq(struct vb2_queue *vq, unsigned int count) 1361 { 1362 struct rvin_dev *vin = vb2_get_drv_priv(vq); 1363 int ret = -ENOMEM; 1364 1365 /* Allocate scratch buffer. */ 1366 vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage, 1367 &vin->scratch_phys, GFP_KERNEL); 1368 if (!vin->scratch) 1369 goto err_scratch; 1370 1371 ret = rvin_start_streaming(vin); 1372 if (ret) 1373 goto err_start; 1374 1375 return 0; 1376 err_start: 1377 dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, 1378 vin->scratch_phys); 1379 err_scratch: 1380 return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); 1381 1382 return ret; 1383 } 1384 1385 void rvin_stop_streaming(struct rvin_dev *vin) 1386 { 1387 unsigned long flags; 1388 1389 spin_lock_irqsave(&vin->qlock, flags); 1390 1391 if (!vin->running) { 1392 spin_unlock_irqrestore(&vin->qlock, flags); 1393 return; 1394 } 1395 1396 /* Wait for streaming to stop */ 1397 for (unsigned int i = 0; i < RVIN_RETRIES; i++) { 1398 rvin_capture_stop(vin); 1399 1400 /* Check if HW is stopped */ 1401 if (!rvin_capture_active(vin)) { 1402 break; 1403 } 1404 1405 spin_unlock_irqrestore(&vin->qlock, flags); 1406 msleep(RVIN_TIMEOUT_MS); 1407 spin_lock_irqsave(&vin->qlock, flags); 1408 } 1409 1410 if (rvin_capture_active(vin)) 1411 vin_err(vin, "Hardware did not stop\n"); 1412 1413 vin->running = false; 1414 1415 spin_unlock_irqrestore(&vin->qlock, flags); 1416 1417 rvin_set_stream(vin, 0); 1418 1419 /* disable interrupts */ 1420 rvin_disable_interrupts(vin); 1421 1422 /* Return unprocessed buffers from hardware. */ 1423 for (unsigned int i = 0; i < HW_BUFFER_NUM; i++) { 1424 if (vin->buf_hw[i].buffer) 1425 vb2_buffer_done(&vin->buf_hw[i].buffer->vb2_buf, 1426 VB2_BUF_STATE_ERROR); 1427 } 1428 1429 } 1430 1431 static void rvin_stop_streaming_vq(struct vb2_queue *vq) 1432 { 1433 struct rvin_dev *vin = vb2_get_drv_priv(vq); 1434 1435 rvin_stop_streaming(vin); 1436 1437 /* Free scratch buffer. */ 1438 dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, 1439 vin->scratch_phys); 1440 1441 return_unused_buffers(vin, VB2_BUF_STATE_ERROR); 1442 } 1443 1444 static const struct vb2_ops rvin_qops = { 1445 .queue_setup = rvin_queue_setup, 1446 .buf_prepare = rvin_buffer_prepare, 1447 .buf_queue = rvin_buffer_queue, 1448 .start_streaming = rvin_start_streaming_vq, 1449 .stop_streaming = rvin_stop_streaming_vq, 1450 }; 1451 1452 void rvin_dma_unregister(struct rvin_dev *vin) 1453 { 1454 mutex_destroy(&vin->lock); 1455 1456 v4l2_device_unregister(&vin->v4l2_dev); 1457 } 1458 1459 int rvin_dma_register(struct rvin_dev *vin, int irq) 1460 { 1461 struct vb2_queue *q = &vin->queue; 1462 int i, ret; 1463 1464 /* Initialize the top-level structure */ 1465 ret = v4l2_device_register(vin->dev, &vin->v4l2_dev); 1466 if (ret) 1467 return ret; 1468 1469 mutex_init(&vin->lock); 1470 INIT_LIST_HEAD(&vin->buf_list); 1471 1472 spin_lock_init(&vin->qlock); 1473 1474 for (i = 0; i < HW_BUFFER_NUM; i++) 1475 vin->buf_hw[i].buffer = NULL; 1476 1477 /* buffer queue */ 1478 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1479 q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF; 1480 q->lock = &vin->lock; 1481 q->drv_priv = vin; 1482 q->buf_struct_size = sizeof(struct rvin_buffer); 1483 q->ops = &rvin_qops; 1484 q->mem_ops = &vb2_dma_contig_memops; 1485 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1486 q->min_queued_buffers = 4; 1487 q->dev = vin->dev; 1488 1489 ret = vb2_queue_init(q); 1490 if (ret < 0) { 1491 vin_err(vin, "failed to initialize VB2 queue\n"); 1492 goto error; 1493 } 1494 1495 /* irq */ 1496 ret = devm_request_irq(vin->dev, irq, rvin_irq, IRQF_SHARED, 1497 KBUILD_MODNAME, vin); 1498 if (ret) { 1499 vin_err(vin, "failed to request irq\n"); 1500 goto error; 1501 } 1502 1503 return 0; 1504 error: 1505 rvin_dma_unregister(vin); 1506 1507 return ret; 1508 } 1509 1510 /* ----------------------------------------------------------------------------- 1511 * Gen3 CHSEL manipulation 1512 */ 1513 1514 /* 1515 * There is no need to have locking around changing the routing 1516 * as it's only possible to do so when no VIN in the group is 1517 * streaming so nothing can race with the VNMC register. 1518 */ 1519 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) 1520 { 1521 const struct rvin_group_route *route; 1522 u32 ifmd = 0; 1523 u32 vnmc; 1524 int ret; 1525 1526 ret = pm_runtime_resume_and_get(vin->dev); 1527 if (ret < 0) 1528 return ret; 1529 1530 /* Make register writes take effect immediately. */ 1531 vnmc = rvin_read(vin, VNMC_REG); 1532 rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG); 1533 1534 /* 1535 * Set data expansion mode to "pad with 0s" by inspecting the routes 1536 * table to find out which bit fields are available in the IFMD 1537 * register. IFMD_DES1 controls data expansion mode for CSI20/21, 1538 * IFMD_DES0 controls data expansion mode for CSI40/41. 1539 */ 1540 for (route = vin->info->routes; route->chsel; route++) { 1541 if (route->csi == RVIN_CSI20 || route->csi == RVIN_CSI21) 1542 ifmd |= VNCSI_IFMD_DES1; 1543 else 1544 ifmd |= VNCSI_IFMD_DES0; 1545 1546 if (ifmd == (VNCSI_IFMD_DES0 | VNCSI_IFMD_DES1)) 1547 break; 1548 } 1549 1550 if (ifmd) { 1551 ifmd |= VNCSI_IFMD_CSI_CHSEL(chsel); 1552 rvin_write(vin, ifmd, VNCSI_IFMD_REG); 1553 } 1554 1555 vin_dbg(vin, "Set IFMD 0x%x\n", ifmd); 1556 1557 vin->chsel = chsel; 1558 1559 /* Restore VNMC. */ 1560 rvin_write(vin, vnmc, VNMC_REG); 1561 1562 pm_runtime_put(vin->dev); 1563 1564 return 0; 1565 } 1566 1567 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha) 1568 { 1569 unsigned long flags; 1570 u32 dmr; 1571 1572 spin_lock_irqsave(&vin->qlock, flags); 1573 1574 vin->alpha = alpha; 1575 1576 if (!vin->running) 1577 goto out; 1578 1579 switch (vin->format.pixelformat) { 1580 case V4L2_PIX_FMT_ARGB555: 1581 dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT; 1582 if (vin->alpha) 1583 dmr |= VNDMR_ABIT; 1584 break; 1585 case V4L2_PIX_FMT_ABGR32: 1586 dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK; 1587 dmr |= VNDMR_A8BIT(vin->alpha); 1588 break; 1589 default: 1590 goto out; 1591 } 1592 1593 rvin_write(vin, dmr, VNDMR_REG); 1594 out: 1595 spin_unlock_irqrestore(&vin->qlock, flags); 1596 } 1597