1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Renesas R-Car Fine Display Processor 4 * 5 * Video format converter and frame deinterlacer device. 6 * 7 * Author: Kieran Bingham, <kieran@bingham.xyz> 8 * Copyright (c) 2016 Renesas Electronics Corporation. 9 * 10 * This code is developed and inspired from the vim2m, rcar_jpu, 11 * m2m-deinterlace, and vsp1 drivers. 12 */ 13 14#include <linux/clk.h> 15#include <linux/delay.h> 16#include <linux/dma-mapping.h> 17#include <linux/fs.h> 18#include <linux/interrupt.h> 19#include <linux/module.h> 20#include <linux/of.h> 21#include <linux/of_device.h> 22#include <linux/platform_device.h> 23#include <linux/pm_runtime.h> 24#include <linux/sched.h> 25#include <linux/slab.h> 26#include <linux/timer.h> 27#include <media/rcar-fcp.h> 28#include <media/v4l2-ctrls.h> 29#include <media/v4l2-device.h> 30#include <media/v4l2-event.h> 31#include <media/v4l2-ioctl.h> 32#include <media/v4l2-mem2mem.h> 33#include <media/videobuf2-dma-contig.h> 34 35static unsigned int debug; 36module_param(debug, uint, 0644); 37MODULE_PARM_DESC(debug, "activate debug info"); 38 39/* Minimum and maximum frame width/height */ 40#define FDP1_MIN_W 80U 41#define FDP1_MIN_H 80U 42 43#define FDP1_MAX_W 3840U 44#define FDP1_MAX_H 2160U 45 46#define FDP1_MAX_PLANES 3U 47#define FDP1_MAX_STRIDE 8190U 48 49/* Flags that indicate a format can be used for capture/output */ 50#define FDP1_CAPTURE BIT(0) 51#define FDP1_OUTPUT BIT(1) 52 53#define DRIVER_NAME "rcar_fdp1" 54 55/* Number of Job's to have available on the processing queue */ 56#define FDP1_NUMBER_JOBS 8 57 58#define dprintk(fdp1, fmt, arg...) \ 59 v4l2_dbg(1, debug, &fdp1->v4l2_dev, "%s: " fmt, __func__, ## arg) 60 61/* 62 * FDP1 registers and bits 63 */ 64 65/* FDP1 start register - Imm */ 66#define FD1_CTL_CMD 0x0000 67#define FD1_CTL_CMD_STRCMD BIT(0) 68 69/* Sync generator register - Imm */ 70#define FD1_CTL_SGCMD 0x0004 71#define FD1_CTL_SGCMD_SGEN BIT(0) 72 73/* Register set end register - Imm */ 74#define FD1_CTL_REGEND 0x0008 75#define FD1_CTL_REGEND_REGEND BIT(0) 76 77/* Channel activation register - Vupdt */ 78#define FD1_CTL_CHACT 0x000c 79#define FD1_CTL_CHACT_SMW BIT(9) 80#define FD1_CTL_CHACT_WR BIT(8) 81#define FD1_CTL_CHACT_SMR BIT(3) 82#define FD1_CTL_CHACT_RD2 BIT(2) 83#define FD1_CTL_CHACT_RD1 BIT(1) 84#define FD1_CTL_CHACT_RD0 BIT(0) 85 86/* Operation Mode Register - Vupdt */ 87#define FD1_CTL_OPMODE 0x0010 88#define FD1_CTL_OPMODE_PRG BIT(4) 89#define FD1_CTL_OPMODE_VIMD_INTERRUPT (0 << 0) 90#define FD1_CTL_OPMODE_VIMD_BESTEFFORT (1 << 0) 91#define FD1_CTL_OPMODE_VIMD_NOINTERRUPT (2 << 0) 92 93#define FD1_CTL_VPERIOD 0x0014 94#define FD1_CTL_CLKCTRL 0x0018 95#define FD1_CTL_CLKCTRL_CSTP_N BIT(0) 96 97/* Software reset register */ 98#define FD1_CTL_SRESET 0x001c 99#define FD1_CTL_SRESET_SRST BIT(0) 100 101/* Control status register (V-update-status) */ 102#define FD1_CTL_STATUS 0x0024 103#define FD1_CTL_STATUS_VINT_CNT_MASK GENMASK(31, 16) 104#define FD1_CTL_STATUS_VINT_CNT_SHIFT 16 105#define FD1_CTL_STATUS_SGREGSET BIT(10) 106#define FD1_CTL_STATUS_SGVERR BIT(9) 107#define FD1_CTL_STATUS_SGFREND BIT(8) 108#define FD1_CTL_STATUS_BSY BIT(0) 109 110#define FD1_CTL_VCYCLE_STAT 0x0028 111 112/* Interrupt enable register */ 113#define FD1_CTL_IRQENB 0x0038 114/* Interrupt status register */ 115#define FD1_CTL_IRQSTA 0x003c 116/* Interrupt control register */ 117#define FD1_CTL_IRQFSET 0x0040 118 119/* Common IRQ Bit settings */ 120#define FD1_CTL_IRQ_VERE BIT(16) 121#define FD1_CTL_IRQ_VINTE BIT(4) 122#define FD1_CTL_IRQ_FREE BIT(0) 123#define FD1_CTL_IRQ_MASK (FD1_CTL_IRQ_VERE | \ 124 FD1_CTL_IRQ_VINTE | \ 125 FD1_CTL_IRQ_FREE) 126 127/* RPF */ 128#define FD1_RPF_SIZE 0x0060 129#define FD1_RPF_SIZE_MASK GENMASK(12, 0) 130#define FD1_RPF_SIZE_H_SHIFT 16 131#define FD1_RPF_SIZE_V_SHIFT 0 132 133#define FD1_RPF_FORMAT 0x0064 134#define FD1_RPF_FORMAT_CIPM BIT(16) 135#define FD1_RPF_FORMAT_RSPYCS BIT(13) 136#define FD1_RPF_FORMAT_RSPUVS BIT(12) 137#define FD1_RPF_FORMAT_CF BIT(8) 138 139#define FD1_RPF_PSTRIDE 0x0068 140#define FD1_RPF_PSTRIDE_Y_SHIFT 16 141#define FD1_RPF_PSTRIDE_C_SHIFT 0 142 143/* RPF0 Source Component Y Address register */ 144#define FD1_RPF0_ADDR_Y 0x006c 145 146/* RPF1 Current Picture Registers */ 147#define FD1_RPF1_ADDR_Y 0x0078 148#define FD1_RPF1_ADDR_C0 0x007c 149#define FD1_RPF1_ADDR_C1 0x0080 150 151/* RPF2 next picture register */ 152#define FD1_RPF2_ADDR_Y 0x0084 153 154#define FD1_RPF_SMSK_ADDR 0x0090 155#define FD1_RPF_SWAP 0x0094 156 157/* WPF */ 158#define FD1_WPF_FORMAT 0x00c0 159#define FD1_WPF_FORMAT_PDV_SHIFT 24 160#define FD1_WPF_FORMAT_FCNL BIT(20) 161#define FD1_WPF_FORMAT_WSPYCS BIT(15) 162#define FD1_WPF_FORMAT_WSPUVS BIT(14) 163#define FD1_WPF_FORMAT_WRTM_601_16 (0 << 9) 164#define FD1_WPF_FORMAT_WRTM_601_0 (1 << 9) 165#define FD1_WPF_FORMAT_WRTM_709_16 (2 << 9) 166#define FD1_WPF_FORMAT_CSC BIT(8) 167 168#define FD1_WPF_RNDCTL 0x00c4 169#define FD1_WPF_RNDCTL_CBRM BIT(28) 170#define FD1_WPF_RNDCTL_CLMD_NOCLIP (0 << 12) 171#define FD1_WPF_RNDCTL_CLMD_CLIP_16_235 (1 << 12) 172#define FD1_WPF_RNDCTL_CLMD_CLIP_1_254 (2 << 12) 173 174#define FD1_WPF_PSTRIDE 0x00c8 175#define FD1_WPF_PSTRIDE_Y_SHIFT 16 176#define FD1_WPF_PSTRIDE_C_SHIFT 0 177 178/* WPF Destination picture */ 179#define FD1_WPF_ADDR_Y 0x00cc 180#define FD1_WPF_ADDR_C0 0x00d0 181#define FD1_WPF_ADDR_C1 0x00d4 182#define FD1_WPF_SWAP 0x00d8 183#define FD1_WPF_SWAP_OSWAP_SHIFT 0 184#define FD1_WPF_SWAP_SSWAP_SHIFT 4 185 186/* WPF/RPF Common */ 187#define FD1_RWPF_SWAP_BYTE BIT(0) 188#define FD1_RWPF_SWAP_WORD BIT(1) 189#define FD1_RWPF_SWAP_LWRD BIT(2) 190#define FD1_RWPF_SWAP_LLWD BIT(3) 191 192/* IPC */ 193#define FD1_IPC_MODE 0x0100 194#define FD1_IPC_MODE_DLI BIT(8) 195#define FD1_IPC_MODE_DIM_ADAPT2D3D (0 << 0) 196#define FD1_IPC_MODE_DIM_FIXED2D (1 << 0) 197#define FD1_IPC_MODE_DIM_FIXED3D (2 << 0) 198#define FD1_IPC_MODE_DIM_PREVFIELD (3 << 0) 199#define FD1_IPC_MODE_DIM_NEXTFIELD (4 << 0) 200 201#define FD1_IPC_SMSK_THRESH 0x0104 202#define FD1_IPC_SMSK_THRESH_CONST 0x00010002 203 204#define FD1_IPC_COMB_DET 0x0108 205#define FD1_IPC_COMB_DET_CONST 0x00200040 206 207#define FD1_IPC_MOTDEC 0x010c 208#define FD1_IPC_MOTDEC_CONST 0x00008020 209 210/* DLI registers */ 211#define FD1_IPC_DLI_BLEND 0x0120 212#define FD1_IPC_DLI_BLEND_CONST 0x0080ff02 213 214#define FD1_IPC_DLI_HGAIN 0x0124 215#define FD1_IPC_DLI_HGAIN_CONST 0x001000ff 216 217#define FD1_IPC_DLI_SPRS 0x0128 218#define FD1_IPC_DLI_SPRS_CONST 0x009004ff 219 220#define FD1_IPC_DLI_ANGLE 0x012c 221#define FD1_IPC_DLI_ANGLE_CONST 0x0004080c 222 223#define FD1_IPC_DLI_ISOPIX0 0x0130 224#define FD1_IPC_DLI_ISOPIX0_CONST 0xff10ff10 225 226#define FD1_IPC_DLI_ISOPIX1 0x0134 227#define FD1_IPC_DLI_ISOPIX1_CONST 0x0000ff10 228 229/* Sensor registers */ 230#define FD1_IPC_SENSOR_TH0 0x0140 231#define FD1_IPC_SENSOR_TH0_CONST 0x20208080 232 233#define FD1_IPC_SENSOR_TH1 0x0144 234#define FD1_IPC_SENSOR_TH1_CONST 0 235 236#define FD1_IPC_SENSOR_CTL0 0x0170 237#define FD1_IPC_SENSOR_CTL0_CONST 0x00002201 238 239#define FD1_IPC_SENSOR_CTL1 0x0174 240#define FD1_IPC_SENSOR_CTL1_CONST 0 241 242#define FD1_IPC_SENSOR_CTL2 0x0178 243#define FD1_IPC_SENSOR_CTL2_X_SHIFT 16 244#define FD1_IPC_SENSOR_CTL2_Y_SHIFT 0 245 246#define FD1_IPC_SENSOR_CTL3 0x017c 247#define FD1_IPC_SENSOR_CTL3_0_SHIFT 16 248#define FD1_IPC_SENSOR_CTL3_1_SHIFT 0 249 250/* Line memory pixel number register */ 251#define FD1_IPC_LMEM 0x01e0 252#define FD1_IPC_LMEM_LINEAR 1024 253#define FD1_IPC_LMEM_TILE 960 254 255/* Internal Data (HW Version) */ 256#define FD1_IP_INTDATA 0x0800 257#define FD1_IP_H3_ES1 0x02010101 258#define FD1_IP_M3W 0x02010202 259#define FD1_IP_H3 0x02010203 260#define FD1_IP_M3N 0x02010204 261#define FD1_IP_E3 0x02010205 262 263/* LUTs */ 264#define FD1_LUT_DIF_ADJ 0x1000 265#define FD1_LUT_SAD_ADJ 0x1400 266#define FD1_LUT_BLD_GAIN 0x1800 267#define FD1_LUT_DIF_GAIN 0x1c00 268#define FD1_LUT_MDET 0x2000 269 270/** 271 * struct fdp1_fmt - The FDP1 internal format data 272 * @fourcc: the fourcc code, to match the V4L2 API 273 * @bpp: bits per pixel per plane 274 * @num_planes: number of planes 275 * @hsub: horizontal subsampling factor 276 * @vsub: vertical subsampling factor 277 * @fmt: 7-bit format code for the fdp1 hardware 278 * @swap_yc: the Y and C components are swapped (Y comes before C) 279 * @swap_uv: the U and V components are swapped (V comes before U) 280 * @swap: swap register control 281 * @types: types of queue this format is applicable to 282 */ 283struct fdp1_fmt { 284 u32 fourcc; 285 u8 bpp[3]; 286 u8 num_planes; 287 u8 hsub; 288 u8 vsub; 289 u8 fmt; 290 bool swap_yc; 291 bool swap_uv; 292 u8 swap; 293 u8 types; 294}; 295 296static const struct fdp1_fmt fdp1_formats[] = { 297 /* RGB formats are only supported by the Write Pixel Formatter */ 298 299 { V4L2_PIX_FMT_RGB332, { 8, 0, 0 }, 1, 1, 1, 0x00, false, false, 300 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 301 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 302 FDP1_CAPTURE }, 303 { V4L2_PIX_FMT_XRGB444, { 16, 0, 0 }, 1, 1, 1, 0x01, false, false, 304 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 305 FD1_RWPF_SWAP_WORD, 306 FDP1_CAPTURE }, 307 { V4L2_PIX_FMT_XRGB555, { 16, 0, 0 }, 1, 1, 1, 0x04, false, false, 308 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 309 FD1_RWPF_SWAP_WORD, 310 FDP1_CAPTURE }, 311 { V4L2_PIX_FMT_RGB565, { 16, 0, 0 }, 1, 1, 1, 0x06, false, false, 312 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 313 FD1_RWPF_SWAP_WORD, 314 FDP1_CAPTURE }, 315 { V4L2_PIX_FMT_ABGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, 316 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD, 317 FDP1_CAPTURE }, 318 { V4L2_PIX_FMT_XBGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, 319 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD, 320 FDP1_CAPTURE }, 321 { V4L2_PIX_FMT_ARGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, 322 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 323 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 324 FDP1_CAPTURE }, 325 { V4L2_PIX_FMT_XRGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, 326 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 327 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 328 FDP1_CAPTURE }, 329 { V4L2_PIX_FMT_RGB24, { 24, 0, 0 }, 1, 1, 1, 0x15, false, false, 330 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 331 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 332 FDP1_CAPTURE }, 333 { V4L2_PIX_FMT_BGR24, { 24, 0, 0 }, 1, 1, 1, 0x18, false, false, 334 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 335 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 336 FDP1_CAPTURE }, 337 { V4L2_PIX_FMT_ARGB444, { 16, 0, 0 }, 1, 1, 1, 0x19, false, false, 338 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 339 FD1_RWPF_SWAP_WORD, 340 FDP1_CAPTURE }, 341 { V4L2_PIX_FMT_ARGB555, { 16, 0, 0 }, 1, 1, 1, 0x1b, false, false, 342 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 343 FD1_RWPF_SWAP_WORD, 344 FDP1_CAPTURE }, 345 346 /* YUV Formats are supported by Read and Write Pixel Formatters */ 347 348 { V4L2_PIX_FMT_NV16M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, false, 349 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 350 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 351 FDP1_CAPTURE | FDP1_OUTPUT }, 352 { V4L2_PIX_FMT_NV61M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, true, 353 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 354 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 355 FDP1_CAPTURE | FDP1_OUTPUT }, 356 { V4L2_PIX_FMT_NV12M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, false, 357 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 358 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 359 FDP1_CAPTURE | FDP1_OUTPUT }, 360 { V4L2_PIX_FMT_NV21M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, true, 361 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 362 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 363 FDP1_CAPTURE | FDP1_OUTPUT }, 364 { V4L2_PIX_FMT_UYVY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, false, 365 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 366 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 367 FDP1_CAPTURE | FDP1_OUTPUT }, 368 { V4L2_PIX_FMT_VYUY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, true, 369 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 370 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 371 FDP1_CAPTURE | FDP1_OUTPUT }, 372 { V4L2_PIX_FMT_YUYV, { 16, 0, 0 }, 1, 2, 1, 0x47, true, false, 373 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 374 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 375 FDP1_CAPTURE | FDP1_OUTPUT }, 376 { V4L2_PIX_FMT_YVYU, { 16, 0, 0 }, 1, 2, 1, 0x47, true, true, 377 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 378 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 379 FDP1_CAPTURE | FDP1_OUTPUT }, 380 { V4L2_PIX_FMT_YUV444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, false, 381 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 382 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 383 FDP1_CAPTURE | FDP1_OUTPUT }, 384 { V4L2_PIX_FMT_YVU444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, true, 385 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 386 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 387 FDP1_CAPTURE | FDP1_OUTPUT }, 388 { V4L2_PIX_FMT_YUV422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, false, 389 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 390 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 391 FDP1_CAPTURE | FDP1_OUTPUT }, 392 { V4L2_PIX_FMT_YVU422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, true, 393 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 394 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 395 FDP1_CAPTURE | FDP1_OUTPUT }, 396 { V4L2_PIX_FMT_YUV420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, false, 397 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 398 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 399 FDP1_CAPTURE | FDP1_OUTPUT }, 400 { V4L2_PIX_FMT_YVU420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, true, 401 FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | 402 FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, 403 FDP1_CAPTURE | FDP1_OUTPUT }, 404}; 405 406static int fdp1_fmt_is_rgb(const struct fdp1_fmt *fmt) 407{ 408 return fmt->fmt <= 0x1b; /* Last RGB code */ 409} 410 411/* 412 * FDP1 Lookup tables range from 0...255 only 413 * 414 * Each table must be less than 256 entries, and all tables 415 * are padded out to 256 entries by duplicating the last value. 416 */ 417static const u8 fdp1_diff_adj[] = { 418 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf, 419 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3, 420 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 421}; 422 423static const u8 fdp1_sad_adj[] = { 424 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf, 425 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3, 426 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 427}; 428 429static const u8 fdp1_bld_gain[] = { 430 0x80, 431}; 432 433static const u8 fdp1_dif_gain[] = { 434 0x80, 435}; 436 437static const u8 fdp1_mdet[] = { 438 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 439 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 440 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 441 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 442 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 443 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 444 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 445 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 446 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 447 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 448 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 449 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 450 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 451 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 452 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 453 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 454 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 455 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 456 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 457 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 458 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 459 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 460 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 461 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 462 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 463 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 464 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 465 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 466 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 467 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 468 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 469 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff 470}; 471 472/* Per-queue, driver-specific private data */ 473struct fdp1_q_data { 474 const struct fdp1_fmt *fmt; 475 struct v4l2_pix_format_mplane format; 476 477 unsigned int vsize; 478 unsigned int stride_y; 479 unsigned int stride_c; 480}; 481 482static const struct fdp1_fmt *fdp1_find_format(u32 pixelformat) 483{ 484 const struct fdp1_fmt *fmt; 485 unsigned int i; 486 487 for (i = 0; i < ARRAY_SIZE(fdp1_formats); i++) { 488 fmt = &fdp1_formats[i]; 489 if (fmt->fourcc == pixelformat) 490 return fmt; 491 } 492 493 return NULL; 494} 495 496enum fdp1_deint_mode { 497 FDP1_PROGRESSIVE = 0, /* Must be zero when !deinterlacing */ 498 FDP1_ADAPT2D3D, 499 FDP1_FIXED2D, 500 FDP1_FIXED3D, 501 FDP1_PREVFIELD, 502 FDP1_NEXTFIELD, 503}; 504 505#define FDP1_DEINT_MODE_USES_NEXT(mode) \ 506 (mode == FDP1_ADAPT2D3D || \ 507 mode == FDP1_FIXED3D || \ 508 mode == FDP1_NEXTFIELD) 509 510#define FDP1_DEINT_MODE_USES_PREV(mode) \ 511 (mode == FDP1_ADAPT2D3D || \ 512 mode == FDP1_FIXED3D || \ 513 mode == FDP1_PREVFIELD) 514 515/* 516 * FDP1 operates on potentially 3 fields, which are tracked 517 * from the VB buffers using this context structure. 518 * Will always be a field or a full frame, never two fields. 519 */ 520struct fdp1_field_buffer { 521 struct vb2_v4l2_buffer *vb; 522 dma_addr_t addrs[3]; 523 524 /* Should be NONE:TOP:BOTTOM only */ 525 enum v4l2_field field; 526 527 /* Flag to indicate this is the last field in the vb */ 528 bool last_field; 529 530 /* Buffer queue lists */ 531 struct list_head list; 532}; 533 534struct fdp1_buffer { 535 struct v4l2_m2m_buffer m2m_buf; 536 struct fdp1_field_buffer fields[2]; 537 unsigned int num_fields; 538}; 539 540static inline struct fdp1_buffer *to_fdp1_buffer(struct vb2_v4l2_buffer *vb) 541{ 542 return container_of(vb, struct fdp1_buffer, m2m_buf.vb); 543} 544 545struct fdp1_job { 546 struct fdp1_field_buffer *previous; 547 struct fdp1_field_buffer *active; 548 struct fdp1_field_buffer *next; 549 struct fdp1_field_buffer *dst; 550 551 /* A job can only be on one list at a time */ 552 struct list_head list; 553}; 554 555struct fdp1_dev { 556 struct v4l2_device v4l2_dev; 557 struct video_device vfd; 558 559 struct mutex dev_mutex; 560 spinlock_t irqlock; 561 spinlock_t device_process_lock; 562 563 void __iomem *regs; 564 unsigned int irq; 565 struct device *dev; 566 567 /* Job Queues */ 568 struct fdp1_job jobs[FDP1_NUMBER_JOBS]; 569 struct list_head free_job_list; 570 struct list_head queued_job_list; 571 struct list_head hw_job_list; 572 573 unsigned int clk_rate; 574 575 struct rcar_fcp_device *fcp; 576 struct v4l2_m2m_dev *m2m_dev; 577}; 578 579struct fdp1_ctx { 580 struct v4l2_fh fh; 581 struct fdp1_dev *fdp1; 582 583 struct v4l2_ctrl_handler hdl; 584 unsigned int sequence; 585 586 /* Processed buffers in this transaction */ 587 u8 num_processed; 588 589 /* Transaction length (i.e. how many buffers per transaction) */ 590 u32 translen; 591 592 /* Abort requested by m2m */ 593 int aborting; 594 595 /* Deinterlace processing mode */ 596 enum fdp1_deint_mode deint_mode; 597 598 /* 599 * Adaptive 2D/3D mode uses a shared mask 600 * This is allocated at streamon, if the ADAPT2D3D mode 601 * is requested 602 */ 603 unsigned int smsk_size; 604 dma_addr_t smsk_addr[2]; 605 void *smsk_cpu; 606 607 /* Capture pipeline, can specify an alpha value 608 * for supported formats. 0-255 only 609 */ 610 unsigned char alpha; 611 612 /* Source and destination queue data */ 613 struct fdp1_q_data out_q; /* HW Source */ 614 struct fdp1_q_data cap_q; /* HW Destination */ 615 616 /* 617 * Field Queues 618 * Interlaced fields are used on 3 occasions, and tracked in this list. 619 * 620 * V4L2 Buffers are tracked inside the fdp1_buffer 621 * and released when the last 'field' completes 622 */ 623 struct list_head fields_queue; 624 unsigned int buffers_queued; 625 626 /* 627 * For de-interlacing we need to track our previous buffer 628 * while preparing our job lists. 629 */ 630 struct fdp1_field_buffer *previous; 631}; 632 633static inline struct fdp1_ctx *fh_to_ctx(struct v4l2_fh *fh) 634{ 635 return container_of(fh, struct fdp1_ctx, fh); 636} 637 638static struct fdp1_q_data *get_q_data(struct fdp1_ctx *ctx, 639 enum v4l2_buf_type type) 640{ 641 if (V4L2_TYPE_IS_OUTPUT(type)) 642 return &ctx->out_q; 643 else 644 return &ctx->cap_q; 645} 646 647/* 648 * list_remove_job: Take the first item off the specified job list 649 * 650 * Returns: pointer to a job, or NULL if the list is empty. 651 */ 652static struct fdp1_job *list_remove_job(struct fdp1_dev *fdp1, 653 struct list_head *list) 654{ 655 struct fdp1_job *job; 656 unsigned long flags; 657 658 spin_lock_irqsave(&fdp1->irqlock, flags); 659 job = list_first_entry_or_null(list, struct fdp1_job, list); 660 if (job) 661 list_del(&job->list); 662 spin_unlock_irqrestore(&fdp1->irqlock, flags); 663 664 return job; 665} 666 667/* 668 * list_add_job: Add a job to the specified job list 669 * 670 * Returns: void - always succeeds 671 */ 672static void list_add_job(struct fdp1_dev *fdp1, 673 struct list_head *list, 674 struct fdp1_job *job) 675{ 676 unsigned long flags; 677 678 spin_lock_irqsave(&fdp1->irqlock, flags); 679 list_add_tail(&job->list, list); 680 spin_unlock_irqrestore(&fdp1->irqlock, flags); 681} 682 683static struct fdp1_job *fdp1_job_alloc(struct fdp1_dev *fdp1) 684{ 685 return list_remove_job(fdp1, &fdp1->free_job_list); 686} 687 688static void fdp1_job_free(struct fdp1_dev *fdp1, struct fdp1_job *job) 689{ 690 /* Ensure that all residue from previous jobs is gone */ 691 memset(job, 0, sizeof(struct fdp1_job)); 692 693 list_add_job(fdp1, &fdp1->free_job_list, job); 694} 695 696static void queue_job(struct fdp1_dev *fdp1, struct fdp1_job *job) 697{ 698 list_add_job(fdp1, &fdp1->queued_job_list, job); 699} 700 701static struct fdp1_job *get_queued_job(struct fdp1_dev *fdp1) 702{ 703 return list_remove_job(fdp1, &fdp1->queued_job_list); 704} 705 706static void queue_hw_job(struct fdp1_dev *fdp1, struct fdp1_job *job) 707{ 708 list_add_job(fdp1, &fdp1->hw_job_list, job); 709} 710 711static struct fdp1_job *get_hw_queued_job(struct fdp1_dev *fdp1) 712{ 713 return list_remove_job(fdp1, &fdp1->hw_job_list); 714} 715 716/* 717 * Buffer lists handling 718 */ 719static void fdp1_field_complete(struct fdp1_ctx *ctx, 720 struct fdp1_field_buffer *fbuf) 721{ 722 /* job->previous may be on the first field */ 723 if (!fbuf) 724 return; 725 726 if (fbuf->last_field) 727 v4l2_m2m_buf_done(fbuf->vb, VB2_BUF_STATE_DONE); 728} 729 730static void fdp1_queue_field(struct fdp1_ctx *ctx, 731 struct fdp1_field_buffer *fbuf) 732{ 733 unsigned long flags; 734 735 spin_lock_irqsave(&ctx->fdp1->irqlock, flags); 736 list_add_tail(&fbuf->list, &ctx->fields_queue); 737 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); 738 739 ctx->buffers_queued++; 740} 741 742static struct fdp1_field_buffer *fdp1_dequeue_field(struct fdp1_ctx *ctx) 743{ 744 struct fdp1_field_buffer *fbuf; 745 unsigned long flags; 746 747 ctx->buffers_queued--; 748 749 spin_lock_irqsave(&ctx->fdp1->irqlock, flags); 750 fbuf = list_first_entry_or_null(&ctx->fields_queue, 751 struct fdp1_field_buffer, list); 752 if (fbuf) 753 list_del(&fbuf->list); 754 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); 755 756 return fbuf; 757} 758 759/* 760 * Return the next field in the queue - or NULL, 761 * without removing the item from the list 762 */ 763static struct fdp1_field_buffer *fdp1_peek_queued_field(struct fdp1_ctx *ctx) 764{ 765 struct fdp1_field_buffer *fbuf; 766 unsigned long flags; 767 768 spin_lock_irqsave(&ctx->fdp1->irqlock, flags); 769 fbuf = list_first_entry_or_null(&ctx->fields_queue, 770 struct fdp1_field_buffer, list); 771 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); 772 773 return fbuf; 774} 775 776static u32 fdp1_read(struct fdp1_dev *fdp1, unsigned int reg) 777{ 778 u32 value = ioread32(fdp1->regs + reg); 779 780 if (debug >= 2) 781 dprintk(fdp1, "Read 0x%08x from 0x%04x\n", value, reg); 782 783 return value; 784} 785 786static void fdp1_write(struct fdp1_dev *fdp1, u32 val, unsigned int reg) 787{ 788 if (debug >= 2) 789 dprintk(fdp1, "Write 0x%08x to 0x%04x\n", val, reg); 790 791 iowrite32(val, fdp1->regs + reg); 792} 793 794/* IPC registers are to be programmed with constant values */ 795static void fdp1_set_ipc_dli(struct fdp1_ctx *ctx) 796{ 797 struct fdp1_dev *fdp1 = ctx->fdp1; 798 799 fdp1_write(fdp1, FD1_IPC_SMSK_THRESH_CONST, FD1_IPC_SMSK_THRESH); 800 fdp1_write(fdp1, FD1_IPC_COMB_DET_CONST, FD1_IPC_COMB_DET); 801 fdp1_write(fdp1, FD1_IPC_MOTDEC_CONST, FD1_IPC_MOTDEC); 802 803 fdp1_write(fdp1, FD1_IPC_DLI_BLEND_CONST, FD1_IPC_DLI_BLEND); 804 fdp1_write(fdp1, FD1_IPC_DLI_HGAIN_CONST, FD1_IPC_DLI_HGAIN); 805 fdp1_write(fdp1, FD1_IPC_DLI_SPRS_CONST, FD1_IPC_DLI_SPRS); 806 fdp1_write(fdp1, FD1_IPC_DLI_ANGLE_CONST, FD1_IPC_DLI_ANGLE); 807 fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX0_CONST, FD1_IPC_DLI_ISOPIX0); 808 fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX1_CONST, FD1_IPC_DLI_ISOPIX1); 809} 810 811 812static void fdp1_set_ipc_sensor(struct fdp1_ctx *ctx) 813{ 814 struct fdp1_dev *fdp1 = ctx->fdp1; 815 struct fdp1_q_data *src_q_data = &ctx->out_q; 816 unsigned int x0, x1; 817 unsigned int hsize = src_q_data->format.width; 818 unsigned int vsize = src_q_data->format.height; 819 820 x0 = hsize / 3; 821 x1 = 2 * hsize / 3; 822 823 fdp1_write(fdp1, FD1_IPC_SENSOR_TH0_CONST, FD1_IPC_SENSOR_TH0); 824 fdp1_write(fdp1, FD1_IPC_SENSOR_TH1_CONST, FD1_IPC_SENSOR_TH1); 825 fdp1_write(fdp1, FD1_IPC_SENSOR_CTL0_CONST, FD1_IPC_SENSOR_CTL0); 826 fdp1_write(fdp1, FD1_IPC_SENSOR_CTL1_CONST, FD1_IPC_SENSOR_CTL1); 827 828 fdp1_write(fdp1, ((hsize - 1) << FD1_IPC_SENSOR_CTL2_X_SHIFT) | 829 ((vsize - 1) << FD1_IPC_SENSOR_CTL2_Y_SHIFT), 830 FD1_IPC_SENSOR_CTL2); 831 832 fdp1_write(fdp1, (x0 << FD1_IPC_SENSOR_CTL3_0_SHIFT) | 833 (x1 << FD1_IPC_SENSOR_CTL3_1_SHIFT), 834 FD1_IPC_SENSOR_CTL3); 835} 836 837/* 838 * fdp1_write_lut: Write a padded LUT to the hw 839 * 840 * FDP1 uses constant data for de-interlacing processing, 841 * with large tables. These hardware tables are all 256 bytes 842 * long, however they often contain repeated data at the end. 843 * 844 * The last byte of the table is written to all remaining entries. 845 */ 846static void fdp1_write_lut(struct fdp1_dev *fdp1, const u8 *lut, 847 unsigned int len, unsigned int base) 848{ 849 unsigned int i; 850 u8 pad; 851 852 /* Tables larger than the hw are clipped */ 853 len = min(len, 256u); 854 855 for (i = 0; i < len; i++) 856 fdp1_write(fdp1, lut[i], base + (i*4)); 857 858 /* Tables are padded with the last entry */ 859 pad = lut[i-1]; 860 861 for (; i < 256; i++) 862 fdp1_write(fdp1, pad, base + (i*4)); 863} 864 865static void fdp1_set_lut(struct fdp1_dev *fdp1) 866{ 867 fdp1_write_lut(fdp1, fdp1_diff_adj, ARRAY_SIZE(fdp1_diff_adj), 868 FD1_LUT_DIF_ADJ); 869 fdp1_write_lut(fdp1, fdp1_sad_adj, ARRAY_SIZE(fdp1_sad_adj), 870 FD1_LUT_SAD_ADJ); 871 fdp1_write_lut(fdp1, fdp1_bld_gain, ARRAY_SIZE(fdp1_bld_gain), 872 FD1_LUT_BLD_GAIN); 873 fdp1_write_lut(fdp1, fdp1_dif_gain, ARRAY_SIZE(fdp1_dif_gain), 874 FD1_LUT_DIF_GAIN); 875 fdp1_write_lut(fdp1, fdp1_mdet, ARRAY_SIZE(fdp1_mdet), 876 FD1_LUT_MDET); 877} 878 879static void fdp1_configure_rpf(struct fdp1_ctx *ctx, 880 struct fdp1_job *job) 881{ 882 struct fdp1_dev *fdp1 = ctx->fdp1; 883 u32 picture_size; 884 u32 pstride; 885 u32 format; 886 u32 smsk_addr; 887 888 struct fdp1_q_data *q_data = &ctx->out_q; 889 890 /* Picture size is common to Source and Destination frames */ 891 picture_size = (q_data->format.width << FD1_RPF_SIZE_H_SHIFT) 892 | (q_data->vsize << FD1_RPF_SIZE_V_SHIFT); 893 894 /* Strides */ 895 pstride = q_data->stride_y << FD1_RPF_PSTRIDE_Y_SHIFT; 896 if (q_data->format.num_planes > 1) 897 pstride |= q_data->stride_c << FD1_RPF_PSTRIDE_C_SHIFT; 898 899 /* Format control */ 900 format = q_data->fmt->fmt; 901 if (q_data->fmt->swap_yc) 902 format |= FD1_RPF_FORMAT_RSPYCS; 903 904 if (q_data->fmt->swap_uv) 905 format |= FD1_RPF_FORMAT_RSPUVS; 906 907 if (job->active->field == V4L2_FIELD_BOTTOM) { 908 format |= FD1_RPF_FORMAT_CF; /* Set for Bottom field */ 909 smsk_addr = ctx->smsk_addr[0]; 910 } else { 911 smsk_addr = ctx->smsk_addr[1]; 912 } 913 914 /* Deint mode is non-zero when deinterlacing */ 915 if (ctx->deint_mode) 916 format |= FD1_RPF_FORMAT_CIPM; 917 918 fdp1_write(fdp1, format, FD1_RPF_FORMAT); 919 fdp1_write(fdp1, q_data->fmt->swap, FD1_RPF_SWAP); 920 fdp1_write(fdp1, picture_size, FD1_RPF_SIZE); 921 fdp1_write(fdp1, pstride, FD1_RPF_PSTRIDE); 922 fdp1_write(fdp1, smsk_addr, FD1_RPF_SMSK_ADDR); 923 924 /* Previous Field Channel (CH0) */ 925 if (job->previous) 926 fdp1_write(fdp1, job->previous->addrs[0], FD1_RPF0_ADDR_Y); 927 928 /* Current Field Channel (CH1) */ 929 fdp1_write(fdp1, job->active->addrs[0], FD1_RPF1_ADDR_Y); 930 fdp1_write(fdp1, job->active->addrs[1], FD1_RPF1_ADDR_C0); 931 fdp1_write(fdp1, job->active->addrs[2], FD1_RPF1_ADDR_C1); 932 933 /* Next Field Channel (CH2) */ 934 if (job->next) 935 fdp1_write(fdp1, job->next->addrs[0], FD1_RPF2_ADDR_Y); 936} 937 938static void fdp1_configure_wpf(struct fdp1_ctx *ctx, 939 struct fdp1_job *job) 940{ 941 struct fdp1_dev *fdp1 = ctx->fdp1; 942 struct fdp1_q_data *src_q_data = &ctx->out_q; 943 struct fdp1_q_data *q_data = &ctx->cap_q; 944 u32 pstride; 945 u32 format; 946 u32 swap; 947 u32 rndctl; 948 949 pstride = q_data->format.plane_fmt[0].bytesperline 950 << FD1_WPF_PSTRIDE_Y_SHIFT; 951 952 if (q_data->format.num_planes > 1) 953 pstride |= q_data->format.plane_fmt[1].bytesperline 954 << FD1_WPF_PSTRIDE_C_SHIFT; 955 956 format = q_data->fmt->fmt; /* Output Format Code */ 957 958 if (q_data->fmt->swap_yc) 959 format |= FD1_WPF_FORMAT_WSPYCS; 960 961 if (q_data->fmt->swap_uv) 962 format |= FD1_WPF_FORMAT_WSPUVS; 963 964 if (fdp1_fmt_is_rgb(q_data->fmt)) { 965 /* Enable Colour Space conversion */ 966 format |= FD1_WPF_FORMAT_CSC; 967 968 /* Set WRTM */ 969 if (src_q_data->format.ycbcr_enc == V4L2_YCBCR_ENC_709) 970 format |= FD1_WPF_FORMAT_WRTM_709_16; 971 else if (src_q_data->format.quantization == 972 V4L2_QUANTIZATION_FULL_RANGE) 973 format |= FD1_WPF_FORMAT_WRTM_601_0; 974 else 975 format |= FD1_WPF_FORMAT_WRTM_601_16; 976 } 977 978 /* Set an alpha value into the Pad Value */ 979 format |= ctx->alpha << FD1_WPF_FORMAT_PDV_SHIFT; 980 981 /* Determine picture rounding and clipping */ 982 rndctl = FD1_WPF_RNDCTL_CBRM; /* Rounding Off */ 983 rndctl |= FD1_WPF_RNDCTL_CLMD_NOCLIP; 984 985 /* WPF Swap needs both ISWAP and OSWAP setting */ 986 swap = q_data->fmt->swap << FD1_WPF_SWAP_OSWAP_SHIFT; 987 swap |= src_q_data->fmt->swap << FD1_WPF_SWAP_SSWAP_SHIFT; 988 989 fdp1_write(fdp1, format, FD1_WPF_FORMAT); 990 fdp1_write(fdp1, rndctl, FD1_WPF_RNDCTL); 991 fdp1_write(fdp1, swap, FD1_WPF_SWAP); 992 fdp1_write(fdp1, pstride, FD1_WPF_PSTRIDE); 993 994 fdp1_write(fdp1, job->dst->addrs[0], FD1_WPF_ADDR_Y); 995 fdp1_write(fdp1, job->dst->addrs[1], FD1_WPF_ADDR_C0); 996 fdp1_write(fdp1, job->dst->addrs[2], FD1_WPF_ADDR_C1); 997} 998 999static void fdp1_configure_deint_mode(struct fdp1_ctx *ctx, 1000 struct fdp1_job *job) 1001{ 1002 struct fdp1_dev *fdp1 = ctx->fdp1; 1003 u32 opmode = FD1_CTL_OPMODE_VIMD_NOINTERRUPT; 1004 u32 ipcmode = FD1_IPC_MODE_DLI; /* Always set */ 1005 u32 channels = FD1_CTL_CHACT_WR | FD1_CTL_CHACT_RD1; /* Always on */ 1006 1007 /* De-interlacing Mode */ 1008 switch (ctx->deint_mode) { 1009 default: 1010 case FDP1_PROGRESSIVE: 1011 dprintk(fdp1, "Progressive Mode\n"); 1012 opmode |= FD1_CTL_OPMODE_PRG; 1013 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D; 1014 break; 1015 case FDP1_ADAPT2D3D: 1016 dprintk(fdp1, "Adapt2D3D Mode\n"); 1017 if (ctx->sequence == 0 || ctx->aborting) 1018 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D; 1019 else 1020 ipcmode |= FD1_IPC_MODE_DIM_ADAPT2D3D; 1021 1022 if (ctx->sequence > 1) { 1023 channels |= FD1_CTL_CHACT_SMW; 1024 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2; 1025 } 1026 1027 if (ctx->sequence > 2) 1028 channels |= FD1_CTL_CHACT_SMR; 1029 1030 break; 1031 case FDP1_FIXED3D: 1032 dprintk(fdp1, "Fixed 3D Mode\n"); 1033 ipcmode |= FD1_IPC_MODE_DIM_FIXED3D; 1034 /* Except for first and last frame, enable all channels */ 1035 if (!(ctx->sequence == 0 || ctx->aborting)) 1036 channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2; 1037 break; 1038 case FDP1_FIXED2D: 1039 dprintk(fdp1, "Fixed 2D Mode\n"); 1040 ipcmode |= FD1_IPC_MODE_DIM_FIXED2D; 1041 /* No extra channels enabled */ 1042 break; 1043 case FDP1_PREVFIELD: 1044 dprintk(fdp1, "Previous Field Mode\n"); 1045 ipcmode |= FD1_IPC_MODE_DIM_PREVFIELD; 1046 channels |= FD1_CTL_CHACT_RD0; /* Previous */ 1047 break; 1048 case FDP1_NEXTFIELD: 1049 dprintk(fdp1, "Next Field Mode\n"); 1050 ipcmode |= FD1_IPC_MODE_DIM_NEXTFIELD; 1051 channels |= FD1_CTL_CHACT_RD2; /* Next */ 1052 break; 1053 } 1054 1055 fdp1_write(fdp1, channels, FD1_CTL_CHACT); 1056 fdp1_write(fdp1, opmode, FD1_CTL_OPMODE); 1057 fdp1_write(fdp1, ipcmode, FD1_IPC_MODE); 1058} 1059 1060/* 1061 * fdp1_device_process() - Run the hardware 1062 * 1063 * Configure and start the hardware to generate a single frame 1064 * of output given our input parameters. 1065 */ 1066static int fdp1_device_process(struct fdp1_ctx *ctx) 1067 1068{ 1069 struct fdp1_dev *fdp1 = ctx->fdp1; 1070 struct fdp1_job *job; 1071 unsigned long flags; 1072 1073 spin_lock_irqsave(&fdp1->device_process_lock, flags); 1074 1075 /* Get a job to process */ 1076 job = get_queued_job(fdp1); 1077 if (!job) { 1078 /* 1079 * VINT can call us to see if we can queue another job. 1080 * If we have no work to do, we simply return. 1081 */ 1082 spin_unlock_irqrestore(&fdp1->device_process_lock, flags); 1083 return 0; 1084 } 1085 1086 /* First Frame only? ... */ 1087 fdp1_write(fdp1, FD1_CTL_CLKCTRL_CSTP_N, FD1_CTL_CLKCTRL); 1088 1089 /* Set the mode, and configuration */ 1090 fdp1_configure_deint_mode(ctx, job); 1091 1092 /* DLI Static Configuration */ 1093 fdp1_set_ipc_dli(ctx); 1094 1095 /* Sensor Configuration */ 1096 fdp1_set_ipc_sensor(ctx); 1097 1098 /* Setup the source picture */ 1099 fdp1_configure_rpf(ctx, job); 1100 1101 /* Setup the destination picture */ 1102 fdp1_configure_wpf(ctx, job); 1103 1104 /* Line Memory Pixel Number Register for linear access */ 1105 fdp1_write(fdp1, FD1_IPC_LMEM_LINEAR, FD1_IPC_LMEM); 1106 1107 /* Enable Interrupts */ 1108 fdp1_write(fdp1, FD1_CTL_IRQ_MASK, FD1_CTL_IRQENB); 1109 1110 /* Finally, the Immediate Registers */ 1111 1112 /* This job is now in the HW queue */ 1113 queue_hw_job(fdp1, job); 1114 1115 /* Start the command */ 1116 fdp1_write(fdp1, FD1_CTL_CMD_STRCMD, FD1_CTL_CMD); 1117 1118 /* Registers will update to HW at next VINT */ 1119 fdp1_write(fdp1, FD1_CTL_REGEND_REGEND, FD1_CTL_REGEND); 1120 1121 /* Enable VINT Generator */ 1122 fdp1_write(fdp1, FD1_CTL_SGCMD_SGEN, FD1_CTL_SGCMD); 1123 1124 spin_unlock_irqrestore(&fdp1->device_process_lock, flags); 1125 1126 return 0; 1127} 1128 1129/* 1130 * mem2mem callbacks 1131 */ 1132 1133/* 1134 * job_ready() - check whether an instance is ready to be scheduled to run 1135 */ 1136static int fdp1_m2m_job_ready(void *priv) 1137{ 1138 struct fdp1_ctx *ctx = priv; 1139 struct fdp1_q_data *src_q_data = &ctx->out_q; 1140 int srcbufs = 1; 1141 int dstbufs = 1; 1142 1143 dprintk(ctx->fdp1, "+ Src: %d : Dst: %d\n", 1144 v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx), 1145 v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)); 1146 1147 /* One output buffer is required for each field */ 1148 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field)) 1149 dstbufs = 2; 1150 1151 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < srcbufs 1152 || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < dstbufs) { 1153 dprintk(ctx->fdp1, "Not enough buffers available\n"); 1154 return 0; 1155 } 1156 1157 return 1; 1158} 1159 1160static void fdp1_m2m_job_abort(void *priv) 1161{ 1162 struct fdp1_ctx *ctx = priv; 1163 1164 dprintk(ctx->fdp1, "+\n"); 1165 1166 /* Will cancel the transaction in the next interrupt handler */ 1167 ctx->aborting = 1; 1168 1169 /* Immediate abort sequence */ 1170 fdp1_write(ctx->fdp1, 0, FD1_CTL_SGCMD); 1171 fdp1_write(ctx->fdp1, FD1_CTL_SRESET_SRST, FD1_CTL_SRESET); 1172} 1173 1174/* 1175 * fdp1_prepare_job: Prepare and queue a new job for a single action of work 1176 * 1177 * Prepare the next field, (or frame in progressive) and an output 1178 * buffer for the hardware to perform a single operation. 1179 */ 1180static struct fdp1_job *fdp1_prepare_job(struct fdp1_ctx *ctx) 1181{ 1182 struct vb2_v4l2_buffer *vbuf; 1183 struct fdp1_buffer *fbuf; 1184 struct fdp1_dev *fdp1 = ctx->fdp1; 1185 struct fdp1_job *job; 1186 unsigned int buffers_required = 1; 1187 1188 dprintk(fdp1, "+\n"); 1189 1190 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode)) 1191 buffers_required = 2; 1192 1193 if (ctx->buffers_queued < buffers_required) 1194 return NULL; 1195 1196 job = fdp1_job_alloc(fdp1); 1197 if (!job) { 1198 dprintk(fdp1, "No free jobs currently available\n"); 1199 return NULL; 1200 } 1201 1202 job->active = fdp1_dequeue_field(ctx); 1203 if (!job->active) { 1204 /* Buffer check should prevent this ever happening */ 1205 dprintk(fdp1, "No input buffers currently available\n"); 1206 1207 fdp1_job_free(fdp1, job); 1208 return NULL; 1209 } 1210 1211 dprintk(fdp1, "+ Buffer en-route...\n"); 1212 1213 /* Source buffers have been prepared on our buffer_queue 1214 * Prepare our Output buffer 1215 */ 1216 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1217 fbuf = to_fdp1_buffer(vbuf); 1218 job->dst = &fbuf->fields[0]; 1219 1220 job->active->vb->sequence = ctx->sequence; 1221 job->dst->vb->sequence = ctx->sequence; 1222 ctx->sequence++; 1223 1224 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) { 1225 job->previous = ctx->previous; 1226 1227 /* Active buffer becomes the next job's previous buffer */ 1228 ctx->previous = job->active; 1229 } 1230 1231 if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode)) { 1232 /* Must be called after 'active' is dequeued */ 1233 job->next = fdp1_peek_queued_field(ctx); 1234 } 1235 1236 /* Transfer timestamps and flags from src->dst */ 1237 1238 job->dst->vb->vb2_buf.timestamp = job->active->vb->vb2_buf.timestamp; 1239 1240 job->dst->vb->flags = job->active->vb->flags & 1241 V4L2_BUF_FLAG_TSTAMP_SRC_MASK; 1242 1243 /* Ideally, the frame-end function will just 'check' to see 1244 * if there are more jobs instead 1245 */ 1246 ctx->translen++; 1247 1248 /* Finally, Put this job on the processing queue */ 1249 queue_job(fdp1, job); 1250 1251 dprintk(fdp1, "Job Queued translen = %d\n", ctx->translen); 1252 1253 return job; 1254} 1255 1256/* fdp1_m2m_device_run() - prepares and starts the device for an M2M task 1257 * 1258 * A single input buffer is taken and serialised into our fdp1_buffer 1259 * queue. The queue is then processed to create as many jobs as possible 1260 * from our available input. 1261 */ 1262static void fdp1_m2m_device_run(void *priv) 1263{ 1264 struct fdp1_ctx *ctx = priv; 1265 struct fdp1_dev *fdp1 = ctx->fdp1; 1266 struct vb2_v4l2_buffer *src_vb; 1267 struct fdp1_buffer *buf; 1268 unsigned int i; 1269 1270 dprintk(fdp1, "+\n"); 1271 1272 ctx->translen = 0; 1273 1274 /* Get our incoming buffer of either one or two fields, or one frame */ 1275 src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1276 buf = to_fdp1_buffer(src_vb); 1277 1278 for (i = 0; i < buf->num_fields; i++) { 1279 struct fdp1_field_buffer *fbuf = &buf->fields[i]; 1280 1281 fdp1_queue_field(ctx, fbuf); 1282 dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n", 1283 i, fbuf->last_field); 1284 } 1285 1286 /* Queue as many jobs as our data provides for */ 1287 while (fdp1_prepare_job(ctx)) 1288 ; 1289 1290 if (ctx->translen == 0) { 1291 dprintk(fdp1, "No jobs were processed. M2M action complete\n"); 1292 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx); 1293 return; 1294 } 1295 1296 /* Kick the job processing action */ 1297 fdp1_device_process(ctx); 1298} 1299 1300/* 1301 * device_frame_end: 1302 * 1303 * Handles the M2M level after a buffer completion event. 1304 */ 1305static void device_frame_end(struct fdp1_dev *fdp1, 1306 enum vb2_buffer_state state) 1307{ 1308 struct fdp1_ctx *ctx; 1309 unsigned long flags; 1310 struct fdp1_job *job = get_hw_queued_job(fdp1); 1311 1312 dprintk(fdp1, "+\n"); 1313 1314 ctx = v4l2_m2m_get_curr_priv(fdp1->m2m_dev); 1315 1316 if (ctx == NULL) { 1317 v4l2_err(&fdp1->v4l2_dev, 1318 "Instance released before the end of transaction\n"); 1319 return; 1320 } 1321 1322 ctx->num_processed++; 1323 1324 /* 1325 * fdp1_field_complete will call buf_done only when the last vb2_buffer 1326 * reference is complete 1327 */ 1328 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) 1329 fdp1_field_complete(ctx, job->previous); 1330 else 1331 fdp1_field_complete(ctx, job->active); 1332 1333 spin_lock_irqsave(&fdp1->irqlock, flags); 1334 v4l2_m2m_buf_done(job->dst->vb, state); 1335 job->dst = NULL; 1336 spin_unlock_irqrestore(&fdp1->irqlock, flags); 1337 1338 /* Move this job back to the free job list */ 1339 fdp1_job_free(fdp1, job); 1340 1341 dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n", 1342 ctx->num_processed, ctx->translen); 1343 1344 if (ctx->num_processed == ctx->translen || 1345 ctx->aborting) { 1346 dprintk(ctx->fdp1, "Finishing transaction\n"); 1347 ctx->num_processed = 0; 1348 v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx); 1349 } else { 1350 /* 1351 * For pipelined performance support, this would 1352 * be called from a VINT handler 1353 */ 1354 fdp1_device_process(ctx); 1355 } 1356} 1357 1358/* 1359 * video ioctls 1360 */ 1361static int fdp1_vidioc_querycap(struct file *file, void *priv, 1362 struct v4l2_capability *cap) 1363{ 1364 strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); 1365 strscpy(cap->card, DRIVER_NAME, sizeof(cap->card)); 1366 snprintf(cap->bus_info, sizeof(cap->bus_info), 1367 "platform:%s", DRIVER_NAME); 1368 return 0; 1369} 1370 1371static int fdp1_enum_fmt(struct v4l2_fmtdesc *f, u32 type) 1372{ 1373 unsigned int i, num; 1374 1375 num = 0; 1376 1377 for (i = 0; i < ARRAY_SIZE(fdp1_formats); ++i) { 1378 if (fdp1_formats[i].types & type) { 1379 if (num == f->index) 1380 break; 1381 ++num; 1382 } 1383 } 1384 1385 /* Format not found */ 1386 if (i >= ARRAY_SIZE(fdp1_formats)) 1387 return -EINVAL; 1388 1389 /* Format found */ 1390 f->pixelformat = fdp1_formats[i].fourcc; 1391 1392 return 0; 1393} 1394 1395static int fdp1_enum_fmt_vid_cap(struct file *file, void *priv, 1396 struct v4l2_fmtdesc *f) 1397{ 1398 return fdp1_enum_fmt(f, FDP1_CAPTURE); 1399} 1400 1401static int fdp1_enum_fmt_vid_out(struct file *file, void *priv, 1402 struct v4l2_fmtdesc *f) 1403{ 1404 return fdp1_enum_fmt(f, FDP1_OUTPUT); 1405} 1406 1407static int fdp1_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 1408{ 1409 struct fdp1_q_data *q_data; 1410 struct fdp1_ctx *ctx = fh_to_ctx(priv); 1411 1412 if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type)) 1413 return -EINVAL; 1414 1415 q_data = get_q_data(ctx, f->type); 1416 f->fmt.pix_mp = q_data->format; 1417 1418 return 0; 1419} 1420 1421static void fdp1_compute_stride(struct v4l2_pix_format_mplane *pix, 1422 const struct fdp1_fmt *fmt) 1423{ 1424 unsigned int i; 1425 1426 /* Compute and clamp the stride and image size. */ 1427 for (i = 0; i < min_t(unsigned int, fmt->num_planes, 2U); ++i) { 1428 unsigned int hsub = i > 0 ? fmt->hsub : 1; 1429 unsigned int vsub = i > 0 ? fmt->vsub : 1; 1430 /* From VSP : TODO: Confirm alignment limits for FDP1 */ 1431 unsigned int align = 128; 1432 unsigned int bpl; 1433 1434 bpl = clamp_t(unsigned int, pix->plane_fmt[i].bytesperline, 1435 pix->width / hsub * fmt->bpp[i] / 8, 1436 round_down(FDP1_MAX_STRIDE, align)); 1437 1438 pix->plane_fmt[i].bytesperline = round_up(bpl, align); 1439 pix->plane_fmt[i].sizeimage = pix->plane_fmt[i].bytesperline 1440 * pix->height / vsub; 1441 1442 memset(pix->plane_fmt[i].reserved, 0, 1443 sizeof(pix->plane_fmt[i].reserved)); 1444 } 1445 1446 if (fmt->num_planes == 3) { 1447 /* The two chroma planes must have the same stride. */ 1448 pix->plane_fmt[2].bytesperline = pix->plane_fmt[1].bytesperline; 1449 pix->plane_fmt[2].sizeimage = pix->plane_fmt[1].sizeimage; 1450 1451 memset(pix->plane_fmt[2].reserved, 0, 1452 sizeof(pix->plane_fmt[2].reserved)); 1453 } 1454} 1455 1456static void fdp1_try_fmt_output(struct fdp1_ctx *ctx, 1457 const struct fdp1_fmt **fmtinfo, 1458 struct v4l2_pix_format_mplane *pix) 1459{ 1460 const struct fdp1_fmt *fmt; 1461 unsigned int width; 1462 unsigned int height; 1463 1464 /* Validate the pixel format to ensure the output queue supports it. */ 1465 fmt = fdp1_find_format(pix->pixelformat); 1466 if (!fmt || !(fmt->types & FDP1_OUTPUT)) 1467 fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV); 1468 1469 if (fmtinfo) 1470 *fmtinfo = fmt; 1471 1472 pix->pixelformat = fmt->fourcc; 1473 pix->num_planes = fmt->num_planes; 1474 1475 /* 1476 * Progressive video and all interlaced field orders are acceptable. 1477 * Default to V4L2_FIELD_INTERLACED. 1478 */ 1479 if (pix->field != V4L2_FIELD_NONE && 1480 pix->field != V4L2_FIELD_ALTERNATE && 1481 !V4L2_FIELD_HAS_BOTH(pix->field)) 1482 pix->field = V4L2_FIELD_INTERLACED; 1483 1484 /* 1485 * The deinterlacer doesn't care about the colorspace, accept all values 1486 * and default to V4L2_COLORSPACE_SMPTE170M. The YUV to RGB conversion 1487 * at the output of the deinterlacer supports a subset of encodings and 1488 * quantization methods and will only be available when the colorspace 1489 * allows it. 1490 */ 1491 if (pix->colorspace == V4L2_COLORSPACE_DEFAULT) 1492 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 1493 1494 /* 1495 * Align the width and height for YUV 4:2:2 and 4:2:0 formats and clamp 1496 * them to the supported frame size range. The height boundary are 1497 * related to the full frame, divide them by two when the format passes 1498 * fields in separate buffers. 1499 */ 1500 width = round_down(pix->width, fmt->hsub); 1501 pix->width = clamp(width, FDP1_MIN_W, FDP1_MAX_W); 1502 1503 height = round_down(pix->height, fmt->vsub); 1504 if (pix->field == V4L2_FIELD_ALTERNATE) 1505 pix->height = clamp(height, FDP1_MIN_H / 2, FDP1_MAX_H / 2); 1506 else 1507 pix->height = clamp(height, FDP1_MIN_H, FDP1_MAX_H); 1508 1509 fdp1_compute_stride(pix, fmt); 1510} 1511 1512static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx, 1513 const struct fdp1_fmt **fmtinfo, 1514 struct v4l2_pix_format_mplane *pix) 1515{ 1516 struct fdp1_q_data *src_data = &ctx->out_q; 1517 enum v4l2_colorspace colorspace; 1518 enum v4l2_ycbcr_encoding ycbcr_enc; 1519 enum v4l2_quantization quantization; 1520 const struct fdp1_fmt *fmt; 1521 bool allow_rgb; 1522 1523 /* 1524 * Validate the pixel format. We can only accept RGB output formats if 1525 * the input encoding and quantization are compatible with the format 1526 * conversions supported by the hardware. The supported combinations are 1527 * 1528 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_LIM_RANGE 1529 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_FULL_RANGE 1530 * V4L2_YCBCR_ENC_709 + V4L2_QUANTIZATION_LIM_RANGE 1531 */ 1532 colorspace = src_data->format.colorspace; 1533 1534 ycbcr_enc = src_data->format.ycbcr_enc; 1535 if (ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) 1536 ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(colorspace); 1537 1538 quantization = src_data->format.quantization; 1539 if (quantization == V4L2_QUANTIZATION_DEFAULT) 1540 quantization = V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace, 1541 ycbcr_enc); 1542 1543 allow_rgb = ycbcr_enc == V4L2_YCBCR_ENC_601 || 1544 (ycbcr_enc == V4L2_YCBCR_ENC_709 && 1545 quantization == V4L2_QUANTIZATION_LIM_RANGE); 1546 1547 fmt = fdp1_find_format(pix->pixelformat); 1548 if (!fmt || (!allow_rgb && fdp1_fmt_is_rgb(fmt))) 1549 fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV); 1550 1551 if (fmtinfo) 1552 *fmtinfo = fmt; 1553 1554 pix->pixelformat = fmt->fourcc; 1555 pix->num_planes = fmt->num_planes; 1556 pix->field = V4L2_FIELD_NONE; 1557 1558 /* 1559 * The colorspace on the capture queue is copied from the output queue 1560 * as the hardware can't change the colorspace. It can convert YCbCr to 1561 * RGB though, in which case the encoding and quantization are set to 1562 * default values as anything else wouldn't make sense. 1563 */ 1564 pix->colorspace = src_data->format.colorspace; 1565 pix->xfer_func = src_data->format.xfer_func; 1566 1567 if (fdp1_fmt_is_rgb(fmt)) { 1568 pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 1569 pix->quantization = V4L2_QUANTIZATION_DEFAULT; 1570 } else { 1571 pix->ycbcr_enc = src_data->format.ycbcr_enc; 1572 pix->quantization = src_data->format.quantization; 1573 } 1574 1575 /* 1576 * The frame width is identical to the output queue, and the height is 1577 * either doubled or identical depending on whether the output queue 1578 * field order contains one or two fields per frame. 1579 */ 1580 pix->width = src_data->format.width; 1581 if (src_data->format.field == V4L2_FIELD_ALTERNATE) 1582 pix->height = 2 * src_data->format.height; 1583 else 1584 pix->height = src_data->format.height; 1585 1586 fdp1_compute_stride(pix, fmt); 1587} 1588 1589static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 1590{ 1591 struct fdp1_ctx *ctx = fh_to_ctx(priv); 1592 1593 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1594 fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp); 1595 else 1596 fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp); 1597 1598 dprintk(ctx->fdp1, "Try %s format: %4.4s (0x%08x) %ux%u field %u\n", 1599 V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture", 1600 (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat, 1601 f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field); 1602 1603 return 0; 1604} 1605 1606static void fdp1_set_format(struct fdp1_ctx *ctx, 1607 struct v4l2_pix_format_mplane *pix, 1608 enum v4l2_buf_type type) 1609{ 1610 struct fdp1_q_data *q_data = get_q_data(ctx, type); 1611 const struct fdp1_fmt *fmtinfo; 1612 1613 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1614 fdp1_try_fmt_output(ctx, &fmtinfo, pix); 1615 else 1616 fdp1_try_fmt_capture(ctx, &fmtinfo, pix); 1617 1618 q_data->fmt = fmtinfo; 1619 q_data->format = *pix; 1620 1621 q_data->vsize = pix->height; 1622 if (pix->field != V4L2_FIELD_NONE) 1623 q_data->vsize /= 2; 1624 1625 q_data->stride_y = pix->plane_fmt[0].bytesperline; 1626 q_data->stride_c = pix->plane_fmt[1].bytesperline; 1627 1628 /* Adjust strides for interleaved buffers */ 1629 if (pix->field == V4L2_FIELD_INTERLACED || 1630 pix->field == V4L2_FIELD_INTERLACED_TB || 1631 pix->field == V4L2_FIELD_INTERLACED_BT) { 1632 q_data->stride_y *= 2; 1633 q_data->stride_c *= 2; 1634 } 1635 1636 /* Propagate the format from the output node to the capture node. */ 1637 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1638 struct fdp1_q_data *dst_data = &ctx->cap_q; 1639 1640 /* 1641 * Copy the format, clear the per-plane bytes per line and image 1642 * size, override the field and double the height if needed. 1643 */ 1644 dst_data->format = q_data->format; 1645 memset(dst_data->format.plane_fmt, 0, 1646 sizeof(dst_data->format.plane_fmt)); 1647 1648 dst_data->format.field = V4L2_FIELD_NONE; 1649 if (pix->field == V4L2_FIELD_ALTERNATE) 1650 dst_data->format.height *= 2; 1651 1652 fdp1_try_fmt_capture(ctx, &dst_data->fmt, &dst_data->format); 1653 1654 dst_data->vsize = dst_data->format.height; 1655 dst_data->stride_y = dst_data->format.plane_fmt[0].bytesperline; 1656 dst_data->stride_c = dst_data->format.plane_fmt[1].bytesperline; 1657 } 1658} 1659 1660static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f) 1661{ 1662 struct fdp1_ctx *ctx = fh_to_ctx(priv); 1663 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; 1664 struct vb2_queue *vq = v4l2_m2m_get_vq(m2m_ctx, f->type); 1665 1666 if (vb2_is_busy(vq)) { 1667 v4l2_err(&ctx->fdp1->v4l2_dev, "%s queue busy\n", __func__); 1668 return -EBUSY; 1669 } 1670 1671 fdp1_set_format(ctx, &f->fmt.pix_mp, f->type); 1672 1673 dprintk(ctx->fdp1, "Set %s format: %4.4s (0x%08x) %ux%u field %u\n", 1674 V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture", 1675 (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat, 1676 f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field); 1677 1678 return 0; 1679} 1680 1681static int fdp1_g_ctrl(struct v4l2_ctrl *ctrl) 1682{ 1683 struct fdp1_ctx *ctx = 1684 container_of(ctrl->handler, struct fdp1_ctx, hdl); 1685 struct fdp1_q_data *src_q_data = &ctx->out_q; 1686 1687 switch (ctrl->id) { 1688 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 1689 if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field)) 1690 ctrl->val = 2; 1691 else 1692 ctrl->val = 1; 1693 return 0; 1694 } 1695 1696 return 1; 1697} 1698 1699static int fdp1_s_ctrl(struct v4l2_ctrl *ctrl) 1700{ 1701 struct fdp1_ctx *ctx = 1702 container_of(ctrl->handler, struct fdp1_ctx, hdl); 1703 1704 switch (ctrl->id) { 1705 case V4L2_CID_ALPHA_COMPONENT: 1706 ctx->alpha = ctrl->val; 1707 break; 1708 1709 case V4L2_CID_DEINTERLACING_MODE: 1710 ctx->deint_mode = ctrl->val; 1711 break; 1712 } 1713 1714 return 0; 1715} 1716 1717static const struct v4l2_ctrl_ops fdp1_ctrl_ops = { 1718 .s_ctrl = fdp1_s_ctrl, 1719 .g_volatile_ctrl = fdp1_g_ctrl, 1720}; 1721 1722static const char * const fdp1_ctrl_deint_menu[] = { 1723 "Progressive", 1724 "Adaptive 2D/3D", 1725 "Fixed 2D", 1726 "Fixed 3D", 1727 "Previous field", 1728 "Next field", 1729 NULL 1730}; 1731 1732static const struct v4l2_ioctl_ops fdp1_ioctl_ops = { 1733 .vidioc_querycap = fdp1_vidioc_querycap, 1734 1735 .vidioc_enum_fmt_vid_cap = fdp1_enum_fmt_vid_cap, 1736 .vidioc_enum_fmt_vid_out = fdp1_enum_fmt_vid_out, 1737 .vidioc_g_fmt_vid_cap_mplane = fdp1_g_fmt, 1738 .vidioc_g_fmt_vid_out_mplane = fdp1_g_fmt, 1739 .vidioc_try_fmt_vid_cap_mplane = fdp1_try_fmt, 1740 .vidioc_try_fmt_vid_out_mplane = fdp1_try_fmt, 1741 .vidioc_s_fmt_vid_cap_mplane = fdp1_s_fmt, 1742 .vidioc_s_fmt_vid_out_mplane = fdp1_s_fmt, 1743 1744 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 1745 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 1746 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 1747 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 1748 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 1749 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 1750 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 1751 1752 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 1753 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 1754 1755 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 1756 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1757}; 1758 1759/* 1760 * Queue operations 1761 */ 1762 1763static int fdp1_queue_setup(struct vb2_queue *vq, 1764 unsigned int *nbuffers, unsigned int *nplanes, 1765 unsigned int sizes[], 1766 struct device *alloc_ctxs[]) 1767{ 1768 struct fdp1_ctx *ctx = vb2_get_drv_priv(vq); 1769 struct fdp1_q_data *q_data; 1770 unsigned int i; 1771 1772 q_data = get_q_data(ctx, vq->type); 1773 1774 if (*nplanes) { 1775 if (*nplanes > FDP1_MAX_PLANES) 1776 return -EINVAL; 1777 1778 return 0; 1779 } 1780 1781 *nplanes = q_data->format.num_planes; 1782 1783 for (i = 0; i < *nplanes; i++) 1784 sizes[i] = q_data->format.plane_fmt[i].sizeimage; 1785 1786 return 0; 1787} 1788 1789static void fdp1_buf_prepare_field(struct fdp1_q_data *q_data, 1790 struct vb2_v4l2_buffer *vbuf, 1791 unsigned int field_num) 1792{ 1793 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf); 1794 struct fdp1_field_buffer *fbuf = &buf->fields[field_num]; 1795 unsigned int num_fields; 1796 unsigned int i; 1797 1798 num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1; 1799 1800 fbuf->vb = vbuf; 1801 fbuf->last_field = (field_num + 1) == num_fields; 1802 1803 for (i = 0; i < vbuf->vb2_buf.num_planes; ++i) 1804 fbuf->addrs[i] = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, i); 1805 1806 switch (vbuf->field) { 1807 case V4L2_FIELD_INTERLACED: 1808 /* 1809 * Interlaced means bottom-top for 60Hz TV standards (NTSC) and 1810 * top-bottom for 50Hz. As TV standards are not applicable to 1811 * the mem-to-mem API, use the height as a heuristic. 1812 */ 1813 fbuf->field = (q_data->format.height < 576) == field_num 1814 ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; 1815 break; 1816 case V4L2_FIELD_INTERLACED_TB: 1817 case V4L2_FIELD_SEQ_TB: 1818 fbuf->field = field_num ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP; 1819 break; 1820 case V4L2_FIELD_INTERLACED_BT: 1821 case V4L2_FIELD_SEQ_BT: 1822 fbuf->field = field_num ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; 1823 break; 1824 default: 1825 fbuf->field = vbuf->field; 1826 break; 1827 } 1828 1829 /* Buffer is completed */ 1830 if (!field_num) 1831 return; 1832 1833 /* Adjust buffer addresses for second field */ 1834 switch (vbuf->field) { 1835 case V4L2_FIELD_INTERLACED: 1836 case V4L2_FIELD_INTERLACED_TB: 1837 case V4L2_FIELD_INTERLACED_BT: 1838 for (i = 0; i < vbuf->vb2_buf.num_planes; i++) 1839 fbuf->addrs[i] += 1840 (i == 0 ? q_data->stride_y : q_data->stride_c); 1841 break; 1842 case V4L2_FIELD_SEQ_TB: 1843 case V4L2_FIELD_SEQ_BT: 1844 for (i = 0; i < vbuf->vb2_buf.num_planes; i++) 1845 fbuf->addrs[i] += q_data->vsize * 1846 (i == 0 ? q_data->stride_y : q_data->stride_c); 1847 break; 1848 } 1849} 1850 1851static int fdp1_buf_prepare(struct vb2_buffer *vb) 1852{ 1853 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1854 struct fdp1_q_data *q_data = get_q_data(ctx, vb->vb2_queue->type); 1855 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1856 struct fdp1_buffer *buf = to_fdp1_buffer(vbuf); 1857 unsigned int i; 1858 1859 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { 1860 bool field_valid = true; 1861 1862 /* Validate the buffer field. */ 1863 switch (q_data->format.field) { 1864 case V4L2_FIELD_NONE: 1865 if (vbuf->field != V4L2_FIELD_NONE) 1866 field_valid = false; 1867 break; 1868 1869 case V4L2_FIELD_ALTERNATE: 1870 if (vbuf->field != V4L2_FIELD_TOP && 1871 vbuf->field != V4L2_FIELD_BOTTOM) 1872 field_valid = false; 1873 break; 1874 1875 case V4L2_FIELD_INTERLACED: 1876 case V4L2_FIELD_SEQ_TB: 1877 case V4L2_FIELD_SEQ_BT: 1878 case V4L2_FIELD_INTERLACED_TB: 1879 case V4L2_FIELD_INTERLACED_BT: 1880 if (vbuf->field != q_data->format.field) 1881 field_valid = false; 1882 break; 1883 } 1884 1885 if (!field_valid) { 1886 dprintk(ctx->fdp1, 1887 "buffer field %u invalid for format field %u\n", 1888 vbuf->field, q_data->format.field); 1889 return -EINVAL; 1890 } 1891 } else { 1892 vbuf->field = V4L2_FIELD_NONE; 1893 } 1894 1895 /* Validate the planes sizes. */ 1896 for (i = 0; i < q_data->format.num_planes; i++) { 1897 unsigned long size = q_data->format.plane_fmt[i].sizeimage; 1898 1899 if (vb2_plane_size(vb, i) < size) { 1900 dprintk(ctx->fdp1, 1901 "data will not fit into plane [%u/%u] (%lu < %lu)\n", 1902 i, q_data->format.num_planes, 1903 vb2_plane_size(vb, i), size); 1904 return -EINVAL; 1905 } 1906 1907 /* We have known size formats all around */ 1908 vb2_set_plane_payload(vb, i, size); 1909 } 1910 1911 buf->num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1; 1912 for (i = 0; i < buf->num_fields; ++i) 1913 fdp1_buf_prepare_field(q_data, vbuf, i); 1914 1915 return 0; 1916} 1917 1918static void fdp1_buf_queue(struct vb2_buffer *vb) 1919{ 1920 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1921 struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1922 1923 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 1924} 1925 1926static int fdp1_start_streaming(struct vb2_queue *q, unsigned int count) 1927{ 1928 struct fdp1_ctx *ctx = vb2_get_drv_priv(q); 1929 struct fdp1_q_data *q_data = get_q_data(ctx, q->type); 1930 1931 if (V4L2_TYPE_IS_OUTPUT(q->type)) { 1932 /* 1933 * Force our deint_mode when we are progressive, 1934 * ignoring any setting on the device from the user, 1935 * Otherwise, lock in the requested de-interlace mode. 1936 */ 1937 if (q_data->format.field == V4L2_FIELD_NONE) 1938 ctx->deint_mode = FDP1_PROGRESSIVE; 1939 1940 if (ctx->deint_mode == FDP1_ADAPT2D3D) { 1941 u32 stride; 1942 dma_addr_t smsk_base; 1943 const u32 bpp = 2; /* bytes per pixel */ 1944 1945 stride = round_up(q_data->format.width, 8); 1946 1947 ctx->smsk_size = bpp * stride * q_data->vsize; 1948 1949 ctx->smsk_cpu = dma_alloc_coherent(ctx->fdp1->dev, 1950 ctx->smsk_size, &smsk_base, GFP_KERNEL); 1951 1952 if (ctx->smsk_cpu == NULL) { 1953 dprintk(ctx->fdp1, "Failed to alloc smsk\n"); 1954 return -ENOMEM; 1955 } 1956 1957 ctx->smsk_addr[0] = smsk_base; 1958 ctx->smsk_addr[1] = smsk_base + (ctx->smsk_size/2); 1959 } 1960 } 1961 1962 return 0; 1963} 1964 1965static void fdp1_stop_streaming(struct vb2_queue *q) 1966{ 1967 struct fdp1_ctx *ctx = vb2_get_drv_priv(q); 1968 struct vb2_v4l2_buffer *vbuf; 1969 unsigned long flags; 1970 1971 while (1) { 1972 if (V4L2_TYPE_IS_OUTPUT(q->type)) 1973 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1974 else 1975 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1976 if (vbuf == NULL) 1977 break; 1978 spin_lock_irqsave(&ctx->fdp1->irqlock, flags); 1979 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 1980 spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); 1981 } 1982 1983 /* Empty Output queues */ 1984 if (V4L2_TYPE_IS_OUTPUT(q->type)) { 1985 /* Empty our internal queues */ 1986 struct fdp1_field_buffer *fbuf; 1987 1988 /* Free any queued buffers */ 1989 fbuf = fdp1_dequeue_field(ctx); 1990 while (fbuf != NULL) { 1991 fdp1_field_complete(ctx, fbuf); 1992 fbuf = fdp1_dequeue_field(ctx); 1993 } 1994 1995 /* Free smsk_data */ 1996 if (ctx->smsk_cpu) { 1997 dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size, 1998 ctx->smsk_cpu, ctx->smsk_addr[0]); 1999 ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0; 2000 ctx->smsk_cpu = NULL; 2001 } 2002 2003 WARN(!list_empty(&ctx->fields_queue), 2004 "Buffer queue not empty"); 2005 } else { 2006 /* Empty Capture queues (Jobs) */ 2007 struct fdp1_job *job; 2008 2009 job = get_queued_job(ctx->fdp1); 2010 while (job) { 2011 if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) 2012 fdp1_field_complete(ctx, job->previous); 2013 else 2014 fdp1_field_complete(ctx, job->active); 2015 2016 v4l2_m2m_buf_done(job->dst->vb, VB2_BUF_STATE_ERROR); 2017 job->dst = NULL; 2018 2019 job = get_queued_job(ctx->fdp1); 2020 } 2021 2022 /* Free any held buffer in the ctx */ 2023 fdp1_field_complete(ctx, ctx->previous); 2024 2025 WARN(!list_empty(&ctx->fdp1->queued_job_list), 2026 "Queued Job List not empty"); 2027 2028 WARN(!list_empty(&ctx->fdp1->hw_job_list), 2029 "HW Job list not empty"); 2030 } 2031} 2032 2033static const struct vb2_ops fdp1_qops = { 2034 .queue_setup = fdp1_queue_setup, 2035 .buf_prepare = fdp1_buf_prepare, 2036 .buf_queue = fdp1_buf_queue, 2037 .start_streaming = fdp1_start_streaming, 2038 .stop_streaming = fdp1_stop_streaming, 2039 .wait_prepare = vb2_ops_wait_prepare, 2040 .wait_finish = vb2_ops_wait_finish, 2041}; 2042 2043static int queue_init(void *priv, struct vb2_queue *src_vq, 2044 struct vb2_queue *dst_vq) 2045{ 2046 struct fdp1_ctx *ctx = priv; 2047 int ret; 2048 2049 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2050 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 2051 src_vq->drv_priv = ctx; 2052 src_vq->buf_struct_size = sizeof(struct fdp1_buffer); 2053 src_vq->ops = &fdp1_qops; 2054 src_vq->mem_ops = &vb2_dma_contig_memops; 2055 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 2056 src_vq->lock = &ctx->fdp1->dev_mutex; 2057 src_vq->dev = ctx->fdp1->dev; 2058 2059 ret = vb2_queue_init(src_vq); 2060 if (ret) 2061 return ret; 2062 2063 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2064 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 2065 dst_vq->drv_priv = ctx; 2066 dst_vq->buf_struct_size = sizeof(struct fdp1_buffer); 2067 dst_vq->ops = &fdp1_qops; 2068 dst_vq->mem_ops = &vb2_dma_contig_memops; 2069 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 2070 dst_vq->lock = &ctx->fdp1->dev_mutex; 2071 dst_vq->dev = ctx->fdp1->dev; 2072 2073 return vb2_queue_init(dst_vq); 2074} 2075 2076/* 2077 * File operations 2078 */ 2079static int fdp1_open(struct file *file) 2080{ 2081 struct fdp1_dev *fdp1 = video_drvdata(file); 2082 struct v4l2_pix_format_mplane format; 2083 struct fdp1_ctx *ctx = NULL; 2084 struct v4l2_ctrl *ctrl; 2085 int ret = 0; 2086 2087 if (mutex_lock_interruptible(&fdp1->dev_mutex)) 2088 return -ERESTARTSYS; 2089 2090 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 2091 if (!ctx) { 2092 ret = -ENOMEM; 2093 goto done; 2094 } 2095 2096 v4l2_fh_init(&ctx->fh, video_devdata(file)); 2097 file->private_data = &ctx->fh; 2098 ctx->fdp1 = fdp1; 2099 2100 /* Initialise Queues */ 2101 INIT_LIST_HEAD(&ctx->fields_queue); 2102 2103 ctx->translen = 1; 2104 ctx->sequence = 0; 2105 2106 /* Initialise controls */ 2107 2108 v4l2_ctrl_handler_init(&ctx->hdl, 3); 2109 v4l2_ctrl_new_std_menu_items(&ctx->hdl, &fdp1_ctrl_ops, 2110 V4L2_CID_DEINTERLACING_MODE, 2111 FDP1_NEXTFIELD, BIT(0), FDP1_FIXED3D, 2112 fdp1_ctrl_deint_menu); 2113 2114 ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops, 2115 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1); 2116 if (ctrl) 2117 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 2118 2119 v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops, 2120 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); 2121 2122 if (ctx->hdl.error) { 2123 ret = ctx->hdl.error; 2124 goto error_ctx; 2125 } 2126 2127 ctx->fh.ctrl_handler = &ctx->hdl; 2128 v4l2_ctrl_handler_setup(&ctx->hdl); 2129 2130 /* Configure default parameters. */ 2131 memset(&format, 0, sizeof(format)); 2132 fdp1_set_format(ctx, &format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 2133 2134 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fdp1->m2m_dev, ctx, &queue_init); 2135 2136 if (IS_ERR(ctx->fh.m2m_ctx)) { 2137 ret = PTR_ERR(ctx->fh.m2m_ctx); 2138 goto error_ctx; 2139 } 2140 2141 /* Perform any power management required */ 2142 ret = pm_runtime_resume_and_get(fdp1->dev); 2143 if (ret < 0) 2144 goto error_pm; 2145 2146 v4l2_fh_add(&ctx->fh); 2147 2148 dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n", 2149 ctx, ctx->fh.m2m_ctx); 2150 2151 mutex_unlock(&fdp1->dev_mutex); 2152 return 0; 2153 2154error_pm: 2155 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 2156error_ctx: 2157 v4l2_ctrl_handler_free(&ctx->hdl); 2158 kfree(ctx); 2159done: 2160 mutex_unlock(&fdp1->dev_mutex); 2161 return ret; 2162} 2163 2164static int fdp1_release(struct file *file) 2165{ 2166 struct fdp1_dev *fdp1 = video_drvdata(file); 2167 struct fdp1_ctx *ctx = fh_to_ctx(file->private_data); 2168 2169 dprintk(fdp1, "Releasing instance %p\n", ctx); 2170 2171 v4l2_fh_del(&ctx->fh); 2172 v4l2_fh_exit(&ctx->fh); 2173 v4l2_ctrl_handler_free(&ctx->hdl); 2174 mutex_lock(&fdp1->dev_mutex); 2175 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 2176 mutex_unlock(&fdp1->dev_mutex); 2177 kfree(ctx); 2178 2179 pm_runtime_put(fdp1->dev); 2180 2181 return 0; 2182} 2183 2184static const struct v4l2_file_operations fdp1_fops = { 2185 .owner = THIS_MODULE, 2186 .open = fdp1_open, 2187 .release = fdp1_release, 2188 .poll = v4l2_m2m_fop_poll, 2189 .unlocked_ioctl = video_ioctl2, 2190 .mmap = v4l2_m2m_fop_mmap, 2191}; 2192 2193static const struct video_device fdp1_videodev = { 2194 .name = DRIVER_NAME, 2195 .vfl_dir = VFL_DIR_M2M, 2196 .fops = &fdp1_fops, 2197 .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, 2198 .ioctl_ops = &fdp1_ioctl_ops, 2199 .minor = -1, 2200 .release = video_device_release_empty, 2201}; 2202 2203static const struct v4l2_m2m_ops m2m_ops = { 2204 .device_run = fdp1_m2m_device_run, 2205 .job_ready = fdp1_m2m_job_ready, 2206 .job_abort = fdp1_m2m_job_abort, 2207}; 2208 2209static irqreturn_t fdp1_irq_handler(int irq, void *dev_id) 2210{ 2211 struct fdp1_dev *fdp1 = dev_id; 2212 u32 int_status; 2213 u32 ctl_status; 2214 u32 vint_cnt; 2215 u32 cycles; 2216 2217 int_status = fdp1_read(fdp1, FD1_CTL_IRQSTA); 2218 cycles = fdp1_read(fdp1, FD1_CTL_VCYCLE_STAT); 2219 ctl_status = fdp1_read(fdp1, FD1_CTL_STATUS); 2220 vint_cnt = (ctl_status & FD1_CTL_STATUS_VINT_CNT_MASK) >> 2221 FD1_CTL_STATUS_VINT_CNT_SHIFT; 2222 2223 /* Clear interrupts */ 2224 fdp1_write(fdp1, ~(int_status) & FD1_CTL_IRQ_MASK, FD1_CTL_IRQSTA); 2225 2226 if (debug >= 2) { 2227 dprintk(fdp1, "IRQ: 0x%x %s%s%s\n", int_status, 2228 int_status & FD1_CTL_IRQ_VERE ? "[Error]" : "[!E]", 2229 int_status & FD1_CTL_IRQ_VINTE ? "[VSync]" : "[!V]", 2230 int_status & FD1_CTL_IRQ_FREE ? "[FrameEnd]" : "[!F]"); 2231 2232 dprintk(fdp1, "CycleStatus = %d (%dms)\n", 2233 cycles, cycles/(fdp1->clk_rate/1000)); 2234 2235 dprintk(fdp1, 2236 "Control Status = 0x%08x : VINT_CNT = %d %s:%s:%s:%s\n", 2237 ctl_status, vint_cnt, 2238 ctl_status & FD1_CTL_STATUS_SGREGSET ? "RegSet" : "", 2239 ctl_status & FD1_CTL_STATUS_SGVERR ? "Vsync Error" : "", 2240 ctl_status & FD1_CTL_STATUS_SGFREND ? "FrameEnd" : "", 2241 ctl_status & FD1_CTL_STATUS_BSY ? "Busy" : ""); 2242 dprintk(fdp1, "***********************************\n"); 2243 } 2244 2245 /* Spurious interrupt */ 2246 if (!(FD1_CTL_IRQ_MASK & int_status)) 2247 return IRQ_NONE; 2248 2249 /* Work completed, release the frame */ 2250 if (FD1_CTL_IRQ_VERE & int_status) 2251 device_frame_end(fdp1, VB2_BUF_STATE_ERROR); 2252 else if (FD1_CTL_IRQ_FREE & int_status) 2253 device_frame_end(fdp1, VB2_BUF_STATE_DONE); 2254 2255 return IRQ_HANDLED; 2256} 2257 2258static int fdp1_probe(struct platform_device *pdev) 2259{ 2260 struct fdp1_dev *fdp1; 2261 struct video_device *vfd; 2262 struct device_node *fcp_node; 2263 struct clk *clk; 2264 unsigned int i; 2265 2266 int ret; 2267 int hw_version; 2268 2269 fdp1 = devm_kzalloc(&pdev->dev, sizeof(*fdp1), GFP_KERNEL); 2270 if (!fdp1) 2271 return -ENOMEM; 2272 2273 INIT_LIST_HEAD(&fdp1->free_job_list); 2274 INIT_LIST_HEAD(&fdp1->queued_job_list); 2275 INIT_LIST_HEAD(&fdp1->hw_job_list); 2276 2277 /* Initialise the jobs on the free list */ 2278 for (i = 0; i < ARRAY_SIZE(fdp1->jobs); i++) 2279 list_add(&fdp1->jobs[i].list, &fdp1->free_job_list); 2280 2281 mutex_init(&fdp1->dev_mutex); 2282 2283 spin_lock_init(&fdp1->irqlock); 2284 spin_lock_init(&fdp1->device_process_lock); 2285 fdp1->dev = &pdev->dev; 2286 platform_set_drvdata(pdev, fdp1); 2287 2288 /* Memory-mapped registers */ 2289 fdp1->regs = devm_platform_ioremap_resource(pdev, 0); 2290 if (IS_ERR(fdp1->regs)) 2291 return PTR_ERR(fdp1->regs); 2292 2293 /* Interrupt service routine registration */ 2294 ret = platform_get_irq(pdev, 0); 2295 if (ret < 0) 2296 return ret; 2297 fdp1->irq = ret; 2298 2299 ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0, 2300 dev_name(&pdev->dev), fdp1); 2301 if (ret) { 2302 dev_err(&pdev->dev, "cannot claim IRQ %d\n", fdp1->irq); 2303 return ret; 2304 } 2305 2306 /* FCP */ 2307 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0); 2308 if (fcp_node) { 2309 fdp1->fcp = rcar_fcp_get(fcp_node); 2310 of_node_put(fcp_node); 2311 if (IS_ERR(fdp1->fcp)) { 2312 dev_dbg(&pdev->dev, "FCP not found (%ld)\n", 2313 PTR_ERR(fdp1->fcp)); 2314 return PTR_ERR(fdp1->fcp); 2315 } 2316 } 2317 2318 /* Determine our clock rate */ 2319 clk = clk_get(&pdev->dev, NULL); 2320 if (IS_ERR(clk)) { 2321 ret = PTR_ERR(clk); 2322 goto put_dev; 2323 } 2324 2325 fdp1->clk_rate = clk_get_rate(clk); 2326 clk_put(clk); 2327 2328 /* V4L2 device registration */ 2329 ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev); 2330 if (ret) { 2331 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); 2332 goto put_dev; 2333 } 2334 2335 /* M2M registration */ 2336 fdp1->m2m_dev = v4l2_m2m_init(&m2m_ops); 2337 if (IS_ERR(fdp1->m2m_dev)) { 2338 v4l2_err(&fdp1->v4l2_dev, "Failed to init mem2mem device\n"); 2339 ret = PTR_ERR(fdp1->m2m_dev); 2340 goto unreg_dev; 2341 } 2342 2343 /* Video registration */ 2344 fdp1->vfd = fdp1_videodev; 2345 vfd = &fdp1->vfd; 2346 vfd->lock = &fdp1->dev_mutex; 2347 vfd->v4l2_dev = &fdp1->v4l2_dev; 2348 video_set_drvdata(vfd, fdp1); 2349 strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name)); 2350 2351 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0); 2352 if (ret) { 2353 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); 2354 goto release_m2m; 2355 } 2356 2357 v4l2_info(&fdp1->v4l2_dev, "Device registered as /dev/video%d\n", 2358 vfd->num); 2359 2360 /* Power up the cells to read HW */ 2361 pm_runtime_enable(&pdev->dev); 2362 ret = pm_runtime_resume_and_get(fdp1->dev); 2363 if (ret < 0) 2364 goto disable_pm; 2365 2366 hw_version = fdp1_read(fdp1, FD1_IP_INTDATA); 2367 switch (hw_version) { 2368 case FD1_IP_H3_ES1: 2369 dprintk(fdp1, "FDP1 Version R-Car H3 ES1\n"); 2370 break; 2371 case FD1_IP_M3W: 2372 dprintk(fdp1, "FDP1 Version R-Car M3-W\n"); 2373 break; 2374 case FD1_IP_H3: 2375 dprintk(fdp1, "FDP1 Version R-Car H3\n"); 2376 break; 2377 case FD1_IP_M3N: 2378 dprintk(fdp1, "FDP1 Version R-Car M3-N\n"); 2379 break; 2380 case FD1_IP_E3: 2381 dprintk(fdp1, "FDP1 Version R-Car E3\n"); 2382 break; 2383 default: 2384 dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n", 2385 hw_version); 2386 } 2387 2388 /* Allow the hw to sleep until an open call puts it to use */ 2389 pm_runtime_put(fdp1->dev); 2390 2391 return 0; 2392 2393disable_pm: 2394 pm_runtime_disable(fdp1->dev); 2395 2396release_m2m: 2397 v4l2_m2m_release(fdp1->m2m_dev); 2398 2399unreg_dev: 2400 v4l2_device_unregister(&fdp1->v4l2_dev); 2401 2402put_dev: 2403 rcar_fcp_put(fdp1->fcp); 2404 return ret; 2405} 2406 2407static int fdp1_remove(struct platform_device *pdev) 2408{ 2409 struct fdp1_dev *fdp1 = platform_get_drvdata(pdev); 2410 2411 v4l2_m2m_release(fdp1->m2m_dev); 2412 video_unregister_device(&fdp1->vfd); 2413 v4l2_device_unregister(&fdp1->v4l2_dev); 2414 pm_runtime_disable(&pdev->dev); 2415 rcar_fcp_put(fdp1->fcp); 2416 2417 return 0; 2418} 2419 2420static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev) 2421{ 2422 struct fdp1_dev *fdp1 = dev_get_drvdata(dev); 2423 2424 rcar_fcp_disable(fdp1->fcp); 2425 2426 return 0; 2427} 2428 2429static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev) 2430{ 2431 struct fdp1_dev *fdp1 = dev_get_drvdata(dev); 2432 2433 /* Program in the static LUTs */ 2434 fdp1_set_lut(fdp1); 2435 2436 return rcar_fcp_enable(fdp1->fcp); 2437} 2438 2439static const struct dev_pm_ops fdp1_pm_ops = { 2440 SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend, 2441 fdp1_pm_runtime_resume, 2442 NULL) 2443}; 2444 2445static const struct of_device_id fdp1_dt_ids[] = { 2446 { .compatible = "renesas,fdp1" }, 2447 { }, 2448}; 2449MODULE_DEVICE_TABLE(of, fdp1_dt_ids); 2450 2451static struct platform_driver fdp1_pdrv = { 2452 .probe = fdp1_probe, 2453 .remove = fdp1_remove, 2454 .driver = { 2455 .name = DRIVER_NAME, 2456 .of_match_table = fdp1_dt_ids, 2457 .pm = &fdp1_pm_ops, 2458 }, 2459}; 2460 2461module_platform_driver(fdp1_pdrv); 2462 2463MODULE_DESCRIPTION("Renesas R-Car Fine Display Processor Driver"); 2464MODULE_AUTHOR("Kieran Bingham <kieran@bingham.xyz>"); 2465MODULE_LICENSE("GPL"); 2466MODULE_ALIAS("platform:" DRIVER_NAME); 2467